MariaDB'de temporal tablolar üç biçimde gelir: sistem sürümlü (system-versioned) tablolar her değişikliğin geçmişini sunucu saatine göre otomatik saklar, uygulama zamanı dönemleri (application-time periods) bir satırın hangi tarih aralığında geçerli olduğunu sizin verdiğiniz iki sütunla tanımlar, bitemporal tablolar ise ikisini birleştirir. Bir tabloyu sürümlü yapmak için CREATE TABLE ... WITH SYSTEM VERSIONING ya da ALTER TABLE ... ADD SYSTEM VERSIONING yeterlidir; geçmişi okumak için tablo adından sonra FOR SYSTEM_TIME AS OF, BETWEEN, FROM ... TO ya da ALL yazarsınız.

Bu yazıda sürümlü tablo oluşturmayı, güncelleme ve silmenin geçmişe nasıl yansıdığını, geçmişi sorgulamayı, transaction hassasiyetinde geçmişi, geçmişi ayrı bölümlerde tutmayı ve temizlemeyi, ardından uygulama zamanı dönemlerini ve FOR PORTION OF ifadelerini resmî belgelerdeki örneklerle anlatıyoruz. Seriye genel bakış için MariaDB öğrenme rehberi sayfasına bakın.

Sistem sürümlü tablolar neye yarar?

Sistem sürümlü bir tablo yalnızca şu anda geçerli olan veriyi değil, tüm değişikliklerin geçmişini saklar. Belgeler tipik kullanım alanlarını şöyle sayar: verilerin N yıl saklanmasını isteyen yasal gereklilikler ve adli inceleme, geçmişe dönük analiz ve eğilimler (örneğin personel bilgilerinin bir yıl önceki hâli) ve bir tablonun belirli bir andaki durumunu geri getirmek. Bu özellik ilk olarak SQL:2011 standardında tanımlandı.

Tetikleyicilerle elle yazılmış bir denetim tablosuna göre fark, geçmişin sunucu tarafından tutarlı biçimde tutulması ve aynı tablo üzerinde standart bir sözdizimiyle sorgulanabilmesidir. Uygulamanın her UPDATE ve DELETE öncesinde kopya yazmasına gerek kalmaz. Elle denetim tablosu yazmayı tercih ederseniz MariaDB trigger yazısı bu yaklaşımı anlatır.

Sürümlü tablo oluşturmak

SQL:2011'e göre sürümlü bir tablonun iki üretilmiş (generated) sütunu, bir dönemi ve özel bir tablo seçeneği olmalıdır. Satırın ne zaman geçerli olmaya başladığını ROW START, ne zaman geçerliliğini yitirdiğini ROW END sütunu tutar:

sql
CREATE TABLE t(
   x INT,
   start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
   end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
   PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp)
) WITH SYSTEM VERSIONING;

MariaDB daha kısa bir sözdizimine de izin verir. Bu durumda görünür ek sütun oluşmaz, SELECT * çıktısı kalabalıklaşmaz; sürüm bilgisi yine saklanır ve ROW_START ile ROW_END sözde sütunlarıyla okunabilir:

sql
CREATE TABLE t (
   x INT
) WITH SYSTEM VERSIONING;

SELECT x, ROW_START, ROW_END FROM t;

Mevcut bir tabloya sürümleme eklemek ya da kaldırmak için ALTER TABLE kullanılır; sütunları açıkça tanımlayarak da ekleyebilirsiniz. Belgelere göre MariaDB 11.7'den itibaren örtük sütunlu bir sürümlü tabloyu açık row_start/row_end sütunlarına dönüştürmek de mümkündür; bunun için system_versioning_alter_history değişkeninin KEEP olması gerekir:

sql
ALTER TABLE t ADD SYSTEM VERSIONING;
ALTER TABLE t DROP SYSTEM VERSIONING;

ALTER TABLE t ADD COLUMN ts TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
              ADD COLUMN te TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
              ADD PERIOD FOR SYSTEM_TIME(ts, te),
              ADD SYSTEM VERSIONING;

Ekleme, güncelleme ve silme geçmişe nasıl yansır?

Sürümlü tabloya eklenen satırın row_start değeri geçerli zaman damgasıdır, row_end değeri ise satırın hâlâ geçerli olduğunu gösteren uzak bir üst sınırdır. Geçerli zaman damgası timestamp sistem değişkeniyle ayarlanabilir; belgelerdeki örnek SET @@timestamp ile gelecekte başlayan bir satır eklemeyi gösterir. DELETE satırı fiziksel olarak silmez, row_end değerini silme anına çekerek satırı geçmişe taşır.

