Delta tabloları iki geçmiş sorgu modunu destekler: zaman yolculuğu sorguları ve artımlı sorgular. Zaman yolculuğu sorgusu, tablonun belirli bir zamandaki veya sürümdeki anlık görüntüsünü okur. Artımlı sorgu ise iki zaman noktası veya iki sürüm arasında değişen satırları döndürür.
Her iki sorgu türü de standart MaxCompute Veri Sorgulama Dili (DQL) sözdizimini genişletir. Tüm DQL sözdizimi ve sınırlamalar geçerlidir; tek bir ekleme vardır: FROM yan tümcesi bir zaman veya sürüm niteleyicisini kabul eder.
Sözdizimi
[WITH <cte>[, ...] ]
SELECT [ALL | DISTINCT] <select_expr>[, <except_expr>)][, <replace_expr>] ...
FROM <table_reference>
[TIMESTAMP | VERSION AS OF expr]
[TIMESTAMP | VERSION BETWEEN start_expr AND end_expr]
[WHERE <where_condition>]
[GROUP BY {<col_list> | ROLLUP(<col_list>)}]
[HAVING <having_condition>]
[ORDER BY <order_condition>]
[DISTRIBUTE BY <distribute_condition> [SORT BY <sort_condition>]|[ CLUSTER BY <cluster_condition>] ]
[LIMIT <number>]
[WINDOW <window_clause>]
Zaman yolculuğu sorguları için TIMESTAMP | VERSION AS OF expr, artımlı sorgular için ise TIMESTAMP | VERSION BETWEEN start_expr AND end_expr kullanın.
Zaman yolculuğu sorguları
Zaman yolculuğu sorgusu, tablonun tarihsel bir anlık görüntüsünü döndürür; verilerin belirtilen zaman noktasındaki veya sürümündeki ya da öncesindeki durumunu gösterir.
TIMESTAMP AS OF
SELECT * FROM <table> TIMESTAMP AS OF <expr>
expr aşağıdaki biçimlerden herhangi birini kabul eder:
| Biçim | Örnek | Açıklama |
|---|---|---|
| TIMESTAMP dizesi | '2023-01-01 00:00:00.123' |
Milisaniye içeren kesin zaman damgası |
| DATETIME dizesi | '2023-01-01 00:00:00' |
Milisaniye içermeyen zaman damgası |
| DATE dizesi | '2023-01-01' |
Yalnızca tarih; saat varsayılan olarak gece yarısıdır |
current_timestamp() |
current_timestamp() |
Geçerli saat |
getDate() + N |
getDate() - 3600 |
Şu ana göre N saniye; negatif değer geçmiş, pozitif değer gelecektir |
get_latest_timestamp(tablename [, number]) |
get_latest_timestamp('mf_tt2', 2) |
En son gerçekleşen N. DML işleminin zaman damgası (varsayılan: 1 = en son). Döndürülen zaman damgası, farklı number değerleri için aynı olabilir. |
Proje çapraz erişim için tablename öğesini ProjectName.TableName biçiminde belirtin. Üç katmanlı model için ProjectName.SchemaName.TableName kullanın.
Sınırlamalar:
Geçerli sorgu aralığı
[CreateTableTimestamp, expr]şeklindedir; buradaCreateTableTimestamptablo oluşturma işleminin onaylandığı saattir.exprtablo oluşturma saatinden önceyse veya N saatten daha eskiyse bir hata döndürülür. N değeri, tablo oluşturma sırasındaacid.data.retain.hoursözelliği ile ayarlanır. Örneğin,acid.data.retain.hoursdeğeri72ise veexpr80 saat öncesi ise sorgu başarısız olur.exprtam olarak N saat önceyse, dahili sistemlerdeki saniye düzeyindeki gecikme süresi nedeniyle yine de hata döndürülebilir.
Saklama sınırına yakın sorgular için TIMESTAMP AS OF current_timestamp() - <seconds> kullanmaktan kaçının. Son onaylamalara güvenli bir şekilde başvurmak için get_latest_timestamp() kullanın.
VERSION AS OF
SELECT * FROM <table> VERSION AS OF <expr>
expr şunları kabul eder:
| Biçim | Örnek | Açıklama |
|---|---|---|
| BIGINT sabiti | 3 |
Belirli bir sürüm numarası |
get_latest_version(tablename [, number]) |
get_latest_version('mf_tt2', 2) |
En son gerçekleşen N. DML işleminin sürümü (varsayılan: 1 = en son). get_latest_timestamp işlevinden farklı olarak, döndürülen sürüm her number değeriyle birlikte değişir. |
tablename biçimlendirmesi için get_latest_timestamp() ile aynı kuralları uygulayın.
Sınırlamalar:
Her DML işlemi kesin olarak artan bir sürüm numarası oluşturur. Tüm sürümleri görüntülemek için
SHOW HISTORY FOR TABLE/PARTITIONçalıştırın.Geçerli sürüm aralığı
[CreateTableVersion, expr]şeklindedir.CreateTableVersionvarsayılan olarak1değerine sahiptir.Sürüm, N saatten (N =
acid.data.retain.hours) daha eski bir onaylama zamanına karşılık geliyorsa veya sürüm1değerinden küçükse bir hata döndürülür.expren son DML sürümünü aşarsa bir hata döndürülür.
Geçerli bir sürüm numarası almak ve aralık dışı hatalardan kaçınmak için get_latest_version() kullanın.
Artımlı sorgular
Artımlı sorgu, yalnızca bir zaman aralığında veya sürüm aralığında eklenen ya da değiştirilen satırları döndürür; bu, iki anlık görüntü arasındaki farka eşdeğerdir.
Birleştirme (compaction) işlemiyle üretilen veriler yeni veri olarak değerlendirilmez ve artımlı sorgu sonuçlarının dışında tutulur.
TIMESTAMP BETWEEN
SELECT * FROM <table> TIMESTAMP BETWEEN <start_expr> AND <end_expr>
Zaman aralığı (start_expr, end_expr] şeklindedir — sol taraf açık, sağ taraf kapalıdır. Her iki ifade de TIMESTAMP AS OF tarafından desteklenen aynı biçimleri takip eder.
Sınırlamalar:
start_exprtablo oluşturma saatinden önceyse veya N saatten daha eskiyse bir hata döndürülür. N =acid.data.retain.hours.-
end_exprson DML onaylama saatinden sonra ise davranış,acid.incremental.query.out.of.time.range.enabledayarına bağlıdır:Varsayılan (
false): Bir hata döndürülür.trueolarak ayarlandığında: Sorgu,(start_expr, end_expr]aralığındaki tüm artımlı verileri döndürür.
En son onaylamanın ötesine geçen sorgulara izin vermek için özelliği true olarak ayarlayın:
ALTER TABLE <table> SET tblproperties("acid.incremental.query.out.of.time.range.enabled"="true");
VERSION BETWEEN
SELECT * FROM <table> VERSION BETWEEN <start_expr> AND <end_expr>
Sürüm aralığı (start_expr, end_expr] şeklindedir — sol taraf açık, sağ taraf kapalıdır. Her iki ifade de VERSION AS OF tarafından desteklenen aynı biçimleri takip eder.
Sınırlamalar:
Sistem,
start_exprifadesini bir onaylama zamanına çözer. Bu zaman N saatten daha eskiyse veya sürüm1değerinden küçükse bir hata döndürülür. N =acid.data.retain.hours.-
end_expren son DML sürümünü aşarsa davranış,acid.incremental.query.out.of.time.range.enabledayarına bağlıdır:Varsayılan (
false): Bir hata döndürülür.trueolarak ayarlandığında: Sorgu,(start_expr, end_expr]aralığındaki tüm artımlı verileri döndürür.
Kullanım notları
Yalnızca Delta tabloları zaman yolculuğu sorgularını ve artımlı sorguları destekler.
Yinelenen anahtarlar: Birden fazla satır aynı birincil anahtarı paylaştığında yalnızca en son satır döndürülür.
DELETEdurumundaki satırlar hariç tutulur.Değişim Verisi Yakalama (CDC): Değişim Verisi Yakalama (CDC) benzeri biçimlerde verilerin güncelleme durumunu sorgulama henüz desteklenmemektedir ve gelecek bir sürümde planlanmaktadır.
Silinen veya yeniden adlandırılan tablolar: Bir tablo silindikten veya yeniden adlandırıldıktan sonra tarihsel verilerini sorgulayamazsınız. Önce tabloyu geri yükleyin, ardından sorguyu çalıştırın.
Aynı tablo, birden çok niteleyici: Bir SQL ifadesinde aynı tablo üzerinde zaman yolculuğu sorgusu veya artımlı sorgu gerçekleştirmek istiyorsanız, sorgular için zaman damgalarını veya sürümleri aynı değerlere ayarlamanız gerekir.
Bölümlenmiş tablolar: Taramayı o bölümle sınırlamak ve sorgu süresini azaltmak için
WHEREyan tümcesinde bir bölüm belirtin.Eşzamanlılık: Delta tabloları, eşzamanlı okuma ve yazma işlemlerini yalıtmak için Çoklu Sürüm Eşzamanlılık Kontrolü (MVCC) kullanır. Read Committed yalıtım düzeyi desteklenir.
Örnekler
Aşağıdaki örnekler, bölümlenmiş bir Delta tablosu mf_tt2 kullanır.
Örnek verileri ayarlama
-- Table creation. Version = 1.
-- Run "SHOW HISTORY FOR TABLE mf_tt2" to confirm.
CREATE TABLE mf_tt2 (
pk bigint NOT NULL PRIMARY KEY,
val bigint NOT NULL)
PARTITIONED BY (dd string, hh string)
tblproperties ("transactional"="true");
-- INSERT OVERWRITE. Version = 2.
INSERT OVERWRITE TABLE mf_tt2 PARTITION (dd='01', hh='01') VALUES (1, 1), (2, 2), (3, 3);
-- INSERT INTO. Version = 3.
INSERT INTO TABLE mf_tt2 PARTITION (dd='01', hh='01') VALUES (3, 30), (4, 4), (5, 5);
Sorguları çalıştırmadan önce tablo oluşturma saatini ve sürüm geçmişini kontrol etmek için:
-- Get the table creation timestamp
DESC EXTENDED mf_tt2;
Aşağıdaki sonuç döndürülür.
+------------------------------------------------------------------------------------+
| Owner: ALIYUN$****_doctest@test.aliyunid.com | Project: doc_test_prod |
| TableComment: |
+------------------------------------------------------------------------------------+
| CreateTime: 2023-06-26 09:31:38 |
| LastDDLTime: 2023-06-26 09:31:38 |
| LastModifiedTime: 2023-06-26 09:32:31 |
+------------------------------------------------------------------------------------+
| InternalTable: YES | Size: 8541 |
+------------------------------------------------------------------------------------+
| Native Columns: |
+------------------------------------------------------------------------------------+
| Field | Type | Label | ExtendedLabel | Nullable | DefaultValue | Comment |
+------------------------------------------------------------------------------------+
| pk | bigint | | | false | NULL | |
| val | bigint | | | false | NULL | |
+------------------------------------------------------------------------------------+
| Partition Columns: |
+------------------------------------------------------------------------------------+
| dd | string | |
| hh | string | |
+------------------------------------------------------------------------------------+
| Extended Info: |
+------------------------------------------------------------------------------------+
| TableID: bec515a56cc9492c8f906a224c62**** |
| IsArchived: false |
| PhysicalSize: 25623 |
| FileNum: 9 |
| StoredAs: AliOrc |
| CompressionStrategy: normal |
| ClusterType: hash |
| BucketNum: 16 |
| ClusterColumns: [pk] |
| SortColumns: [pk ASC] |
+------------------------------------------------------------------------------------+
-- Get all DML version numbers and commit times
SHOW HISTORY FOR TABLE mf_tt2 PARTITION (dd='01', hh='01');
Aşağıdaki sonuç döndürülür.
ID = 20230626021756157ghict5k****
ObjectType ObjectId ObjectName VERSION(LSN) Time Operation
PARTITION 4764c8e1cb634a4fb9c21f3fc850**** dd=01/hh=01 0000000000000002 2023-06-26 09:31:56 CREATE
PARTITION 4764c8e1cb634a4fb9c21f3fc850**** dd=01/hh=01 0000000000000003 2023-06-26 09:32:32 APPEND
SHOW HISTORY çıktısı, her işlemi, sürüm numarasını, onaylama saatini ve işlem türünü (CREATE, APPEND vb.) gösterir.
Zaman yolculuğu sorgu örnekleri
Belirli bir tarih saatteki anlık görüntü — 09:33:00 itibarıyla tüm veriler:
SELECT * FROM mf_tt2 TIMESTAMP AS OF '2023-06-26 09:33:00' WHERE dd = '01' AND hh = '01';
2. ve 3. sürümler tarafından yazılan tüm 5 satırı döndürür (pk 1–5, pk=3 en son yazımdan dolayı val=30 değerini gösterir).
2. sürümdeki anlık görüntü — INSERT INTO öncesinde:
SELECT * FROM mf_tt2 VERSION AS OF 2 WHERE dd = '01' AND hh = '01';
INSERT OVERWRITE işleminden gelen 3 satırı döndürür: pk=1, pk=2, pk=3 (val=3).
Geçerli zamandaki anlık görüntü:
SELECT * FROM mf_tt2 TIMESTAMP AS OF current_timestamp() WHERE dd = '01' AND hh = '01';
10 saniye önceki anlık görüntü:
SELECT * FROM mf_tt2 TIMESTAMP AS OF current_timestamp() - 10 WHERE dd = '01' AND hh = '01';
İkinci en son onaylamadaki anlık görüntü (get_latest_timestamp kullanarak):
SELECT * FROM mf_tt2 TIMESTAMP AS OF get_latest_timestamp('mf_tt2', 2) WHERE dd = '01' AND hh = '01';
2. sürümden gelen 3 satırı döndürür.
İkinci en son sürümdeki anlık görüntü (get_latest_version kullanarak):
SELECT * FROM mf_tt2 VERSION AS OF get_latest_version('mf_tt2', 2) WHERE dd = '01' AND hh = '01';
2. sürümden gelen 3 satırı döndürür.
Artımlı sorgu örnekleri
İki onaylama zaman damgası arasındaki değişiklikler:
SELECT * FROM mf_tt2 TIMESTAMP BETWEEN '2023-06-26 09:31:40' AND '2023-06-26 09:32:00' WHERE dd = '01' AND hh = '01';
2. sürüm tarafından yazılan 3 satırı döndürür.
2. sürüm ile 3. sürüm arasındaki değişiklikler:
SELECT * FROM mf_tt2 VERSION BETWEEN 2 AND 3 WHERE dd = '01' AND hh = '01';
3. sürüm tarafından yazılan 3 satırı döndürür: pk=3 (val=30), pk=4, pk=5.
Son 300 saniye; acid.incremental.query.out.of.time.range.enabled değeri false (varsayılan) olarak ayarlandığında:
SELECT * FROM mf_tt2 TIMESTAMP BETWEEN current_timestamp() - 301 AND current_timestamp() WHERE dd = '01' AND hh='01';
end_expr en son onaylama zaman damgasını aştığı için bir hata döndürülür:
FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed:
com.aliyun.odps.meta.exception.MetaException: ...
Incremental query can't exceed current version. Current version timestamp: 2023-06-26 09:32:32, input timestamp is: 2023-06-26 10:47:55
Sorgunun en son onaylamanın ötesine geçmesine izin vermek için özelliği etkinleştirin:
ALTER TABLE mf_tt2 SET tblproperties("acid.incremental.query.out.of.time.range.enabled"="true");
Ardından sorguyu yeniden çalıştırın. Sonuç boştur (son 300 saniyede yeni veri yazılmamıştır):
+------------+------------+----+----+
| pk | val | dd | hh |
+------------+------------+----+----+
+------------+------------+----+----+
Üçüncü en son onaylamadan en son onaylamaya kadar olan değişiklikler:
SELECT * FROM mf_tt2 TIMESTAMP BETWEEN get_latest_timestamp('mf_tt2', 3) AND get_latest_timestamp('mf_tt2') WHERE dd = '01' AND hh = '01';
Tüm 5 satırı döndürür (hem 2. hem de 3. sürüm onaylamalarını kapsar).
Üçüncü en son sürümden en son sürüme kadar olan değişiklikler:
SELECT * FROM mf_tt2 VERSION BETWEEN get_latest_version('mf_tt2', 3) AND get_latest_version('mf_tt2') WHERE dd = '01' AND hh = '01';
Tüm 5 satırı döndürür.