【问题标题】:How to add a constraint on multiple columns to prevent duplicate rows?如何在多列上添加约束以防止重复行?
【发布时间】:2021-06-16 06:27:05
【问题描述】:

我在 Postgres 数据库中有一个累积重复值的现有表。我们已经清除了表格并重新填充了值,但希望防止再次发生重复。因此我们需要添加一个约束。

表名:camembert,样本数据:

| handle | id  | num   |
| ------ | --- | ----- |
| 259    | 869 | AC003 |
| 259    | 869 | AC003 |
| 259    | 869 | AC003 |
| 259    | 856 | AC005 | 
| 259    | 856 | AC005 |
| 259    | 856 | AC005 |
etc.

下面是这个问题的一个例子(我们实际上是一式三份)

约束应该允许前两列具有重复值,但是,第三列是使行唯一的微分器。例如,当表格被正确填充时,它看起来如下:

| handle | id    | num   |
| ------ | ----- | ----- |
| 259    | 869   | AC003 |
| 259    | 856   | AC005 |
| 259    | 856   | AC007 |
| 47138  | 41085 | AC003 |
| 47138  | 41085 | AC005 |
| 47138  | 43513 | AC007 |

我尝试了以下脚本:

ALTER TABLE camembert ADD CONSTRAINT num_uniq UNIQUE (num);

但出现错误:

ERROR: could not create unique index "num"
Detail: Key (num)=(AC003) is duplicated.

我对唯一约束有什么误解?解开这个谜题的关键语句是什么?

【问题讨论】:

  • @a_horse_with_no_name,不唯一性超过三列(句柄,id,num),因此可以有重复的 num 值。解决方案是 JGH 的答案。

标签: sql postgresql database-design unique-constraint


【解决方案1】:

您必须将 3 列上的约束一起添加

ALTER TABLE camembert ADD CONSTRAINT num_vals UNIQUE (handle, id, num);

但在这样做之前,您必须删除重复的。

【讨论】:

    【解决方案2】:

    您需要multicolumn UNIQUE or PRIMARY KEY constraint

    CREATE TABLE camembert (
      handle int
    , id int
    , num text
    , PRIMARY KEY (handle, id, num)
    );
    

    UNIQUE 约束的情况下,您可能还希望将所有三列都标记为NOT NULL

    要更改现有表,请使用您已经尝试过的 ALTER TABLE 语法。

    为了强制执行您的要求,约束中的列顺序无关紧要。不过,这对性能很重要。由于任一约束都是在内部使用唯一索引实现的,因此将您查询最多的列放在前面。您可能还想创建额外的索引。

    相关:

    【讨论】:

      猜你喜欢
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-03
      • 2010-10-12
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多