• Create Sequence 语法
    • Show Create Sequence 语法
    • Drop Sequence
    1. DROP [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name
    • 获取下一个值
    1. SELECT NEXT VALUE FOR sequence_name;
    2. SELECT NEXTVAL(sequence_name);
    • 获取上一个/当前值
    1. SELECT PREVIOUS VALUE FOR sequence_name;
    2. SELECT LASTVAL(sequence_name);
    • 修改当前值
    1. SELECT SETVAL(sequence_name,100);

    本部分将会通过一些案例介绍 TiDB Sequence 的使用方法:

    • 并发应用需要获取单调递增的序列号

    在使用分布式数据库的场景里,通常应用也是分布式架构,这样多个应用节点之间如何获取唯一且递增的序列号就成为一个难题。在分布式数据库没有 Sequence 的时候,应用基本通过雪花算法数据库主键自增等方法实现,业界也有一些较为成熟的方案,比如 、百度的 uid-generator 等,上述方案中为了解决该问题引入一个新的系统或模块,极大的增加了应用系统的复杂度。接下来我们看看 TiDB 如何通过 Sequence 解决上述问题。

    (1) 首先新建一个 Sequence

    (2) 从不同的 TiDB 节点获取到的 Sequence 值顺序有所不同

    如果两个应用节点同时连接至同一个 TiDB 节点,两个节点取到的则为连续递增的值

    1. 节点 Atidb[test]> SELECT NEXT VALUE FOR seq_for_unique;
    2. +-------------------------------+
    3. | NEXT VALUE FOR seq_for_unique |
    4. +-------------------------------+
    5. | 1 |
    6. +-------------------------------+
    7. 1 row in set (0.00 sec)
    8. 节点 Btidb[test]> SELECT NEXT VALUE FOR seq_for_unique;
    9. +-------------------------------+
    10. | NEXT VALUE FOR seq_for_unique |
    11. +-------------------------------+
    12. | 2 |
    13. +-------------------------------+
    1. 节点 Atidb[test]> SELECT NEXT VALUE FOR seq_for_unique;
    2. +-------------------------------+
    3. | NEXT VALUE FOR seq_for_unique |
    4. +-------------------------------+
    5. | 1 |
    6. +-------------------------------+
    7. 1 row in set (0.00 sec)
    8. 节点 Btidb[test]> SELECT NEXT VALUE FOR seq_for_unique;
    9. +-------------------------------+
    10. | NEXT VALUE FOR seq_for_unique |
    11. +-------------------------------+
    12. | 1001 |
    13. +-------------------------------+
    14. 1 row in set (0.00 sec)
    • 在一张表里面需要有多个自增字段

    MySQL 语法中每张表仅能新建一个 auto_increment 字段,且该字段必须定义在主键或是索引列上。在 TiDB 中通过 Sequence 和生成列,我们可以实现多自增字段需求。

    (1) 首先新建如下两个 Sequence

    1. CREATE SEQUENCE seq_for_autoid START WITH 1 INCREMENT BY 2 CACHE 1000 NOCYCLE;
    2. CREATE SEQUENCE seq_for_logid START WITH 100 INCREMENT BY 1 CACHE 1000 NOCYCLE;

    (2) 在新建表的时候通过 default nextval(seq_name) 设置列的默认值

    1. CREATE TABLE `user` (
    2. `userid` varchar(32) NOT NULL,
    3. `autoid` int(11) DEFAULT 'nextval(`test`.`seq_for_autoid`)',
    4. `logid` int(11) DEFAULT 'nextval(`test`.`seq_for_logid`)',
    5. PRIMARY KEY (`userid`)
    6. )

    (3) 接下来我们插入几个用户信息进行测试:

    1. INSERT INTO user (userid) VALUES ('usera');
    2. INSERT INTO user (userid) VALUES ('userb');
    3. INSERT INTO user (userid) VALUES ('userc');

    (4) 查询 user 表,可以发现 autoidlogid 字段的值按照不同的步长进行自增,且主键仍然在列 userid 上:

    • 更新数据表中一列值为连续自增的值

    (1) 新建一张测试表

    1. tidb[test]> CREATE TABLE t( a int, name varchar(32));
    2. Query OK, 0 rows affected (0.01 sec)

    (2) 新建一个 Sequence

    1. Query OK, 0 rows affected (0.00 sec)

    (3) 插入 1 万条记录

    1. for i in $(seq 1 10000)
    2. do
    3. echo "insert into t values($(($RANDOM%1000)),'user${i}');" >> user.sql
    1. tidb[test]> select count(*) from t;
    2. +----------+
    3. | count(*) |
    4. +----------+
    5. | 10000 |
    6. +----------+
    7. 1 row in set (0.05 sec)
    8. tidb[test]> select * from t;
    9. +------+-----------+
    10. | a | name |
    11. +------+-----------+
    12. | 355 | user1 |
    13. | 729 | user2 |
    14. | 684 | user3 |
    15. | 815 | user4 |
    16. | 39 | user5 |
    17. | 294 | user6 |
    18. | 407 | user7 |
    19. | 767 | user8 |
    20. | 246 | user9 |
    21. | 755 | user10 |
    22. | 496 | user11 |
    23. ...

    (4) 更新为连续的值

    1. tidb[test]> update t set a=nextval(test);
    2. Query OK, 10000 rows affected (0.20 sec)

    (5) 查询结果集,可以看到字段 a 的值已经连续自增且唯一

    7.3.2 注意事项