PostgreSQL不像SQL Server一樣有identity關(guān)鍵字可以用來指定字段自增。但是它有序列值產(chǎn)生器可以使用,并且在數(shù)據(jù)字段定義時(shí)可以指定默認(rèn)值為一個(gè)表達(dá)式,這樣我們就可以使用序列值來作實(shí)現(xiàn)字段值自增。
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比成縣網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式成縣網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋成縣地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。
步驟:
創(chuàng)建一個(gè)序列值
create sequence id_sequence increment?1 start 1;
id_sequence為序列值名稱,increment為步長默認(rèn)為1,start為初始值,默認(rèn)為1
在字段定義時(shí),指定默認(rèn)值為獲取序列值(用nextval函數(shù), 參數(shù)為序列值名稱的字符串)
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" 創(chuàng)建隱含序列 "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 行記錄)
結(jié)論:
1、mysql在字段上加AUTO_INCREMENT屬性來實(shí)現(xiàn)自增,pg使用serial類型,序列號(hào)類型其實(shí)不是真正的類型,當(dāng)聲明一個(gè)字段為序列號(hào)類型時(shí)其實(shí)是創(chuàng)建了一個(gè)序列。
2、mysql插入的是字段的值,pg執(zhí)行插入的時(shí)候變化的是字段值和序列的值,只不過在缺省插入的時(shí)候二者相等。
所以,INSERT時(shí)如果沒有給該字段賦值會(huì)默認(rèn)獲取下一個(gè)值或者對(duì)應(yīng)序列的下一個(gè)值。
但是在該字段有賦值插入之后,就有區(qū)別了,pg賦值插入的時(shí)候是改變了字段的值但是沒有改變序列的值,所以再次缺省賦值插入時(shí)依舊是順序獲取對(duì)應(yīng)序列的下一個(gè)值。
3、mysql和pg在delete之后插入是同樣的,但是truncate操作在pg上是清空了表數(shù)據(jù),但是沒有清空對(duì)應(yīng)的序列,所以在執(zhí)行truncate之后,再次插入會(huì)獲取者對(duì)應(yīng)序列的下一個(gè)值,而在mysql上是從1開始。
4、達(dá)到規(guī)定最大值之后都不能繼續(xù)插入,所以不能循環(huán)使用。
備注:結(jié)論是完全參考[PostgreSQL中文社區(qū)]微信公眾號(hào),本文是記錄驗(yàn)證原文結(jié)論實(shí)驗(yàn)步驟,僅供學(xué)習(xí)
SERIAL類型的字段和MySQL中的自增唯一ID等價(jià)。當(dāng)你在你的數(shù)據(jù)表中定義了一個(gè)SERIAL類型的列后,SERIAL的自增功能會(huì)被自動(dòng)添加到數(shù)據(jù)庫
在oracle中sequence就是所謂的序列號(hào),每次取的時(shí)候它會(huì)自動(dòng)增加,一般用在需要按序列號(hào)排序的地方。 1、Create Sequence 你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE權(quán)限, CREATE SEQUENCE emp_sequence INCREMENT BY 1 -- 每次加幾個(gè) START WITH 1 -- 從1開始計(jì)數(shù) NOMAXVALUE -- 不設(shè)置最大值 NOCYCLE -- 一直累加,不循環(huán) CACHE 10; 一旦定義了emp_sequence,你就可以用CURRVAL,NEXTVAL CURRVAL=返回 sequence的當(dāng)前值 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會(huì)自動(dòng)增加你定義的INCREMENT BY值,然后返回增加后的值。CURRVAL 總是返回當(dāng)前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否則會(huì)出錯(cuò)。一次NEXTVAL會(huì)增加一次SEQUENCE的值,所以如果你在同一個(gè)語句里面使用多個(gè)NEXTVAL,其值就是不一樣的。明白? - 如果指定CACHE值,ORACLE就可以預(yù)先在內(nèi)存里面放置一些sequence,這樣存取的快些。cache里面的取完后,oracle自動(dòng)再取一組到cache。 使用cache或許會(huì)跳號(hào), 比如數(shù)據(jù)庫突然不正常down掉(shutdown abort),cache中的sequence就會(huì)丟失. 所以可以在create sequence的時(shí)候用nocache防止這種情況。 2、Alter Sequence 你或者是該sequence的owner,或者有ALTER ANY SEQUENCE 權(quán)限才能改動(dòng)sequence. 可以alter除start至以外的所有sequence參數(shù).如果想要改變start值,必須 drop sequence 再 re-create . Alter sequence 的例子 ALTER SEQUENCE emp_sequence INCREMENT BY 10 MAXVALUE 10000 CYCLE -- 到10000后從頭開始 NOCACHE ; 影響Sequence的初始化參數(shù): SEQUENCE_CACHE_ENTRIES =設(shè)置能同時(shí)被cache的sequence數(shù)目。 可以很簡單的Drop Sequence DROP SEQUENCE order_seq; 示例Sequence: CREATE SEQUENCE SCOTT.DMIFPOSTID START WITH 261 INCREMENT BY 1 NOMINVALUE NOMAXVALUE NOCYCLE CACHE 20 NOORDER 3、如何使用 第一種方法:一般來說需要新建一個(gè)觸發(fā)器(TRIGGER),使得在插入數(shù)據(jù)之前先運(yùn)行Sequence生成自增號(hào)。示例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'); 第二種方法:可以在插入數(shù)據(jù)時(shí)直接調(diào)用。 insert into table(id,name) values(seq_name.nextval,'名字');