创建递增主键
约 987 字大约 3 分钟
2024-11-17
PostgreSQL数据库有多种方法可实现自增字段的设置,常用的有:
- SERIAL,最简单
- IDENTITY,是PostgreSQL 10的新增特性
- 创建SEQUENCE,更灵活
1. SERIAL
SMALLSERIAL、SERIAL 和 BIGSERIAL 范围:
伪类型 | 存储大小 | 范围 |
---|---|---|
SMALLSERIAL | 2字节 | 1 到 32,767 |
SERIAL | 4字节 | 1 到 2,147,483,647 |
BIGSERIAL | 8字节 | 1 到 922,337,2036,854,775,807 |
create table dictionary (
id SERIAL not null,
parent_id INT4 not null,
type VARCHAR(50) not null,
item_name VARCHAR(100) not null,
item_value VARCHAR(100) null,
comment VARCHAR(200) null,
deleted INT2 not null default 0,
create_time DATE not null default CURRENT_TIMESTAMP,
constraint PK_dictionary primary key (id)
);
2. IDENTITY (推荐)
(PostgreSQL 10 及以上版本)
CREATE TABLE t_user (
user_id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY ,
user_name varchar(50) NOT NULL UNIQUE
)
INSERT INTO t_user (user_name) value ('tony')
3. SEQUENCE (不推荐)
-- 创建序列
CREATE SEQUENCE users_id_seq //设置序列名
START WITH 1 //初始值
INCREMENT BY 1 //增长值
NO MINVALUE //最小值
NO MAXVALUE //最大值
CACHE 1; //缓存
INCREMENT BY : 每次序列增加(或减少)的步长
MINVALUE : 序列最小值,NO MINVALUE表示没有最小值
MAXVALUE : 序列最大值,NO MAXVALUE表示没有最大值
START WITH :以什么序列值开始
CYCLE : 序列是否循环使用
OWNED BY : 可以直接指定一个表的字段,也可以不指定。
alter table users alter column id set default nextval('users_id_seq');
create table dictionary (
id int4 NOT NULL DEFAULT nextval('users_id_seq'),
parent_id INT4 not null,
type VARCHAR(50) not null,
item_name VARCHAR(100) not null,
item_value VARCHAR(100) null,
comment VARCHAR(200) null,
deleted INT2 not null default 0,
create_time DATE not null default CURRENT_TIMESTAMP,
constraint PK_dictionary primary key (id)
);
有时,在使用第二种方式时,可能会见到这种语句:
ALTER TABLE ONLY table_name ALTER COLUMN id SET DEFAULT nextval('table_name_id_seq'::regclass);
这里,regclass可以省略。
使用如下sql可以获取序列当前值:
select currval('test_id_seq')
函数 | 返回类型 | 描述 | |
---|---|---|---|
nextval(regclass) | bigint | 递增序列对象到它的下一个数值并且返回该值。这个动作是自动完成的。即使多个会话并发运行nextval,每个进程也会安全地收到一个唯一的序列值。 | 获取指定序列最近一次使用netxval后的数值,如果没有使用nextval而直接使用currval会出错 |
currval(regclass) | bigint | 在当前会话中返回最近一次nextval抓到的该序列的数值。(如果在本会话中从未在该序列上调用过 nextval,那么会报告一个错误。)请注意因为此函数返回一个会话范围的数值,而且也能给出一个可预计的结果,因此可以用于判断其它会话是否执行过nextval。 | 返回最近一次用 nextval 获取的任意序列的数值 |
lastval() | bigint | 返回当前会话里最近一次nextval返回的数值。这个函数等效于currval,只是它不用序列名为参数,它抓取当前会话里面最近一次nextval使用的序列。如果当前会话还没有调用过nextval,那么调用lastval将会报错。 | 递增序列并返回新值 |
setval(regclass, bigint) | bigint | 重置序列对象的计数器数值。设置序列的last_value字段为指定数值并且将其is_called字段设置为true,表示下一次nextval将在返回数值之前递增该序列。 | 设置序列的当前数值 |
setval(regclass, bigint, boolean) | bigint | 重置序列对象的计数器数值。功能等同于上面的setval函数,只是is_called可以设置为true或false。如果将其设置为false,那么下一次nextval将返回该数值,随后的nextval才开始递增该序列。 | 设置序列的当前数值以及 is_called 标志,如果为true则立即生效,如果为false,则调用一次nextval后才会生效 |