阅读424 返回首页    go 小米


全局唯一数字序列使用__开发手册_分布式关系型数据库 DRDS-阿里云

DRDS全局唯一数字序列(64位数字,对应MySQL中BIGINT类型,以下简称为sequence)的主要目标是为了保证所定义唯一字段中的数据的全局唯一(比如PRIMARY KEY,UNIQUE KEY等)和有序递增,但不保证连续性,用户不能依赖sequence的连续性进行任何业务操作。

DRDS中的sequence主要有两类用法:

  • 隐式sequence,在为主键定义AUTO_INCREMENT后,用于自动填充主键,由DRDS自动维护;

  • 显式sequence,通过DRDS的DDL语法创建和维护,可以独立使用。

主键自动填充

DRDS能够支持INSERT时自动填充主键(BIGINT类型,设定为PRIMARY KEY、AUTO_INCREMENT)。这样就意味着,在INSERT语句中若没有指定主键,DRDS会自动地将主键填充进来,请参考以下示例:

  1. mysql> insert into users (name,address,gmt_created,gmt_modified,intro) values ('sun','hz',now(),now(),'aa');
  2. Query OK, 1 row affected (0.02 sec)
  3. mysql> select last_insert_id();
  4. +------------------+
  5. | LAST_INSERT_ID() |
  6. +------------------+
  7. | 5018 |
  8. +------------------+
  9. 1 row in set (0.00 sec)

您也可以使用标准的JDBC接口来获取LastInsertId,与普通的MySQL一致。

注意:当创建DRDS库为非拆分模式,DRDS自动填充主键机制失效,由MySQL生成。

创建、查询、更新和删除sequence

在以下sequence语法中:

  • 大写单词为关键字;
  • 小写斜体单词为需要用户指定的名称或数值;
  • 中括号内包含的为可选项;
  • 尖括号内包含的为必填项;
  • 竖线分隔的关键词为“或”的关系,即多选一。

请注意,上述大小写的区分仅为语法说明的目的,在语句的实际使用中并不区分大小写。

创建sequence

创建sequence语句如下:

CREATE SEQUENCE < sequence name > [ START WITH < numeric value > ] [ INCREMENT BY < numeric value > ] [ MAXVALUE < numeric value > ] [ CYCLE | NOCYCLE ]

START WITH:代表sequence的起始值,若未指定,则默认值为1;

INCREMENT BY:代表sequence每次增长时的增量值(或称为间隔值或步长),若未指定,则默认值为1;

MAXVALUE:代表sequence允许的最大值,若未指定,则默认值为有符号长整形(Signed BIGINT)的最大正值;

CYCLE或NOCYCLE:两者只能选择其一,代表当sequence值增长到最大值后,是否允许继续循环(即仍从START WITH开始)使用sequence值,若未指定,则默认值为NOCYCLE。

示例:

  • 指定所有参数:

    1. mysql> create sequence sample_seq start with 10 increment by 2 maxvalue 10000000 nocycle;
    2. Query OK, 1 row affected (0.01 sec)
  • 指定部分参数,其余使用默认值:

    1. mysql> create sequence sample_seq_part start with 100;
    2. Query OK, 1 row affected (0.01 sec)
  • 不指定参数,全部使用默认值:

    1. mysql> create sequence sample_seq_default;
    2. Query OK, 1 row affected (0.01 sec)

查询sequence

查询sequence语句如下:

SHOW SEQUENCES

示例:

  1. mysql> show sequences;
  2. +------+-------------------------------+--------+---------------------+
  3. | ID | NAME | VALUE | GMT_MODIFIED |
  4. +------+-------------------------------+--------+---------------------+
  5. | 1 | AUTO_SEQ_USERS | 5000 | 2014-08-09 18:20:28 |
  6. | 2 | AUTO_SEQ_ITEMS | 5000 | 2014-06-18 16:08:06 |
  7. | 3 | AUTO_SEQ_ORDERS | 6000 | 2014-06-18 16:08:06 |
  8. | 4 | sample_seq | 12000 | 2014-08-09 18:21:28 |
  9. | 5 | AUTO_SEQ_DEF | 2000 | 2014-07-04 17:55:36 |
  10. | 6 | WEBO_COMMENTS | 0 | 2014-07-13 19:38:55 |
  11. | 7 | AUTO_SEQ_ABC | 66000 | 2014-07-16 15:10:43 |
  12. | 8 | AUTO_SEQ_CATEGORY | 2000 | 2014-07-17 15:53:27 |
  13. | 9 | AUTO_SEQ_USER | 2000 | 2014-07-25 16:54:29 |
  14. | 10 | AUTO_SEQ_CLUSTER | 2000 | 2014-07-27 15:58:34 |
  15. | 11 | AUTO_SEQ_SPE_CLUSTER | 2000 | 2014-07-28 16:21:30 |
  16. | 12 | AUTO_SEQ_A | 2000 | 2014-07-28 16:22:08 |
  17. +------+-------------------------------+--------+---------------------+
  18. 17 rows in set (0.04 sec)

