PostgreSQL10版本中的自增列

本文通过实例演示了如何在PostgreSQL中使用身份列创建表,并进行数据插入操作,包括使用OVERRIDING SYSTEM VALUE覆盖系统生成的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[root@pgserver ~]# su - postgres
Last login: Sun Apr 22 23:46:50 EDT 2018 on pts/2
[postgres@pgserver ~]$ psql
psql (10beta2)
Type "help" for help.

postgres=# create table testa (id int GENERATED ALWAYS AS IDENTITY (cache 100), info text); 
CREATE TABLE
postgres=# \d
              List of relations
 Schema |     Name      |   Type   |  Owner   
--------+---------------+----------+----------
 public | "tab01"       | table    | postgres
 public | lei_two       | table    | postgres
 public | lei_two_2     | table    | postgres
 public | lei_two_22    | table    | postgres
 public | newtable      | table    | postgres
 public | newtbl        | table    | postgres
 public | sampletbl     | table    | postgres
 public | t1            | table    | postgres
 public | tab_datatype1 | table    | postgres
 public | tab_lei       | table    | postgres
 public | tab_lei_1     | table    | postgres
 public | test_t5       | table    | postgres
 public | test_t6       | table    | postgres
 public | testa         | table    | postgres
 public | testa_id_seq  | sequence | postgres
(15 rows)

postgres=# \d testa
                          Table "public.testa"
 Column |  Type   | Collation | Nullable |           Default            
--------+---------+-----------+----------+------------------------------
 id     | integer |           | not null | generated always as identity
 info   | text    |           |          | 

postgres=# insert into testa values('abc');
ERROR:  invalid input syntax for integer: "abc"
LINE 1: insert into testa values('abc');
                                 ^
postgres=# insert into testa(info)  values('abc');
INSERT 0 1
postgres=# 
postgres=# select * from testa;
 id | info 
----+------
  1 | abc
(1 row)

postgres=# insert into testa(info)  values('abcd');
INSERT 0 1
postgres=# select * from testa;
 id | info 
----+------
  1 | abc
  2 | abcd
(2 rows)

postgres=# insert into testa (id, info) OVERRIDING SYSTEM VALUE values (11,'test');  
INSERT 0 1
postgres=# select * from testa;
 id | info 
----+------
  1 | abc
  2 | abcd
 11 | test
(3 rows)

postgres=# insert into testa(info)  values('asdfghjkl');
INSERT 0 1
postgres=# select * from testa;
 id |   info    
----+-----------
  1 | abc
  2 | abcd
 11 | test
  3 | asdfghjkl
(4 rows)

postgres=# insert into testa(info)  values('asdf4');
INSERT 0 1
postgres=# select * from testa;
 id |   info    
----+-----------
  1 | abc
  2 | abcd
 11 | test
  3 | asdfghjkl
  4 | asdf4
(5 rows)

postgres=# insert into testa(info)  values('asdf5');
INSERT 0 1
postgres=# insert into testa(info)  values('asdf6');
INSERT 0 1
postgres=# insert into testa(info)  values('asdf7');
INSERT 0 1
postgres=# insert into testa(info)  values('asdf8');
INSERT 0 1
postgres=# insert into testa(info)  values('asdf9');
INSERT 0 1
postgres=# select * from testa;
 id |   info    
----+-----------
  1 | abc
  2 | abcd
 11 | test
  3 | asdfghjkl
  4 | asdf4
  5 | asdf5
  6 | asdf6
  7 | asdf7
  8 | asdf8
  9 | asdf9
(10 rows)

postgres=# insert into testa(info)  values('asdf10');
INSERT 0 1
postgres=# select * from testa;
 id |   info    
----+-----------
  1 | abc
  2 | abcd
 11 | test
  3 | asdfghjkl
  4 | asdf4
  5 | asdf5
  6 | asdf6
  7 | asdf7
  8 | asdf8
  9 | asdf9
 10 | asdf10
(11 rows)

postgres=# insert into testa(info)  values('asdf11');
INSERT 0 1
postgres=# select * from testa;
 id |   info    
----+-----------
  1 | abc
  2 | abcd
 11 | test
  3 | asdfghjkl
  4 | asdf4
  5 | asdf5
  6 | asdf6
  7 | asdf7
  8 | asdf8
  9 | asdf9
 10 | asdf10
 11 | asdf11
(12 rows)

postgres=# 

从上面可以看到, OVERRIDING SYSTEM VALUE关键字可以插入values子句后面手工指定的值,该手工值可以比identity所在列的所有值都大。

postgres=# insert into testa (id, info) OVERRIDING SYSTEM VALUE values (9,'asdf9');  --->>注意此处的9,本语句执行之前id的最大值是11
INSERT 0 1
postgres=# select * from testa;
 id |   info    
----+-----------
  1 | abc
  2 | abcd
 11 | test
  3 | asdfghjkl
  4 | asdf4
  5 | asdf5
  6 | asdf6
  7 | asdf7
  8 | asdf8
  9 | asdf9
 10 | asdf10
 11 | asdf11
  9 | asdf9
(13 rows)

postgres=# 
从上面可以看到, OVERRIDING SYSTEM VALUE关键字可以插入values子句后面手工指定的值,该手工值可以比identity所在列的最大值还小。


identity列是PG10中的新特性,请见:https://www.postgresql.org/docs/10/static/sql-createtable.html

其实identity列也是使用sequence来实现的

postgres=# \ds+
                           List of relations
 Schema |     Name     |   Type   |  Owner   |    Size    | Description 
--------+--------------+----------+----------+------------+-------------
 public | testa_id_seq | sequence | postgres | 8192 bytes | 
(1 row)


postgres=# 


### PostgreSQL 序列不自增问题排查与解决方案 当遇到PostgreSQL序列未自动增加的情况时,通常涉及几个常见原因和相应的解决方法。 #### 1. 检查表定义中的默认值设置 如果表创建语句中没有正确配置`serial`或手动指定的`DEFAULT nextval('sequence_name')`,则不会触发序列增长。应确认字段确实设置了正确的默认值[^1]: ```sql CREATE TABLE example ( id SERIAL PRIMARY KEY, name TEXT NOT NULL ); ``` 上述例子展示了如何通过声明`SERIAL`来让系统自动管理ID列的增长。 #### 2. 验证插入操作是否覆盖了默认值 有时应用程序层可能会显式提供主键值,在这种情况下即使存在默认值也不会生效。确保应用逻辑允许数据库引擎处理该字段并使用其预设规则。 #### 3. 查看现有数据及其对应的序列状态 可以查询当前最大值以及序列的状态来进行对比分析: ```sql SELECT currval(pg_get_serial_sequence('example', 'id')); -- 或者查看下一个预期值 SELECT setval(pg_get_serial_sequence('example', 'id'), (SELECT MAX(id) FROM example)); ``` 这些命令有助于理解实际使用的数值范围,并可用来重置序列到合适位置。 #### 4. 排除并发事务的影响 在高并发环境下可能出现竞争条件导致某些记录未能按顺序排列。虽然这不是严格意义上的“不自增”,但也可能导致看似异常的现象。考虑优化锁机制或者调整业务流程减少冲突概率[^2]。 对于批量插入场景特别需要注意这一点,因为这可能涉及到多个会话同时尝试获取新的序号资源。 #### 5. 审核日志文件寻找线索 最后不要忘记查阅服务器的日志输出,特别是错误消息部分。这里往往能发现更多关于为何某次特定请求失败的具体提示信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值