PostgreSQL不像SQL Server一样有identity关键字可以用来指定字段自增。但是它有序列值产生器可以使用,并且在数据字段定义时可以指定默认值为一个表达式,这样我们就可以使用序列值来作实现字段值自增。
创新互联-专业网站定制、快速模板网站建设、高性价比成县网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式成县网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖成县地区。费用合理售后完善,10多年实体公司更值得信赖。
步骤:
创建一个序列值
create sequence id_sequence increment 1 start 1;
id_sequence为序列值名称,increment为步长默认为1,start为初始值,默认为1
在字段定义时,指定默认值为获取序列值(用nextval函数, 参数为序列值名称的字符串)
create table mytest (id integer not null default nextval('id_sequence'), txt varchar(100));
使用 serial 来处理。
CREATE TABLE test_create_tab2 (
id SERIAL,
val VARCHAR(10)
);
Test=# CREATE TABLE test_create_tab2 (
Test(# id SERIAL,
Test(# val VARCHAR(10)
Test(# );
注意: CREATE TABLE 将为 serial 字段 "test_create_tab2.id" 创建隐含序列 "test_create_tab2_id_seq"
CREATE TABLE
Test=# \d test_create_tab2;
资料表 "public.test_create_tab2"
栏位 | 型别 | 修饰词
------+-----------------------+-------------------------------------------------
-------
id | integer | 非空 缺省 nextval('test_create_tab2_id_seq'::regclass)
val | character varying(10) |
Test=# INSERT INTO test_create_tab2(val) VALUES ('NO id');
INSERT 0 1
Test=# INSERT INTO test_create_tab2(val) VALUES ('NO id 2');
INSERT 0 1
Test=# select * from test_create_tab2;
id | val
----+---------
1 | NO id
2 | NO id 2
(2 行记录)
Test=# select lastval();
lastval
---------
2
(1 行记录)
结论:
1、mysql在字段上加AUTO_INCREMENT属性来实现自增,pg使用serial类型,序列号类型其实不是真正的类型,当声明一个字段为序列号类型时其实是创建了一个序列。
2、mysql插入的是字段的值,pg执行插入的时候变化的是字段值和序列的值,只不过在缺省插入的时候二者相等。
所以,INSERT时如果没有给该字段赋值会默认获取下一个值或者对应序列的下一个值。
但是在该字段有赋值插入之后,就有区别了,pg赋值插入的时候是改变了字段的值但是没有改变序列的值,所以再次缺省赋值插入时依旧是顺序获取对应序列的下一个值。
3、mysql和pg在delete之后插入是同样的,但是truncate操作在pg上是清空了表数据,但是没有清空对应的序列,所以在执行truncate之后,再次插入会获取者对应序列的下一个值,而在mysql上是从1开始。
4、达到规定最大值之后都不能继续插入,所以不能循环使用。
备注:结论是完全参考[PostgreSQL中文社区]微信公众号,本文是记录验证原文结论实验步骤,仅供学习
SERIAL类型的字段和MySQL中的自增唯一ID等价。当你在你的数据表中定义了一个SERIAL类型的列后,SERIAL的自增功能会被自动添加到数据库
在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方。 1、Create Sequence 你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE权限, CREATE SEQUENCE emp_sequence INCREMENT BY 1 -- 每次加几个 START WITH 1 -- 从1开始计数 NOMAXVALUE -- 不设置最大值 NOCYCLE -- 一直累加,不循环 CACHE 10; 一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL CURRVAL=返回 sequence的当前值 NEXTVAL=增加sequence的值,然后返回 sequence 值 比如: emp_sequence.CURRVAL emp_sequence.NEXTVAL 可以使用sequence的地方: - 不包含子查询、snapshot、VIEW的 SELECT 语句 - INSERT语句的子查询中 - NSERT语句的VALUES中 - UPDATE 的 SET中 可以看如下例子: INSERT INTO emp VALUES (empseq.nextval, 'LEWIS', 'CLERK',7902, SYSDATE, 1200, NULL, 20); SELECT empseq.currval FROM DUAL; 但是要注意的是: - 第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白? - 如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,oracle自动再取一组到cache。 使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失. 所以可以在create sequence的时候用nocache防止这种情况。 2、Alter Sequence 你或者是该sequence的owner,或者有ALTER ANY SEQUENCE 权限才能改动sequence. 可以alter除start至以外的所有sequence参数.如果想要改变start值,必须 drop sequence 再 re-create . Alter sequence 的例子 ALTER SEQUENCE emp_sequence INCREMENT BY 10 MAXVALUE 10000 CYCLE -- 到10000后从头开始 NOCACHE ; 影响Sequence的初始化参数: SEQUENCE_CACHE_ENTRIES =设置能同时被cache的sequence数目。 可以很简单的Drop Sequence DROP SEQUENCE order_seq; 示例Sequence: CREATE SEQUENCE SCOTT.DMIFPOSTID START WITH 261 INCREMENT BY 1 NOMINVALUE NOMAXVALUE NOCYCLE CACHE 20 NOORDER 3、如何使用 第一种方法:一般来说需要新建一个触发器(TRIGGER),使得在插入数据之前先运行Sequence生成自增号。示例Trigger -- Create table create table TEST ( SEQ INTEGER not null, NAME VARCHAR2(20), PWD VARCHAR2(20) ) tablespace USERS pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); -- Create/Recreate primary, unique and foreign key constraints alter table TEST add constraint PK_TEST primary key (SEQ) using index tablespace USERS pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); create or replace trigger TI_TEST before insert on test for each row declare -- local variables here begin SELECT SEQ_TEST.NEXTVAL INTO :NEW.SEQ FROM DUAL; end TI_TEST; 插入语句 insert into test values('aa','aa'); 第二种方法:可以在插入数据时直接调用。 insert into table(id,name) values(seq_name.nextval,'名字');