Güncellemede önemli bir ayrıntı vardır: SET listesinde sürümlenen bir sütun bulunan her UPDATE ifadesi, değer gerçekten değişmese bile yeni bir geçmiş satırı yazar. Belgeler bunu bilinçli bir tasarım olarak açıklar: UPDATE değer değişmese de tetikleyicileri çalıştırır ve uygulamanın bir kaydı tam o anda işlediği bilgisi denetim için değerlidir. Yalnızca WITHOUT SYSTEM VERSIONING olarak tanımlanmış sütunları değiştiren güncellemeler ise geçmiş satırı üretmez. Bu davranış varsayılan zaman damgası tabanlı sürümleme içindir; transaction hassasiyetli sürümlemede geçmiş InnoDB tarafından gerçek satır değişikliklerine bağlı olarak üretilir.

sql
CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING;
INSERT INTO t VALUES (1);

-- x değeri değişmiyor, ama yine de yeni bir geçmiş satırı oluşur:
UPDATE t SET x = 1;

SELECT x, ROW_START, ROW_END FROM t FOR SYSTEM_TIME ALL;

Geçmişi sorgulamak: FOR SYSTEM_TIME

Geçmişi sorgulamak: FOR SYSTEM_TIME: AS OF zaman, BETWEEN başlangıç AND bitiş, FROM başlangıç TO bitiş, Geçmiş ve geçerli tüm satırlar (MariaDB eklentisi)

Geçmiş veriyi okumak için FOR SYSTEM_TIME ifadesini doğrudan tablo adından sonra, varsa takma addan önce yazarsınız. SQL:2011 üç biçim tanımlar ve MariaDB bunlara bir de kendi eklentisini ekler:

İfadeNe döndürür
AS OF zamanTablonun o andaki hâli
BETWEEN başlangıç AND bitişAralıkta herhangi bir an görünen satırlar, iki uç dahil
FROM başlangıç TO bitişAralıkta görünen satırlar, başlangıç dahil bitiş hariç
ALLGeçmiş ve geçerli tüm satırlar (MariaDB eklentisi)
sql
SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

SELECT * FROM t FOR SYSTEM_TIME BETWEEN (NOW() - INTERVAL 1 YEAR) AND NOW();

SELECT * FROM t FOR SYSTEM_TIME FROM '2016-01-01 00:00:00' TO '2017-01-01 00:00:00';

SELECT * FROM t FOR SYSTEM_TIME ALL;

FOR SYSTEM_TIME kullanılmazsa tablo geçerli veriyi gösterir. Belgelere göre bu genellikle AS OF CURRENT_TIMESTAMP yazmakla aynıdır, ama row_start değeri timestamp değişkeniyle ileri bir tarihe ayarlanmışsa sonuçlar farklılaşabilir. Sürümlü tablo bir view ya da FROM içindeki alt sorguda kullanıldığında FOR SYSTEM_TIME view gövdesine yazılabilir ya da, standart dışı bir eklenti olarak, view kullanılırken tüm view'a uygulanabilir:

sql
CREATE VIEW v1 AS SELECT * FROM t;
SELECT * FROM v1 FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

Aynı geçmiş anına karşı çok sayıda sorgu çalıştıracaksanız system_versioning_asof oturum değişkenine bir zaman damgası atayarak tüm sorgulara örtük bir AS OF uygulatabilirsiniz. Belgelere göre bu ayar INSERT ... SELECT gibi DML ifadelerini etkilemez; varsayılana dönmek için oturum değerine tırnak içinde 'DEFAULT' yazmak gerekir, tırnaksız DEFAULT küresel değeri geri yükler. View oluşturma ayrıntıları için MariaDB view oluşturma yazısına bakın.

Transaction hassasiyetinde geçmiş (InnoDB)

Transaction hassasiyetinde geçmiş (InnoDB)

