我是否应该使用复合主键?

在Java的JPA中似乎只有对复合数据库键的第二类支持(通过IndeddedId或IdClass注释)。当我阅读复合键时,无论语言如何,人们都会觉得它们是一件坏事。但我不明白为什么。如今,复合键是否仍可接受使用?如果没有,为什么不呢?

我找到了一个同意我观点的人:http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx

但另一个不这样做的人:http://weblogs.java.net/blog/bleonard/archive/2006/11/using_composite.html

是只有我,还是人们无法区分复合键在何处合适?我看到复合主键在表不表示实体时很有用 - 即当它表示连接表时。

一个简单的例子:

Actor { Id, Name, Email } Movie { Id, Name, Year } Character { Id, Name } Role { Actor, Movie, Character }

在这里,Actor,电影和角色显然受益于将Id列作为主键。

但角色是多对多联接表。我认为仅仅为了标识数据库中的一行而创建 id 是没有意义的。对我来说,很明显,主键是.这似乎也是一个相当有限的功能,特别是如果连接表中的数据一直在变化,一旦主键序列环绕到0,您可能会发现自己遇到主键冲突。{ Actor, Movie, Character }

那么,回到最初的问题,使用复合主键的做法是否仍然可接受?如果没有,为什么不呢?


答案 1

在我个人看来,由于以下几个原因,您应该避免使用复合主键:

  1. 未来的变化:当你设计一个数据库时,你有时会错过未来会变得重要的东西。一个重要的例子是认为两个或多个字段的组合是唯一的(因此可以成为主键),而将来您希望允许NUL或其他非唯一值在其中。拥有单个主键是防止此类更改的良好可靠解决方案。

  2. 统一性:如果每个表都有一个唯一的数字ID,并且您还保持了有关其名称的一些标准(例如“ID”或“tablename_id”),则代码和引用它的SQL更清晰(在我看来)。

还有其他原因,但这些只是少数几个。

我要问的主要问题是,如果你有一组唯一的字段,为什么不使用单独的主键?费用是多少?额外的整数索引?这还不错。

希望有所帮助。


答案 2

我认为使用复合键没有问题。

对我来说,数据库本身就是一个组件,应该像对待代码一样对待代码:例如,我们想要干净的代码,清楚地传达它的意图,做一件事并且做得很好,不会增加任何不必要的复杂性,等等。

db也是如此,如果PK是复合的,这就是现实,所以模型应该保持干净和清晰。复合 PK 比混合自动增量 + 约束更清晰。当您看到一个不执行任何操作的ID列时,您需要询问真正的PK是什么,是否有任何其他隐藏的事情,您应该注意,等等。一个明确的PK不会留下任何疑问。

db是你的应用程序的基础,对我来说,我们需要最坚实的基础。在此基础上,我们将构建应用程序(Web或非Web)。所以我不明白为什么我们应该弯曲数据库模型以符合一个开发工具/框架/语言中的某些特定内容。数据正在指导应用程序,而不是相反。如果ORM在未来发生变化并变得过时,并且出现了一个更好的解决方案,强加了另一个模型,该怎么办?我们不能使用数据库模型来适应这个或那个框架,模型应该保持不变,它不应该取决于我们使用什么工具来访问数据......

如果数据库模型将来发生更改,则应因功能更改而更改。如果我们今天知道这个功能将如何变化,我们就已经在建模了。如果任何未来的更改都会在时机成熟时处理,例如我们无法预测对现有数据的影响,因此一个额外的列并不能保证它将拒绝任何未来的更改......

我们应该为今天的功能进行设计,并保持数据库模型尽可能简单,这样将来就很容易改变/发展。


推荐