全部產品
Search
文件中心

ApsaraDB RDS:Sequence Engine

更新時間:Feb 28, 2024

AliSQL提供了Sequence Engine,簡化擷取序列值的複雜度。

Sequence Engine介紹

在持久化資料庫系統中,無論是單節點中的業務主鍵,還是分布式系統中的全域唯一值,亦或是多系統中的等冪控制,單調遞增的唯一值是常見的需求。不同的資料庫系統有不同的實現方法,例如MySQL提供的AUTO_INCREMENT,Oracle、SQL Server提供的SEQUENCE。

在MySQL資料庫中,如果業務希望封裝唯一值,例如增加日期、使用者等資訊,使用AUTO_INCREMENT的方法會帶來很大不便,在實際的系統設計中,也存在不同的折中方法:

  • 序列值由Application或者Proxy來產生,不過弊端很明顯,狀態帶到應用端會增加擴容和縮容的複雜度。

  • 序列值由資料庫通過類比的表來產生,但需要中介軟體來封裝和簡化擷取唯一值的邏輯。

AliSQL提供了Sequence Engine,通過引擎的設計方法,儘可能地相容其他資料庫的使用方法,簡化擷取序列值複雜度。

Sequence Engine實現了MySQL儲存引擎的設計介面,但底層的資料仍然使用現有的儲存引擎,例如InnoDB或者MyISAM來儲存持久化資料,相容現有的第三方工具(例如Xtrabackup),所以Sequence Engine僅僅是一個邏輯引擎。

Sequence Engine通過Sequence Handler介面訪問Sequence對象,實現NEXTVAL的滾動、緩衝的管理等,最後透傳給底層的基表資料引擎,實現最終的資料訪問。

前提條件

執行個體版本如下:

  • RDS MySQL 8.0(核心小版本為20190816及以上)

  • RDS MySQL 5.7(核心小版本為20210430及以上)

  • RDS MySQL 5.6(核心小版本為20170901及以上)

說明

執行個體系列不能是三節點企業系列。

使用限制

  • Sequence不支援子查詢和join查詢。

  • 可以使用SHOW CREATE TABLE來訪問Sequence結構。

  • 不支援建表的時候指定Sequence引擎,Sequence表只能通過建立Sequence的文法來建立。

建立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重新開始。取值:

  • CYCLE:允許;

  • NOCYCLE:不允許。

樣本:

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名稱>;

    說明

    適用於MySQL 8.0、MySQL 5.7。

  • SELECT <Sequence名稱>.currval, <Sequence名稱>.nextval FROM dual;

    說明

    適用於MySQL 8.0、MySQL 5.7、MySQL 5.6。

樣本:

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;