Bir satırın eklendiği an ile görünür hâle geldiği an aynı olmayabilir; uzun süren bir transaction içinde eklenen satır saatler sonra commit edilip görünür olabilir. Bazı analizler için bu fark önemsizdir, adli inceleme gibi işlerde ise kritik olabilir. MariaDB yalnızca InnoDB için, verinin belirli bir anda yeni bir bağlantının göreceği hâliyle görülmesini sağlayan transaction hassasiyetli geçmişi destekler. Bunun için üretilmiş sütunlar TIMESTAMP(6) yerine BIGINT UNSIGNED tanımlanır ve sütunların açıkça yazılması gerekir; kalabalık yapmaması için INVISIBLE olarak tanımlanabilirler:

sql
CREATE TABLE t(
   x INT,
   start_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,
   end_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,
   PERIOD FOR SYSTEM_TIME(start_trxid, end_trxid)
) WITH SYSTEM VERSIONING;

SELECT * FROM t FOR SYSTEM_TIME AS OF TRANSACTION 12345;

Bu kipte FOR SYSTEM_TIME içinde transaction kimliği de kullanılabilir; veri bu kimlik için tutulan mysql.transaction_registry tablosuna dayanır. Belgelere göre transaction hassasiyetli sürümlemede PARTITION BY SYSTEM_TIME desteklenmez; bölümleme gerekiyorsa varsayılan zaman damgası tabanlı sürümlemeyi kullanın. Transaction kavramları için MariaDB transaction ve izolasyon seviyeleri yazısına bakın.

Geçmişi ayrı bölümlerde tutmak

Geçmiş geçerli veriyle aynı yerde tutulursa tablo büyür ve yalnızca geçerli veriyi okuyan taramalar ile index aramaları geçmiş satırların üzerinden atlamak zorunda kalır. Sorgularınızın çoğu yalnızca geçerli veriyle ilgiliyse tabloyu SYSTEM_TIME'a göre bölümleyin; partition pruning sayesinde geçerli veri sorguları yalnızca geçerli veriyi tutan bölüme erişir. Tabloda tam olarak bir CURRENT ve en az bir HISTORY bölümü olmalıdır. Geçmiş bölümleri boyuta (LIMIT) ya da zamana (INTERVAL) göre döndürülebilir:

sql
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME (
    PARTITION p_hist HISTORY,
    PARTITION p_cur CURRENT
  );

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME INTERVAL 1 WEEK (
    PARTITION p0 HISTORY,
    PARTITION p1 HISTORY,
    PARTITION p2 HISTORY,
    PARTITION pcur CURRENT
  );

Zamana göre döndürmede ilk hafta p0'a, ikinci hafta p1'e, sonraki tüm geçmiş p2'ye yazılır. LIMIT ile döndürmede belgeler değerin yalnızca bir tahmin olduğunu, döndürme iç işlemler sırasında tetiklendiği için bölümlerin bu sayıdan belirgin biçimde fazla ya da az satır içerebileceğini not eder. MariaDB 10.9.1'den itibaren AUTO anahtar sözcüğüyle geçmiş bölümleri otomatik oluşturulabilir. Bölüm sayısı verip döndürme koşulu vermemek 4115 kodlu bir uyarı, yalnızca tek bölüm istemek ise hata üretir:

sql
CREATE TABLE t1 (x INT) WITH SYSTEM VERSIONING
   PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH
   STARTS '2021-01-01 00:00:00' AUTO PARTITIONS 12;

CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME PARTITIONS 1;
ERROR 4128 (HY000): Wrong partitions for `t`: must have at least one HISTORY and exactly one last CURRENT

Genel bölümleme kuralları ve bakım komutları için MariaDB tablo bölümleme yazısına bakın.

Eski geçmişi temizlemek

