PolarDB-X標準版提供了Sequence Engine,簡化獲取序列值的復雜度。
Sequence Engine介紹
在持久化數據庫系統中,無論是單節點中的業務主鍵,還是分布式系統中的全局唯一值,亦或是多系統中的冪等控制,單調遞增的唯一值是常見的需求。不同的數據庫系統有不同的實現方法,例如MySQL提供的AUTO_INCREMENT,Oracle、SQL Server提供的SEQUENCE。
在MySQL數據庫中,如果業務希望封裝唯一值,例如增加日期、用戶等信息,使用AUTO_INCREMENT的方法會帶來很大不便,在實際的系統設計中,也存在不同的折中方法:
序列值由Application或者Proxy來生成,不過弊端很明顯,狀態帶到應用端會增加擴容和縮容的復雜度。
序列值由數據庫通過模擬的表來生成,但需要中間件來封裝和簡化獲取唯一值的邏輯。
PolarDB-X標準版提供了Sequence Engine,通過引擎的設計方法,盡可能地兼容其他數據庫的使用方法,簡化獲取序列值復雜度。
Sequence Engine實現了MySQL存儲引擎的設計接口,但底層的數據仍然使用現有的存儲引擎,例如InnoDB或者MyISAM來保存持久化數據,兼容現有的第三方工具(例如Xtrabackup),所以Sequence Engine僅僅是一個邏輯引擎。
Sequence Engine通過Sequence Handler接口訪問Sequence對象,實現NEXTVAL的滾動、緩存的管理等,最后透傳給底層的基表數據引擎,實現最終的數據訪問。
前提條件
實例版本要求:PolarDB-X標準版,引擎為MySQL 8.0。
使用限制
Sequence不支持子查詢和join查詢。
可以使用
SHOW CREATE TABLE
來訪問Sequence結構。不支持在建表的時候指定Sequence引擎,Sequence表只能通過Sequence Engine的語法來創建。
創建Sequence
創建Sequence語句如下:
CREATE SEQUENCE [IF NOT EXISTS] <數據庫名>.<Sequence名稱>
[START WITH <constant>]
[MINVALUE <constant>]
[MAXVALUE <constant>]
[INCREMENT BY <constant>]
[CACHE <constant> | NOCACHE]
[CYCLE | NOCYCLE]
;
方括號([])中的內容非必填。
參數說明如下:
參數 | 說明 |
START WITH | Sequence的起始值。 |
MINVALUE | Sequence的最小值。 |
MAXVALUE | Sequence的最大值。 說明 如果有參數NOCYCLE,到達最大值后會報如下錯誤:ERROR HY000: Sequence 'db.seq' has been run out. |
INCREMENT BY | Sequence的步長。 |
CACHE/NOCACHE | 緩存的大小,為了性能考慮,可以設置較大的緩存,但如果遇到實例重啟,緩存內的值會丟失。 |
CYCLE/NOCYCLE | 表示Sequence如果用完了后,是否允許從MINVALUE重新開始。取值:
|
示例:
create sequence s
start with 1
minvalue 1
maxvalue 9999999
increment by 1
cache 20
cycle;
為了兼容MySQL Dump的備份方式,您也可以使用另外一種創建Sequence的方法,即創建Sequence表并插入一行初始記錄。示例如下:
CREATE TABLE schema.sequence_name ( `currval` bigint(21) NOT NULL COMMENT 'current value',
`nextval` bigint(21) NOT NULL COMMENT 'next value',
`minvalue` bigint(21) NOT NULL COMMENT 'min value',
`maxvalue` bigint(21) NOT NULL COMMENT 'max value',
`start` bigint(21) NOT NULL COMMENT 'start value',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache` bigint(21) NOT NULL COMMENT 'cache size',
`cycle` bigint(21) NOT NULL COMMENT 'cycle state',
`round` bigint(21) NOT NULL COMMENT 'already how many round'
) ENGINE=Sequence DEFAULT CHARSET=latin1;
INSERT INTO schema.sequence_name VALUES(0,0,1,9223372036854775807,1,1,10000,1,0);
COMMIT;
Sequence表介紹
由于Sequence是通過真正的引擎表來保存的,所以通過查詢創建語句看到仍然是默認的引擎表。示例如下:
SHOW CREATE TABLE schema.sequence_name;
CREATE TABLE schema.sequence_name (
`currval` bigint(21) NOT NULL COMMENT 'current value',
`nextval` bigint(21) NOT NULL COMMENT 'next value',
`minvalue` bigint(21) NOT NULL COMMENT 'min value',
`maxvalue` bigint(21) NOT NULL COMMENT 'max value',
`start` bigint(21) NOT NULL COMMENT 'start value',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache` bigint(21) NOT NULL COMMENT 'cache size',
`cycle` bigint(21) NOT NULL COMMENT 'cycle state',
`round` bigint(21) NOT NULL COMMENT 'already how many round'
) ENGINE=Sequence DEFAULT CHARSET=latin1
查詢語法
Sequence支持的查詢語法如下:
SELECT nextval(<Sequence名稱>),currval(<Sequence名稱>) FROM <Sequence名稱>;
SELECT <Sequence名稱>.currval, <Sequence名稱>.nextval FROM dual;
示例:
mysql> SELECT test.currval, test.nextval from dual;
+--------------+--------------+
| test.currval | test.nextval |
+--------------+--------------+
| 24 | 25 |
+--------------+--------------+
1 row in set (0.03 sec)
新創建的Sequence需要先調用一次該Sequence的NEXTVAL才能正常進行查詢,否則會報Sequence 'xxx' is not yet defined in current session錯誤。
NEXTVAL調用示例:
SELECT <Sequence名稱>.nextval FROM dual;