在 Postgresql 中,对两列的组合强制唯一

Posted

技术标签:

【中文标题】在 Postgresql 中,对两列的组合强制唯一【英文标题】:In Postgresql, force unique on combination of two columns 【发布时间】:2013-01-08 18:36:14 【问题描述】:

我想在 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 【参考方案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')? postgres:***.com/questions/16236365/…sql server:***.com/a/5149263/5986661【参考方案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

【讨论】:

以上是关于在 Postgresql 中,对两列的组合强制唯一的主要内容,如果未能解决你的问题,请参考以下文章

PostGreSql 使用拥有 Max 子句获取两列的唯一组合

CreateCriteria 对两列组合进行排序

在excel中查找两列的组合,一列中有一个条件

Rails:验证两列的唯一性(一起)

选择对两列求和并希望将结果用作选择条件的查询 [重复]

在 SQLite 中组合两列的巧妙方法?