PostgreSQL解决序列(自增id)自动增长冲突

背景

一般表的id主键我们都是设置为自增序列。

但是如果我们在插入一些数据的时候手动指定id,那么自增序列不会跟随我们手动设置的id增长。

就会出现下次不设置id的时候自增到我们手动指定的id导致主键冲突bug

举个例子

现在数据有

id
1
2
3

现在我们手动插入数据比如

insert into xiaozou(id) values(4)

这时候我们的数据变成

id
1
2
3
4

实际我们的id自增序列还停留在3。

如果我们插入数据不指定id。自动生成的id就还是4,从而导致主键冲突

解决方案

设置自增序列为当前id的最大值+1

SELECT setval('xiaozou_id_seq', (SELECT MAX(id) FROM xiaozou)+1);

xiaozou_id_seq是序列名,xiaozou是表名

如果不知道序列名可以通过如下方式查询

SELECT column_name, column_default
FROM information_schema.columns
WHERE table_name = 'xiaozou' AND column_default LIKE 'nextval%';
### PostgreSQL 设置主键自动序列教程 在 PostgreSQL 中,可以通过多种方式实现主键的自功能。以下是几种常见的方法及其具体操作: #### 方法一:使用 `SERIAL` 类型 PostgreSQL 提供了一种便捷的方式——通过定义列的数据类型为 `SERIAL` 或其变体(如 `BIGSERIAL`),可以直接让该列成为自主键。这种方式下,数据库会在后台自动创建一个序列并与该列关联。 ```sql CREATE TABLE example_table ( id SERIAL PRIMARY KEY, name VARCHAR(100) ); ``` 此语句中的 `id` 列会被设置为主键,并且每次插入新记录时都会自动值[^4]。 --- #### 方法二:手动创建序列并绑定到字段 如果需要更灵活地控制序列的行为,可以选择手动创建序列并将它作为字段的默认值。 ##### 步骤 1:创建序列 首先,创建一个新的序列对象: ```sql CREATE SEQUENCE example_table_id_seq START WITH 1 INCREMENT BY 1; ``` 上述命令创建了一个名为 `example_table_id_seq` 的序列,初始值为 1 并按步长 1 加[^1]。 ##### 步骤 2:创建表结构 接着,在表定义中指定该序列为某一字段的默认值: ```sql CREATE TABLE example_table ( id INTEGER PRIMARY KEY DEFAULT nextval('example_table_id_seq'), name VARCHAR(100) ); ``` 这里设置了 `id` 字段,默认值由调用函数 `nextval()` 获取下一个序列值[^2]。 ##### 步骤 3:将序列与字段绑定 对于已经存在的表,也可以通过修改表结构来完成同样的效果: ```sql ALTER TABLE example_table ALTER COLUMN id SET DEFAULT nextval('example_table_id_seq'); ``` 这一步确保了即使后续新数据未显式提供 `id` 值,也会从序列获取下一可用编号[^5]。 --- #### 方法三:重置已有的主键序列 当向已有表格插入大量数据或者迁移外部数据后,可能需要重新同步序列的最大值以匹配实际存储的内容。执行如下 SQL 可达到目的: 假设目标表名叫做 `existing_table` 而对应的序列名称叫作 `existing_table_id_seq` ,那么可以用下面这条指令调整当前最大 ID 数字至最新状态: ```sql SELECT setval('existing_table_id_seq', (SELECT MAX(id) FROM existing_table)); ``` 这样做的目的是防止未来再次写入时发生重复键冲突错误[^3]。 --- ### 总结 以上介绍了三种不同的技术手段用来配置 PostgreSQL 数据库里的主键属性使其具备自动增长特性。每一种都有各自适用场景,开发者可以根据项目需求选取最合适的方案实施部署。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值