更新sequence

更新sequence语句如下:

ALTER SEQUENCE < sequence name > START WITH < numeric value > [ INCREMENT BY < numeric value > ] [ MAXVALUE < numeric value > ] [ CYCLE | NOCYCLE ]

START WITH:代表sequence的起始值,是必选项,该参数会更新当前维护的sequence值;若想保留更新sequence之前的原sequence值,请先查询原值并用该参数指定;

INCREMENT BY:代表sequence每次增长时的增量值(或称为间隔值或步长),若未指定,则沿用原值;

MAXVALUE:代表sequence允许的最大值,若未指定,则沿用原值;

CYCLE或NOCYCLE:两者只能选择其一,代表当sequence值增长到最大值后,是否允许继续循环(即仍从START WITH开始)使用sequence值,若未指定,则沿用原值。

示例:

  • 指定所有参数:

    1. mysql> alter sequence sample_seq start with 1000 increment by 1 maxvalue 10000000 cycle;
    2. Query OK, 1 row affected (0.01 sec)
  • 指定部分参数,其余沿用原值:

    1. mysql> alter sequence sample_seq start with 100;
    2. Query OK, 1 row affected (0.01 sec)

删除sequence

删除sequence语句如下:

DROP SEQUENCE < sequence name >

示例:

  1. mysql> drop sequence sample_seq;

常用操作及常见问题处理

获取显式sequence值

可以通过DRDS指定SQL获取最新sequence值, 语法是:

< sequence name >.NEXTVAL

示例:

  1. select sample_seq.nextVal from dual;
  2. +--------------------+
  3. | SAMPLE_SEQ.NEXTVAL |
  4. +--------------------+
  5. | 101001 |
  6. +--------------------+
  7. 1 row in set (0.04 sec)

或者可以把这个SAMPLE_SEQ.nextVal当做一个值写入sql中:

  1. mysql> insert into some_users (name,address,gmt_create,gmt_modified,intro) values ('sun',SAMPLE_SEQ.nextVal,now(),now(),'aa');
  2. Query OK, 1 row affected (0.01 sec)

如何处理主键冲突

当您直接在RDS中写入了数据,而对应的主键值不是DRDS生成的sequence值,那么后续让DRDS自动生成主键写入数据库,可能会和这些数据发生主键冲突,一般我们可以通过以下几步解决问题:

1、通过DRDS指定SQL来查看当前已有sequence(AUTO_SEQ_是DRDS自动加上的sequence名字的前缀,USERS指表名):

  1. mysql> show sequences;
  2. +------+-------------------------------+--------+---------------------+
  3. | ID | NAME | VALUE | GMT_MODIFIED |
  4. +------+-------------------------------+--------+---------------------+
  5. | 1 | AUTO_SEQ_USERS | 5000 | 2014-08-09 18:20:28 |
  6. | 2 | AUTO_SEQ_ITEMS | 5000 | 2014-06-18 16:08:06 |
  7. | 3 | AUTO_SEQ_ORDERS | 6000 | 2014-06-18 16:08:06 |
  8. +------+-------------------------------+--------+---------------------+
  9. 3 rows in set (0.04 sec)

2、比如USERS表有冲突,并且USERS表主键是ID,那么从DRDS获取这个表最大主键值:

  1. mysql> select max(id) from USERS;
  2. +----------+
  3. | MAX(ID) |
  4. +----------+
  5. | 8231 |
  6. +----------+
  7. 1 rows in set (0.04 sec)

3、更新DRDS sequence表中对应的值,我们更新成比8231要大的值,比如9000,更新完成后,后续insert DRDS生成自增主键将不再报错:

  1. mysql> alter sequence AUTO_SEQ_USERS start with 9000;
  2. Query OK, 1 row affected (0.01 sec)

最后更新:2016-11-23 17:31:29

  上一篇:go DRDS数据导入__开发手册_分布式关系型数据库 DRDS-阿里云
  下一篇:go 遍历全表操作__开发手册_分布式关系型数据库 DRDS-阿里云