答案 0 :(得分:2)
复合主键并不是数据库设计的问题。在理想的情况下,我们的编程语言和UI库将元组和关系作为一等值支持,因此您可以在下拉控件中分配一对值作为选项的值。但是,由于它们通常仅支持标量变量,因此我们一直在尝试编码或减少标识符。
您当然可以向每个表添加代理键/自动增量列(以及在可用的自然键上的唯一约束)。这是一种非常常见的模式,我见过的大多数数据库至少都有一些这样设置的表。您可能可以保持现有的组合外键不变,或者可能希望/需要更改它们以引用代理主键。
使用代理键作为外键的风险是数据库中的访问路径变得固定。例如,假设tours_regional_details
的主键tours_regional_detail_id
被另一个表中的外键引用。对另一个表的查询将始终需要与tours_regional_details
结合才能获得tour_id
或region_id
。由于标识符在整个数据库中都可以重复使用,因此自然键可提供更灵活的访问路径。这在从属概念的深入层次结构中变得很重要。这些正是复合键的反对者抱怨键“爆炸”的场景,我至少可以同意在编写查询时记住并在众多列上键入联接变得很麻烦。
您可以将自然键列复制到引用表中,但是存储冗余信息需要额外的精力来保持一致性。由于性能或方便性的原因,我经常将其作为代理键来使用,因为代理键可以查询表而不必执行所有联接来取消引用代理标识符。在这些情况下,最好参考自然键。
如果允许我回到理想的世界,也许DBMS可以允许命名和存储联接。
在实践中,代理键有助于平衡我们必须处理的复杂性。使用它们,但不要崇拜它们。