Tüm geçmişi tuttuğu için sürümlü bir tablo zamanla çok büyüyebilir. Belgeler birkaç temizleme yolu sunar. Sürümlemeyi kaldırıp yeniden eklemek tüm geçmişi siler ama tabloyu motora göre bir ya da iki kez yeniden inşa edebileceği için zaman alır. Bölümlenmiş tablolarda geçmiş bölümlerinden biri DROP PARTITION ile silinebilir; geçerli bölüm ve tek geçmiş bölümü silinemez. Üçüncü yol DELETE HISTORY ifadesidir; tüm geçmişi ya da belirli bir zamandan (veya BEFORE SYSTEM_TIME TRANSACTION ile belirli bir transaction'dan) önceki geçmişi siler. Geçmişin bütünlüğünü korumak için bu ifade ayrı bir DELETE HISTORY yetkisi ister:

sql
DELETE HISTORY FROM t BEFORE SYSTEM_TIME '2016-10-09 08:07:06';

ALTER TABLE t DROP PARTITION p0;

TRUNCATE t;
ERROR 4137 (HY000): System-versioned tables do not support TRUNCATE TABLE

Son satırdaki hata, geçmişin SQL standardına uygun olarak TRUNCATE'ten korunduğunu gösterir. DELETE HISTORY yetkisini yalnızca gerçekten ihtiyacı olan hesaplara verin; yetki yönetimi için MariaDB GRANT ve REVOKE yazısına bakın.

Bazı sütunları sürümlemeden hariç tutmak

MariaDB'nin bir başka eklentisi, tablodaki sütunların yalnızca bir kısmını sürümlemektir. Belgelerdeki örnekte kullanıcı bilgisi sürümlenmeli, ama sık artan ve geçmişi ilginç olmayan bir giriş sayacı sürümlenmemelidir. Böyle bir sütun WITHOUT SYSTEM VERSIONING ile işaretlenir. Bunun tersi de mümkündür: tek bir sütunu WITH SYSTEM VERSIONING ile tanımlamak tabloyu otomatik olarak sürümlü yapar.

sql
CREATE TABLE t (
   x INT,
   y INT WITHOUT SYSTEM VERSIONING
) WITH SYSTEM VERSIONING;

Değişiklik, replikasyon ve yedek ayarları

SQL:2011 sürümlü tablolarda ALTER TABLE'a izin vermez. system_versioning_alter_history değişkeninin varsayılanı ERROR'dır ve bu değerde değiştirme girişimi hata verir. KEEP yapıldığında ALTER TABLE çalışır ama belgelerin uyardığı gibi geçmiş artık yanlış olur: geçmiş sorguları yeni tablo yapısını gösterir. Bu kip örneğin yeni sütun eklerken yine de kullanışlıdır.

Sürümlü tablolar row_end sütununu birincil anahtara örtük olarak ekler. Belgelere göre bu, binary log'dan yazma ifadelerini yeniden uygularken ya da birincil sunucunun bir ifadeyi replikada yeniden denediği durumlarda yinelenen anahtar hatalarına yol açabilir. MariaDB replikasyonunda bunu azaltmak için replikada secure_timestamp değişkenini YES yapın; replika satırları kendi saatiyle uygular. Replikasyon kurulumu için MariaDB replikasyon kurulumu yazısına bakın.

Yedek tarafında, mariadb-dump uzun süre geçmiş satırları okumuyordu. Belgelere göre MariaDB 10.11'den itibaren -H ya da --dump-history seçeneği geçmişi de yedeğe katar. MariaDB 11.5 öncesinden 11.5 ya da üstüne geçiyorsanız belgeler ayrıca --update-history seçeneğini önerir; bu seçenek row_end zaman damgasını 2106 yılına kadar tarihleri destekleyecek biçimde günceller. Yedek aracının diğer seçenekleri için mariadb-dump ile yedekleme yazısına bakın.

bash
mariadb-dump --dump-history magaza fiyatlar > fiyatlar_gecmisli.sql

Uygulama zamanı dönemleri

Uygulama zamanı dönemleri, bir satırın sizin belirlediğiniz bir zaman aralığında geçerli olduğunu ifade eder: bir otel rezervasyonu, bir sözleşmenin yürürlük tarihleri ya da bir kampanya fiyatının geçerlilik aralığı gibi. Dönem aynı zamansal veri tipinde ve aynı genişlikte iki sütunla tanımlanır; bu tip DATE, TIMESTAMP ya da DATETIME olabilir, TIME ve YEAR desteklenmez. Dönem tanımlamak iki sütunu örtük olarak NOT NULL yapar ve ilk değerin ikinciden küçük olduğunu denetleyen, SHOW CREATE TABLE çıktısında görünmeyen bir kısıt ekler. Bu nedenle NULL değer içeren bir tabloya dönem eklemek 1265 kodlu "Data truncated" hatasıyla başarısız olur. Dönem ALTER TABLE ... ADD PERIOD FOR ile eklenip DROP PERIOD FOR ile kaldırılabilir; ikisi de IF NOT EXISTS ve IF EXISTS seçeneklerini destekler.

DELETE ... FOR PORTION OF bir zaman aralığına düşen kısmı siler: satırın dönemi tamamen aralık içindeyse satır silinir, kısmen çakışıyorsa satır kısaltılır, aralık satırın dönemi içinde kalıyorsa satır ikiye bölünür. Belgelerdeki örnekte a aralığın dışında kaldığı için değişmez, b ikiye bölünür, c ve d kısaltılır:

sql
CREATE TABLE t1(
   name VARCHAR(50),
   date_1 DATE,
   date_2 DATE,
   PERIOD FOR date_period(date_1, date_2));

INSERT INTO t1 (name, date_1, date_2) VALUES
    ('a', '1999-01-01', '2000-01-01'),
    ('b', '1999-01-01', '2018-12-12'),
    ('c', '1999-01-01', '2017-01-01'),
    ('d', '2017-01-01', '2019-01-01');

DELETE FROM t1
FOR PORTION OF date_period
    FROM '2001-01-01' TO '2018-01-01';
Query OK, 3 rows affected (0.028 sec)

SELECT * FROM t1 ORDER BY name;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2001-01-01 |
| b    | 2018-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2001-01-01 |
| d    | 2018-01-01 | 2019-01-01 |
+------+------------+------------+

UPDATE ... FOR PORTION OF aynı mantıkla çalışır: aralığa düşen kısım güncellenir, dışarıda kalan kısımlar için gerektiğinde yeni satırlar eklenir. Belgelere göre bu ifade dönemin iki sütununu değiştiremez, SET ifadesinde dönem değerlerine başvuramaz ve FROM ... TO ifadeleri sabit olmalıdır. DELETE FOR PORTION için de aralık sabit olmalıdır ve çok tablolu silme desteklenmez. Tabloda DELETE ya da INSERT tetikleyicileri varsa, eşleşen satır silinir ve ardından bir ya da iki satır eklenir; satır tamamen silindiyse ekleme yapılmaz.

WITHOUT OVERLAPS ile çakışmayı engellemek

Rezervasyon sistemi gibi senaryolarda aynı oda için tarihleri çakışan iki kayıt olmamalıdır. WITHOUT OVERLAPS, dönemlerin çakışmamasını şart koşan bir index tanımlar; bu index birincil anahtar ya da benzersiz index olmalıdır. Belgelerdeki örnekte oda numarası ile dönemin birleşimi benzersizdir ve 2 numaralı odanın çakışan dördüncü kaydı reddedilir:

sql
CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE,
 PERIOD FOR p(checkin,checkout),
 UNIQUE (room_number, p WITHOUT OVERLAPS)
 );

