【问题标题】:In Postgresql, force unique on combination of two columns在 Postgresql 中,对两列的组合强制唯一
【发布时间】:2012-12-22 16:57:40
【问题描述】:

我想在 PostgreSQL 中设置一个表,这样两列一起必须是唯一的。任何一个值都可以有多个值,只要没有两个共享两者。

例如:

CREATE TABLE someTable (
    id int PRIMARY KEY AUTOINCREMENT,
    col1 int NOT NULL,
    col2 int NOT NULL
)

所以,col1col2 可以重复,但不能同时重复。所以,这将是允许的(不包括 id)

1 1
1 2
2 1
2 2

但不是这个:

1 1
1 2
1 1 -- would reject this insert for violating constraints

【问题讨论】:

  • 由于这是 google 中排名靠前的搜索结果,最好也提供 alter existing table

标签: sql postgresql unique


【解决方案1】:
CREATE TABLE someTable (
    id serial PRIMARY KEY,
    col1 int NOT NULL,
    col2 int NOT NULL,
    UNIQUE (col1, col2)
)

autoincrement 不是 postgresql。你想要一个integer primary key generated always as identity(或者serial,如果你使用PG 9或更低版本。serial was soft-deprecated in PG 10)。

如果 col1col2 是唯一的并且不能为空,那么它们就是一个好的主键:

CREATE TABLE someTable (
    col1 int NOT NULL,
    col2 int NOT NULL,
    PRIMARY KEY (col1, col2)
)

【讨论】:

  • 我喜欢这里的主键而不是唯一键的建议,因为在这种情况下我们不允许 NULL 值。来自 PostgeSQL 文档:“请注意,唯一约束本身并不提供唯一标识符,因为它不排除空值。)”postgresql.org/docs/8.1/static/ddl-constraints.html#AEN2038
  • 如何在架构定义中实现这一点?
  • 在某些情况下,您可能希望将代理键用作主键,而不是列的组合。特别是在对大数据卷进行连接时提高性能。我个人选择了下面的 UNIQUE CONSTRAINT 解决方案。
  • 是否可以仅对一个排列强制执行唯一约束,例如 unique(col1, col2 = '1')?
【解决方案2】:

创建两个数字不能一起重复的唯一约束:

ALTER TABLE someTable
ADD UNIQUE (col1, col2)

【讨论】:

    【解决方案3】:

    看起来像常规的 UNIQUE CONSTRAINT :)

    CREATE TABLE example (
    a integer,
    b integer,
    c integer,
    UNIQUE (a, c));
    

    更多here

    【讨论】:

    • 这是否会独立添加a 的索引和c 的索引?因为有时候需要根据a快速查找,有时候根据c快速查找。
    • @CMCDragonkai a,c 上的这个索引在内部为两种类型的查询服务。将 'a' 作为 where 子句的查询以及 where 子句中存在列 a 和 c 的查询将从上述索引中受益。在这两种方式中,“a”列都应该存在,因为它是查找列。
    【解决方案4】:

    如果你像我一样来到这里:

    • 预先存在的表,
    • 您需要向其中添加新列,并且
    • 还需要在 new 列以及 old 列上添加新的唯一约束,AND
    • 能够全部撤消(即写下迁移)

    这对我有用,利用上述答案之一并将其扩展:

    -- up
    
    ALTER TABLE myoldtable ADD COLUMN newcolumn TEXT;
    ALTER TABLE myoldtable ADD CONSTRAINT myoldtable_oldcolumn_newcolumn_key UNIQUE (oldcolumn, newcolumn);
    
    ---
    
    ALTER TABLE myoldtable DROP CONSTRAINT myoldtable_oldcolumn_newcolumn_key;
    ALTER TABLE myoldtable DROP COLUMN newcolumn;
    
    -- down
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      • 1970-01-01
      相关资源
      最近更新 更多