数据库中的自增序列
数据库中的自增序列
业务开发中,经常会使用自增 ID 作为数据库表中的主键。 有些时候就是单纯的为了表数据有一个主键ID, 有时候则是业务上有要求需要自增且唯一数字的场景。
大多数情况下就可以使用数据库提供的一些特性来生成。
1. MySQL 中用法
MySQL 中没有序列这种说法,更没有没有专门的序列对象。 通常都是建表的时候使用 AUTO_INCREMENT 实现自增:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
);
简单使用,不需要额外的配置。但是有个问题是跟数据库表绑定了,不能多表共用,更不支持更复杂的序列操作。
当然也可以使用单独一张表去模拟序列。
CREATE TABLE sequences (
name VARCHAR(50) PRIMARY KEY,
current_value INT NOT NULL
);
2. Oracle 中用法
Oracle 的序列功能比较强,也是比较早提供序列特性的数据库。
先创建序列:
CREATE SEQUENCE my_sequence
INCREMENT BY 1 -- 每次增加多少,可以是正数或负数
START WITH 1 -- 起始值,一般都是1
MINVALUE 1 -- 最小值
MAXVALUE 999999999 -- 最大值
CACHE 20 -- 缓存大小,就是提前生成多少个序列
NOCYCLE -- 是否循环
ORDER; -- 保证按请求顺序生成
常规的用法:
-- 获取下一个序列值
SELECT my_sequence.NEXTVAL FROM dual;
-- 获取当前序列值
SELECT my_sequence.CURRVAL FROM dual;
-- 在 INSERT 语句中使用
INSERT INTO test_table (id, name)
VALUES (my_sequence.NEXTVAL, 'John');
-- 建表时作为默认值中使用
CREATE TABLE test_table (
id NUMBER DEFAULT my_sequence.NEXTVAL,
name VARCHAR2(100)
);
可以看出来,Oracle 中序列单独剥离出来,不再跟数据库表绑定。使用起来比较灵活,就是更复杂了。
3. PostgreSQL 中的序列
PostgreSQL 的序列设计很大程度上参考了 Oracle,毕竟 Oracle 是最成熟的商业数据库之一。 基本上可以说相似度极高。
序列定义:
CREATE SEQUENCE my_sequence
INCREMENT BY 1 -- 每次增加多少,可以是正数或负数
MINVALUE 1 -- 最小值
MAXVALUE 999999 -- 最大值
START WITH 1 -- 起始值
CACHE 1 -- 缓存数量
NO CYCLE; -- 是否循环
基本用法:
-- 获取下一个值
SELECT nextval('my_sequence');
-- 获取当前值
SELECT currval('my_sequence');
-- 获取最后生成的值
SELECT lastval();
建表时指定序列:
-- 创建表时指定序列
CREATE TABLE test_table (
id INTEGER PRIMARY KEY DEFAULT nextval('test_table_id_seq'),
name VARCHAR(50)
);
-- 使用 SERIAL 类型会自动创建序列
CREATE TABLE test_table (
id SERIAL PRIMARY KEY, -- 等同于 INTEGER + sequence
name VARCHAR(50)
);
不过这里需要注意的是:
- PostgreSQL 的序列是不支持事务回滚,就算回滚了事务,序列的值也是不会还原回去的。
- 如果业务上不能接受这个情况,就不能依赖于这个自增的序列了。