数据库表设计与易用性。 (复合PKs?)

时间:2010-03-29 21:21:43

标签: database-design

我有一个包含3个字段的表:颜色,水果,日期。我可以选择1种水果和1种颜色,但我每天只能做一次。

的示例:

  1. red,apple,monday
  2. red,芒果,星期一
  3. 蓝色,苹果,星期一
  4. 蓝色,芒果,星期一
  5. red,apple,tuesday
  6. 我可以通过以下两种方式构建表:

    1.-使颜色,水果和日期成为复合主键(PK)。这样可以很容易地将数据插入表中,因为所需的所有验证都是由数据库完成的。

    • PK颜色
    • PK水果
    • PK日期

    2.-将Have和id列设置为PK,然后设置所有其他字段。很多人都说应该这样,因为复合PK是邪恶的。例如,CakePHP不支持它们。

    • PK id
    • 颜色
    • 水果
    • 日期

    两者都有优势。哪个是“更好”的方法?

4 个答案:

答案 0 :(得分:3)

我实际上更喜欢第二个选项,ID列作为“代理”主键。大多数数据库专家可能会说你应该在表中查找“自然键”(可能是复合词),但我认为使用单列代理PK更容易,特别是在使用ORM时。即使ORM支持复合键,使用代理键仍然更容易。对于使用ID的表,而不是复合键,也更容易编写查询。

您可以使用唯一约束来实现这三列唯一性的数据库内验证。

答案 1 :(得分:2)

“最佳”方法是#2。

为什么呢? “复合PK是邪恶的”。他们通常没有多大帮助。从处理器很小,磁盘很小而且每个索引都很珍贵的日子来看,它们都是一种拖延。在三列和单独的代理主键上使用唯一索引约束更简单。

此外,当您拥有单独的代理PK时,可以更新所有数据,而不会破坏数据的参照完整性。

既然你已经知道了,为什么要发布这个问题?

答案 2 :(得分:2)

您可以通过在第二个示例的三个on-PKey列上设置唯一索引来“强制”执行相同类型的唯一性验证。例如。创建一个包含所有三个字段并将其设置为唯一的索引。 (不要在该索引中包含pkey!)

答案 3 :(得分:1)

如果你正在使用支持复合PK的ORM /框架(包括任何一个),并且你不需要在另一个表中使它成为FK,那么使用复合PK。否则使用autoinc PK并创建其他字段的复合唯一键。