在单个表上使用多个唯一约束是否被认为是糟糕的设计?

app*_*l3r 8 postgresql database-design merge

我正在查看 PostgreSQL 的INSERT INTO .. ON CONFLICT (..) DO UPDATE ..语法并意识到,您不能使用它进行多个唯一约束检查​​。我的意思是,您要么通过列名引用复合唯一索引ON CONFLICT (Name, Symbol)(如果为这两列定义了唯一索引),要么使用主键。如果为列定义两个单独的唯一索引,则只能检查一个。

CREATE TABLE student
    (Id int primary key, Name varchar(50), Symbol varchar(50),
      CONSTRAINT col1_unique UNIQUE (Name),
      CONSTRAINT col2_unique UNIQUE (Symbol)
    ); 

INSERT INTO student
    (Id, Name, Symbol)
VALUES
    (1, 'John', 'J'),
    (2, 'David', 'D'),
    (3, 'Will', 'W');

INSERT INTO student
    (Id, Name, Symbol)
VALUES
    (4, 'Jeremy', 'J')
   on conflict(Name) DO UPDATE
   set Name = 'Jeremy';
Run Code Online (Sandbox Code Playgroud)

可能会抛出错误,说J是重复的。然而,这个例子只是一个糟糕的设计,因为符号应该在另一个表中,并通过一对多关系连接到学生表。这就是为什么我想知道,也许 PostgreSQLon conflict是这样设计的,因为您总是可以以某种方式重构表,其中只有一个唯一索引。是真的还是另有原因?

小提琴示例:http ://www.sqlfiddle.com/#!17/ 9c0ce

Mic*_*een 8

总有第六种,或域键,范式。这里每个非键列都成为它自己的表。所以 3NF 表 T(Key, Col1, Col2, ..) 变成 T1(Key, Col1), T2(Key, Col2) 等等。那些需要唯一性的新表可以声明它。

然而,我认为在一个表上有多个唯一约束是完全可以的。以国家/地区表为例。例如,这将包含 ID、名称、ISO 代码、首都和其他一些内容。前四个中的每一个都是独一无二的。此外,如果我们希望我们的系统依赖于每个都是独一无二的,我相信我们应该为每个定义独特的约束。这强制执行所有消费者都可以依赖的数据的真实性。

  • 问题是(有点)“如果多个 UNIQUE 索引没问题,为什么 PostgreSQL 要求为“ON CONFLICT ... DO UPDATE”指定仲裁索引,不幸的是这个答案没有解决这一点。 (2认同)