INSERT INTO rooms VALUES
 (1, 'Regina', '2020-10-01', '2020-10-03'),
 (2, 'Cochise', '2020-10-02', '2020-10-05'),
 (1, 'Nowell', '2020-10-03', '2020-10-07'),
 (2, 'Eusebius', '2020-10-04', '2020-10-06');
ERROR 1062 (23000): Duplicate entry '2-2020-10-06-2020-10-04' for key 'room_number'

MariaDB 11.4'ten itibaren INFORMATION_SCHEMA.PERIODS ve KEY_PERIOD_USAGE görünümleri ile COLUMNS tablosundaki ek sütunlar dönemli tablolar hakkında bilgi verir.

Bitemporal tablolar

Bitemporal bir tablo hem sistem sürümlemesini hem bir uygulama zamanı dönemini birlikte kullanır. Böylece hem "bu bilgi gerçek dünyada hangi tarihlerde geçerliydi" hem de "veritabanı bu bilgiyi ne zaman biliyordu" sorularını yanıtlayabilirsiniz. Belgelere göre system_time de bir dönem olsa da DELETE FOR PORTION ya da UPDATE FOR PORTION ifadelerinde kullanılamaz; bu bir sözdizimi hatası üretir:

sql
CREATE TABLE test.t3 (
   date_1 DATE,
   date_2 DATE,
   row_start TIMESTAMP(6) AS ROW START INVISIBLE,
   row_end TIMESTAMP(6) AS ROW END INVISIBLE,
   PERIOD FOR application_time(date_1, date_2),
   PERIOD FOR system_time(row_start, row_end))
WITH SYSTEM VERSIONING;

Küçük bir uygulama: ürün fiyat geçmişi

Bir mağazada ürün fiyatlarının geçmişini, uygulamaya ek kod yazmadan saklamak istediğimizi düşünelim. Görüntülenme sayacı sık artar ve geçmişi önemsizdir, bu yüzden onu sürümlemeden hariç tutuyoruz; geçmiş satırlar ise aylık bölümlere otomatik dağılıyor:

