Database design 组合代理外键作为PK或单独的代理键

Database design 组合代理外键作为PK或单独的代理键,database-design,Database Design,下图显示了两种可选的数据库设计。一个具有两个外键的组合,另一个具有自己的代理键。第二个选项将对DanceGroupId和StudioId具有复合唯一约束,因此不能输入相同的两个。我一直采用第一种设计,但在用C语言构建类之后,如果我能在所有表上放置一个通用的非复合代理键,这将有助于C代码重用。在数据库设计方面,在表(如Booking)上使用代理项而不是组合项有什么负面影响 我不想在这里讨论一般的复合键和代理键,这有点不同,因为选项一中的复合键是由外键组成的。据我所知,由于代理不依赖于业务相关数据

下图显示了两种可选的数据库设计。一个具有两个外键的组合,另一个具有自己的代理键。第二个选项将对DanceGroupId和StudioId具有复合唯一约束,因此不能输入相同的两个。我一直采用第一种设计,但在用C语言构建类之后,如果我能在所有表上放置一个通用的非复合代理键,这将有助于C代码重用。在数据库设计方面,在表(如Booking)上使用代理项而不是组合项有什么负面影响


我不想在这里讨论一般的复合键和代理键,这有点不同,因为选项一中的复合键是由外键组成的。据我所知,由于代理不依赖于业务相关数据,因此比自然密钥更受青睐。在这种情况下,这不是一个问题,也从来没有过,但是我以前从未在“中间”表上看到过这种方法。像在第二个选项中那样实现它似乎是合理的,但我想知道我是否遗漏了什么。

在不需要的情况下定义伪密钥可能会带来负面影响:

  • 每行一个额外的多余整数会使行变宽,占用更多磁盘和内存空间

  • 机制上的更多争用用于生成不必要的伪密钥值

  • 破坏聚集索引的使用以获得额外性能。定义聚类索引以匹配最常见的查询是有意义的。例如,如果您的查询通常包括StudioId上的条件,则将其作为聚集索引的第一列。在某些SQL实现(例如MySQL)中,主键始终用作聚集索引。在其他一些SQL实现中,您可以选择另一个辅助唯一键作为聚集索引


谢谢比尔,这似乎是一个很好的回答:-)我想这是一个权衡系统内存和性能要求以及代码重用的例子。对于我为我的应用程序考虑的解决方案来说,这些考虑可能是最低限度的。