我有一个带有序列号的postgres表。

id (serial) name age

插入通常发生在Web应用程序中。

我手动插入了两个新记录,将id设置为max(id)+1 ****

在这2次插入之后,当Web应用程序插入2条记录时,会给出重复的键错误。

仅用于2条记录。之后,一切正常。

问题是-为什么我的手动插入没有增加序列号?

自动递增和串行是否不同?

我在这里想念什么? MySQL或任何其他SQL是否存在相同的问题?

最佳答案

创建 serial or bigserial 列时,PostgreSQL实际上会执行三件事:

  • 创建intbigint列。
  • 创建一个序列(由列拥有)以生成该列的值。
  • 将列的默认值设置为序列的nextval()

  • 当您在不指定serial列的情况下插入值时(或者如果您明确指定DEFAULT作为其值),则将在序列上调用nextval,以:
  • 返回该列的下一个可用值。
  • 递增序列的值。

  • 如果您为serial列手动提供非默认值,则序列将不会更新,并且nextval可以返回serial列已使用的值。因此,如果您执行这种操作,则必须通过调用 nextval or setval 手动修复序列。

    另外请记住,可以删除记录,因此可以预料到serial列之间的间隔,因此即使没有并发问题,使用max(id) + 1也不是一个好主意。

    如果您使用的是serialbigserial,最好的办法是让PostgreSQL为您分配值,并假装它们是不透明的数字,它们恰好以一定顺序出现:不要自己分配它们,而是除了唯一性之外,不要假设其他任何东西。此经验法则适用于所有数据库IMO。

    我不确定MySQL的auto_increment如何与所有不同的数据库类型一起使用,但是the fine manual可能会有所帮助。

    08-18 07:20
    查看更多