本文介紹如何在Lindorm寬表SQL中通過HINT設置時間戳來實現多版本數據管理。
引擎與版本
HINT語法僅適用于寬表引擎,且引擎版本需為2.3.1及以上版本。
功能介紹
Lindorm寬表引擎中,寫入每條數據時每列都會記錄時間戳,該時間戳一般記錄的是數據寫入時的服務器時間。默認情況下,該時間戳會作為每列的版本標識,用戶也可以在寫入數據時自定義時間戳,時間戳越大說明數據的版本越新。如果寬表的列要存儲多個版本的數據,需要在創建表時設置版本屬性'VERSIONS' = 'n'
(n為正整數,表示每列最多保留的版本數)。通過時間戳查詢多版本的數據時需要指定多版本屬性,多版本的相關屬性如下表:
屬性名稱 | 說明 | 適用語句 |
_l_ts_(N) | 自定義時間戳的值。 | UPSERT、SELECT |
_l_versions_(N) | 表示查詢結果中返回最新的N個版本的數據。 | SELECT |
_l_ts_min_(N) | 用于過濾查詢結果,表示查詢結果中返回時間戳大于等于N的數據。 | SELECT |
_l_ts_max_(N) | 用于過濾查詢結果,表示查詢結果中返回時間戳小于N的數據。 | SELECT |
使用方法
設置時間戳并查詢數據
Lindorm寬表支持在非主鍵列中設置時間戳并通過時間戳查詢指定版本的數據。
創建測試表,指定保留的版本數。語句如下:
CREATE TABLE t_test_versions_2 (c1 INT , c2 INT, c3 VARCHAR(50), PRIMARY KEY(c1)) WITH(VERSIONS='5');
說明您可以執行
ALTER TABLE table_name SET 'VERSIONS' = 'num';
語句為已創建的數據表指定或修改版本數,其中table_name為數據表名稱,num為版本數。寫入數據。設置時間戳時需要指定多版本屬性,語句如下:
UPSERT /*+ _l_ts_(1000) */ INTO t_test_versions_2(c1, c3) values (1, '11'); UPSERT /*+ _l_ts_(2001) */ INTO t_test_versions_2(c1, c3) values (1, '22'); UPSERT /*+ _l_ts_(1000) */ INTO t_test_versions_2(c1, c2) values (1, 1); UPSERT /*+ _l_ts_(2001) */ INTO t_test_versions_2(c1, c2) values (2, 1); UPSERT /*+ _l_ts_(2002) */ INTO t_test_versions_2(c1, c2) values (2, 2); UPSERT /*+ _l_ts_(2003) */ INTO t_test_versions_2(c1, c2) values (2, 3); UPSERT /*+ _l_ts_(2004) */ INTO t_test_versions_2(c1, c2) values (2, 4); UPSERT /*+ _l_ts_(2005) */INTO t_test_versions_2(c1, c2) values (2, 5); UPSERT /*+ _l_ts_(2006) */ INTO t_test_versions_2(c1, c2) values (2, 6);
通過時間戳查詢指定版本的數據。如果要查看時間戳,需要在列名后加上時間戳后綴(即
_l_ts
)。示例一:返回指定時間戳為1000的數據。
SELECT /*+ _l_ts_(1000) */ c1, c3, c3_l_ts FROM t_test_versions_2 WHERE c1 = 1;
返回結果:
+----+----+---------+ | c1 | c3 | c3_l_ts | +----+----+---------+ | 1 | 11 | 1000 | +----+----+---------+
示例二:查詢時間戳在
[1000,2001)
范圍內的數據。SELECT /*+ _l_ts_min_(1000), _l_ts_max_(2001) */ c1, c3, c3_l_ts FROM t_test_versions_2 WHERE c1 = 1;
返回結果:
+----+----+---------+ | c1 | c3 | c3_l_ts | +----+----+---------+ | 1 | 11 | 1000 | +----+----+---------+
示例三:返回最新的N個版本的數據,需要指定
_l_versions_(N)
屬性。SELECT /*+ _l_versions_(1) */ c1, c3, c3_l_ts FROM t_test_versions_2 WHERE c1 = 1;
返回結果:
+----+----+---------+ | c1 | c3 | c3_l_ts | +----+----+---------+ | 1 | 22 | 2001 | +----+----+---------+
示例四:每列返回最新的兩個版本數據,并且按照時間戳相同的列合并為一行返回結果集。查詢語句中指定
_l_versions_(N)
屬性會返回所有非主鍵列的時間戳數據。SELECT /*+ _l_versions_(2) */ c1, c2, c3, c2_l_ts, c3_l_ts FROM t_test_versions_2;
返回結果如下:
+----+------+------+---------+---------+ | c1 | c2 | c3 | c2_l_ts | c3_l_ts | +----+------+------+---------+---------+ | 1 | null | 22 | null | 2001 | | 1 | 1 | 11 | 1000 | 1000 | | 2 | 6 | null | 2006 | null | | 2 | 5 | null | 2005 | null | +----+------+------+---------+---------+
示例五:由于創建表時設置版本屬性僅保留5個版本的數據,所以盡管指定
_l_versions_(6)
屬性也只能返回5個版本的數據。SELECT /*+ _l_versions_(6) */ c1, c2, c2_l_ts FROM t_test_versions_2 WHERE c1=2;
返回結果如下:
+----+----+---------+ | c1 | c2 | c2_l_ts | +----+----+---------+ | 2 | 6 | 2006 | | 2 | 5 | 2005 | | 2 | 4 | 2004 | | 2 | 3 | 2003 | | 2 | 2 | 2002 | +----+----+---------+