如果我们插入一笔记录,我们希望系统自动为我们分配一个ID,那么我们需要使用serial type。如果我们创建表的时候,自动创建一个serial类型(包smallserial and bigserial),系统会自动帮我们创建sequence这种数据库对象。
- create table employ(
- id serial,
- name varchar(64),
- department varchar(64)
- ) ;
- manu_db=# create table employ(id serial,name varchar(64),department varchar(128)) ;
NOTICE: CREATE TABLE will create implicit sequence "employ_id_seq" for serial column "employ.id"
CREATE TABLE
manu_db=# \d
List of relations
Schema | Name | Type | Owner
--------+---------------+----------+-------
public | employ | table | manu
public | employ_id_seq | sequence | manu
(2 rows) - manu_db-# \d employ
Table "public.employ"
Column | Type | Modifiers
------------+------------------------+-----------------------------------------------------
id | integer | not null default nextval('employ_id_seq'::regclass)
name | character varying(64) |
department | character varying(128) |
下面这两条SQL,本质是相等:
- CREATE TABLE employ (
- id serial,
- name varchar(64),
- department varchar(64)
- ) ;
- -----------------------------------------------------------------
- CREATE SEQUENCE employ_id_seq ;
- CREATE TABLE employ (
- id integer NOT NULL DEFAULT nextval('employ_id_seq'),
- name varchar(64),
- department varchar(64)
- );
- ALTER SEQUENCE employ_id_seq OWNED by employ.id;
我们建立数据表和sequence的对应关系,常规的就是这两种方法,要么创建表的时候,某字段是serial类型,要么创建先创建sequence,然后创建表的时候,将某字段和sequence 联系起来(DEFAULT nextvl(‘XXXX_seq’)),有没有第三种方法?假如创建表的时候,没有用DEFAULT nextval建立起来联系,还有没有机会在后面建立这种联系?我为什么纠结这个?
- manu_db=# create table employ_copy (like employ) ;
CREATE TABLE
manu_db=# \d employ_copy
Table "public.employ_copy"
Column | Type | Modifiers
------------+------------------------+-----------
id | integer | not null
name | character varying(64) |
department | character varying(128) |
manu_db=# \d employ
Table "public.employ"
Column | Type | Modifiers
------------+------------------------+-----------------------------------------------------
id | integer | not null default nextval('employ_id_seq'::regclass)
name | character varying(64) |
department | character varying(128) |
manu_db=#
答案是肯定的:
- CREATE SEQUENCE employ_copy_id_seq ;
- ALTER TABLE employ_copy ALTER COLUMN id SET DEFAULT nextval('employ_copy_id_seq');
- ALTER SEQUENCE employ_copy_id_seq OWNED by employ_copy.id ;
- manu_db=# CREATE SEQUENCE employ_copy_id_seq ;
CREATE SEQUENCE
manu_db=# ALTER TABLE employ_copy ALTER COLUMN id SET DEFAULT nextval('employ_copy_id_seq');
ALTER TABLE
manu_db=# \d employ_copy
Table "public.employ_copy"
Column | Type | Modifiers
------------+------------------------+----------------------------------------------------------
id | integer | not null default nextval('employ_copy_id_seq'::regclass)
name | character varying(64) |
department | character varying(128) |
当我们向Postgres插入一笔记录的时候,我们不需要费力告诉DB id的值,因为DB会自动分配一个数值给id:
- manu_db=# insert into employ (name,department) values('bean', 'DDI');
INSERT 0 1
manu_db=# insert into employ (name,department) values('albert', 'DDI');
INSERT 0 1
manu_db=# select * from employ ;
id | name | department
----+--------+------------
1 | bean | DDI
2 | albert | DDI
(2 rows)
- manu_db=# select currval('employ_id_seq');
- currval
- ---------
- 2
- (1 row)
- manu_db=# select nextval('employ_id_seq');
- nextval
- ---------
- 3
- (1 row)
- manu_db=# select nextval('employ_id_seq');
- nextval
- ---------
- 4
- (1 row)
- manu_db=# select setval('employ_id_seq',100);
- setval
- --------
- 100
- (1 row)
- manu_db=# select currval('employ_id_seq');
- currval
- ---------
- 100
- (1 row)
- manu_db=# select nextval('employ_id_seq');
- nextval
- ---------
- 101
- (1 row)
参考文献
1 A Tour of PostgreSQL Data Types
2 Postgres manual 9.1