sql
CREATE TABLE fiyatlar (
  urun_id INT UNSIGNED NOT NULL PRIMARY KEY,
  fiyat_kurus INT UNSIGNED NOT NULL,
  goruntulenme INT WITHOUT SYSTEM VERSIONING
) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH AUTO;

UPDATE fiyatlar SET fiyat_kurus = 129900 WHERE urun_id = 42;

SELECT fiyat_kurus
  FROM fiyatlar FOR SYSTEM_TIME AS OF TIMESTAMP'2026-10-01 00:00:00'
 WHERE urun_id = 42;

SELECT fiyat_kurus, ROW_START, ROW_END
  FROM fiyatlar FOR SYSTEM_TIME ALL
 WHERE urun_id = 42
 ORDER BY ROW_START;

Fiyat güncellendiğinde eski fiyat otomatik olarak geçmişe taşınır ve AS OF sorgusu belirtilen tarihteki fiyatı döndürür. Görüntülenme sayacını artıran güncellemeler ise yeni geçmiş satırı üretmez, çünkü yalnızca WITHOUT SYSTEM VERSIONING sütununu değiştirir. ALL ile tüm fiyat değişikliklerini ROW_START sırasıyla listeleyebilirsiniz. Saklama süresi dolan aylar DROP PARTITION ya da DELETE HISTORY ... BEFORE SYSTEM_TIME ile temizlenir. Tarih fonksiyonları için MariaDB tarih ve saat fonksiyonları yazısına bakabilirsiniz.

Sık yapılan hatalar

Sık yapılan hatalar: TRUNCATE ile geçmişi silmeye çalışmak., ALTER TABLE'ın neden reddedildiğini anlamamak., Her kayıtta tüm sütunları güncellemek., Yedekte geçmişi unutmak.
  • TRUNCATE ile geçmişi silmeye çalışmak. 4137 hatası alırsınız; DELETE HISTORY kullanın.
  • ALTER TABLE'ın neden reddedildiğini anlamamak. system_versioning_alter_history varsayılan olarak ERROR'dır; KEEP geçmişin yapısını bozar.
  • Her kayıtta tüm sütunları güncellemek. Değer değişmese de geçmiş satırı yazılır.
  • Yedekte geçmişi unutmak. mariadb-dump geçmişi ancak --dump-history ile alır.
  • Transaction hassasiyetli tabloyu SYSTEM_TIME ile bölümlemek. Bu birleşim desteklenmez.
  • Dönem sütunlarında NULL bırakmak. Dönem tanımı sütunları NOT NULL yapar.
  • Üretilmiş sütunları sürümlemeye çalışmak. Sürümleme ifadeleri sanal ve kalıcı üretilmiş sütunlara uygulanamaz.

Sık Sorulan Sorular

Sürümlü tabloda silinen bir satırı nasıl geri getiririm?

FOR SYSTEM_TIME AS OF ile silmeden önceki bir anı sorgulayıp satırı okuyun, sonra normal bir INSERT ile geri ekleyin. Belgeler bir tablonun belirli bir andaki durumunu geri getirmeyi tipik kullanımlar arasında sayar.

Gizli ROW_START ve ROW_END sütunlarını nasıl görürüm?

Kısa sözdizimiyle oluşturulan tablolarda bu sütunlar SELECT *'ta görünmez; seçim listesine ROW_START ve ROW_END yazarak okuyabilirsiniz.

Uygulama zamanı dönemi ile sistem sürümlemesi arasındaki fark nedir?

Sistem sürümlemesinde zamanı sunucu belirler ve geçmiş otomatik tutulur. Uygulama zamanı döneminde iki sütunu siz doldurursunuz ve satırın gerçek dünyadaki geçerlilik aralığını ifade eder. İkisi birlikte bitemporal tablo oluşturur.

Geçmiş tablonun boyutunu nasıl kontrol altında tutarım?

Geçmişi PARTITION BY SYSTEM_TIME ile ayrı bölümlerde tutun, eski bölümleri düşürün ya da DELETE HISTORY ... BEFORE SYSTEM_TIME ile belirli bir tarihten öncesini silin.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: MariaDB öğrenme rehberi · MariaDB tablo bölümleme · MariaDB trigger · mariadb-dump ile yedekleme · MariaDB tarih ve saat fonksiyonları · MariaDB transaction