MySQL 里面有auto_increment 自增字段,PostgreSQL 没有自增字段这一说法,但是有单独的对象:序列。 我们可以用序列或者其他土方法来是实现这样的语法。
1. 用序列来实现
先来创建一个步长为2的序列,最大值为10000,每次产生100个值。
t_girl=# create sequence ytt.ytt_s1 start with 1 increment by 2 maxvalue 10000 ;
CREATE SEQUENCE
创建一个测试表。
t_girl=# create unlogged table ytt.tmp_3 (id int not null, log_date date);
CREATE TABLE
改变表tmp_3的列id 默认值是序列ytt_s1的下一个值。
t_girl=# alter table tmp_3 alter id set default nextval('ytt_s1');
ALTER TABLE
t_girl=# \d tmp_3
Unlogged table "ytt.tmp_3"
Column | Type | Modifiers
----------+---------+----------------------------------------------
id | integer | not null default nextval('ytt_s1'::regclass)
log_date | date
OK,我们试着插入几条记录。
t_girl=# insert into tmp_3(log_date) select generate_series('2014-01-01'::timestamp,now(),'1 day');
INSERT 0 14
t_girl=# select * from tmp_3;
id | log_date
----+------------
1 | 2014-01-01
3 | 2014-01-02
5 | 2014-01-03
7 | 2014-01-04
9 | 2014-01-05
11 | 2014-01-06
13 | 2014-01-07
15 | 2014-01-08
17 | 2014-01-09
19 | 2014-01-10
21 | 2014-01-11
23 | 2014-01-12
25 | 2014-01-13
27 | 2014-01-14
(14 rows)
2. 同样是用序列,但是在原表上添加了触发器。
我们先重置原来ID的默认值。
t_girl=# alter table tmp_3 alter id set default 0;
ALTER TABLE
清空测试表:
t_girl=# truncate table tmp_3;
TRUNCATE TABLE
现在的序列已经增长到了27,如下
t_girl=# \d ytt_s1;
Sequence "ytt.ytt_s1"
Column | Type | Value
---------------+---------+--------
sequence_name | name | ytt_s1
last_value | bigint | 27
start_value | bigint | 1
increment_by | bigint | 2
max_value | bigint | 10000
min_value | bigint | 1
cache_value | bigint | 1
log_cnt | bigint | 19
is_cycled | boolean | f
is_called | boolean | t
现在重置下序列。
t_girl=# alter sequence ytt_s1 restart with 1;
ALTER SEQUENCE
t_girl=# \d ytt_s1
Sequence "ytt.ytt_s1"
Column | Type | Value
---------------+---------+--------
sequence_name | name | ytt_s1
last_value | bigint | 1
start_value | bigint | 1
increment_by | bigint | 2
max_value | bigint | 10000
min_value | bigint | 1
cache_value | bigint | 1
log_cnt | bigint | 0
is_cycled | boolean | f
is_called | boolean | f
创建一个触发器函数。
create or replace function sp_increment_tmp_3()
returns trigger as
$ytt$
begin
new.id := nextval('ytt_s1');
return new;
end;
$ytt$ language plpgsql;
创建触发器。
create trigger tr_insert_tmp_3
before insert on ytt.tmp_3
for each row
execute procedure sp_increment_tmp_3();
OK。 再次插入后,看看结果如何。
t_girl=# insert into tmp_3(log_date) select generate_series('2014-01-01'::timestamp,now(),'1 day');
INSERT 0 14
t_girl=# select * from tmp_3;
id | log_date
----+------------
1 | 2014-01-01
3 | 2014-01-02
5 | 2014-01-03
7 | 2014-01-04
9 | 2014-01-05
11 | 2014-01-06
13 | 2014-01-07
15 | 2014-01-08
17 | 2014-01-09
19 | 2014-01-10
21 | 2014-01-11
23 | 2014-01-12
25 | 2014-01-13
27 | 2014-01-14
(14 rows)
3. 其实也是用序列实现,但是有系统提供的类型serial(其实也就是默认的一个序列)。现在呢,删掉之前的触发器和触发器函数。然后创建一张新表。
看看下面,跟第一种是一样的,只不过是系统自己创建了一个序列。
t_girl=# create unlogged table ytt.tmp_3 (id smallserial not null, log_date date);
CREATE TABLE
t_girl=# \d tmp_3;
Unlogged table "ytt.tmp_3"
Column | Type | Modifiers
----------+----------+----------------------------------------------------
id | smallint | not null default nextval('tmp_3_id_seq'::regclass)
log_date | date |
t_girl=# \d tmp_3_id_seq
Sequence "ytt.tmp_3_id_seq"
Column | Type | Value
---------------+---------+---------------------
sequence_name | name | tmp_3_id_seq
last_value | bigint | 1
start_value | bigint | 1
increment_by | bigint | 1
max_value | bigint | 9223372036854775807
min_value | bigint | 1
cache_value | bigint | 1
log_cnt | bigint | 0
is_cycled | boolean | f
is_called | boolean | f
Owned by: ytt.tmp_3.id
|