【问题标题】:How to update unique values in SQL using a PostgreSQL sequence?如何使用 PostgreSQL 序列更新 SQL 中的唯一值?
【发布时间】:2010-09-13 23:07:13
【问题描述】:

在 SQL 中,如何更新表,为每一行设置不同的列值?

我想更新 PostgreSQL 数据库中的一些行,将一列设置为序列中的数字,其中该列具有唯一约束。我希望我可以使用:

update person set unique_number = (select nextval('number_sequence') );

但似乎 nextval 只被调用一次,因此更新对每一行使用相同的数字,并且我收到“重复键违反唯一约束”错误。我应该怎么做?

【问题讨论】:

    标签: sql postgresql sequences


    【解决方案1】:

    我认为 pg 的序列是一种 hack,并且表明增量整数不是键行的最佳方式。虽然 pgsql 直到 8.3 才获得对 UUID 的原生支持

    http://www.postgresql.org/docs/8.3/interactive/datatype-uuid.html

    UUID 的好处是组合几乎是无限的,不像随机数会在某一天发生碰撞。

    【讨论】:

    • “几乎无限?”文档说它是 128 位整数类型。这是很多,但它不是无限的,几乎肯定会在使用所有 2^128 值之前发生冲突。此外,ORM 可能必须转换为字符串类型或从字符串类型转换才能使用它。在我看来,这不是一个明显的胜利。
    • 我想你低估了 2^128 的大小,去维基百科上阅读关于 uuid 的信息。
    • 它主要是学术性的,但 Postgres 序列可能比 UUID 更防冲突,具体取决于它的创建方式。 Python 的uuid 模块使用随机组件,但大大少于 128 个随机位。序列只有在循环时才会发生碰撞,随机数会发生碰撞......随机。
    • Postgres 有自己的 uuid 生成器——我没见过——但它可能比 Python 的更好,fwiw。
    【解决方案2】:

    不要使用子选择,而是直接使用 nextval 函数,像这样:

    update person set unique_number = nextval('number_sequence');
    

    【讨论】:

    • 谢谢 - 这行得通。我被子选择抓住了,因为我试图对两列使用相同的序列号,但我真的不需要这样做。
    • 调用nextval('sequence')后,如果想重复使用相同的序列值,可以使用相关函数currval('sequence'),返回当前序列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    相关资源
    最近更新 更多