这是来自Hibernate 官方教程:
有一个替代
<composite-id>
声明允许使用复合键访问遗留数据。强烈建议不要将其用于其他任何用途。
为什么不鼓励复合键?我正在考虑使用一个 3 列表,其中所有列都是外键,并且一起形成一个主键,这在我的模型中是一个有意义的关系。我不明白为什么这是一个坏主意,尤其是我将在它们上使用索引。
有什么选择?创建一个额外的自动生成的列并将其用作主键?无论如何,我仍然需要查询我的 3 列!?
简而言之,为什么这个说法是正确的?什么是更好的选择?
这是来自Hibernate 官方教程:
有一个替代
<composite-id>
声明允许使用复合键访问遗留数据。强烈建议不要将其用于其他任何用途。
为什么不鼓励复合键?我正在考虑使用一个 3 列表,其中所有列都是外键,并且一起形成一个主键,这在我的模型中是一个有意义的关系。我不明白为什么这是一个坏主意,尤其是我将在它们上使用索引。
有什么选择?创建一个额外的自动生成的列并将其用作主键?无论如何,我仍然需要查询我的 3 列!?
简而言之,为什么这个说法是正确的?什么是更好的选择?
他们不鼓励他们有几个原因:
除了其他三列之外,另一种方法是使用单列自动生成的主键。如果要使三列的元组唯一,请使用唯一约束。
即使现在 - 也许 - 回答你的问题为时已晚,我想在这里就 Hibernate 使用代理键的需要(这真的是一个建议吗?)提出另一种观点(我希望更温和)。
首先,我想明确一个事实,即代理键(人工自动生成的)和自然键(由具有域含义的列组成)各有利弊。我并不是说一种键类型比另一种更好。我想说的是,根据您的要求,自然键可能是比代理键更好的选择,反之亦然。
代理键是:
正如Java Persistence with Hibernate参考中所述:
更有经验的 Hibernate 用户只使用 saveOrUpdate();让 Hibernate 决定什么是新的和什么是旧的要容易得多,尤其是在具有混合状态的更复杂的对象网络中。独占 saveOrUpdate() 唯一(不是很严重)的缺点是它有时无法在不触发数据库的 SELECT 的情况下猜测一个实例是旧的还是新的——例如,当一个类被映射到一个自然复合键并且没有版本或时间戳属性。
可以在此处找到限制的一些表现形式(我认为,我们应该这样称呼它) 。
请不要太拘泥于你的观点。在相关时使用自然键,并在最好使用代理键时使用它们。
希望这对某人有所帮助!
我会从设计的角度考虑这个问题。不仅仅是 Hibernate 认为它们是好是坏。真正的问题是:自然键是否适合成为我的数据的良好标识符?
在您的业务模型中,今天可以很方便地通过一些数据来识别记录,但业务模型会随着时间的推移而发展。当这种情况发生时,您会发现您的自然密钥不再适合唯一标识您的数据。并且由于其他表中的参照完整性,这将使事情更难改变。
拥有代理 PK 很方便,因为它不会将您的数据在存储中的识别方式与您的业务模型结构联系起来。
自然键无法从序列中生成,数据无法通过其数据识别的情况更为常见。这是自然密钥与存储密钥不同的证据,它们不能被视为通用(和好的)方法。
使用代理键简化了应用程序和数据库的设计。它们更容易使用,性能更高,并且做得很好。
自然键只带来缺点:我想不出使用自然键的单一优点。
也就是说,我认为 hibernate 对自然(组合)键没有真正的问题。但是有时您可能会发现一些问题(或错误),以及文档问题或寻求帮助,因为 hibernate 社区广泛承认代理键的好处。因此,请为您选择组合键的原因准备一个很好的答案。
如果正确理解 Hibernate 文档:
“有一个替代<composite-id>
声明允许使用复合键访问遗留数据。强烈建议不要将其用于其他任何事情。”
关于主题 5.1.4。id 标记 xml<id>
使主键映射过早我们可以得出结论,hibernate 文档不鼓励使用复合主键映射而<composite-id>
不是<id>
xml 标记,并且不会使任何引用否定使用复合主键。
使用数据库作为工具开发的应用程序肯定更有利于保持代理键上的工作流,使用聚集索引进行查询优化。
然而,需要特别注意数据仓库和 OLAP 风格的系统,它们利用大量的事实表将维度的代理键联系在一起。在这种情况下,数据决定了可用于维护记录的仪表板/应用程序。
因此,与其说一种方法优于另一种方法,不如说是一种指令对另一种方法有利,用于关键构造:您不会很容易地开发 Hibernate 应用程序来利用对 SSAS 系统实例的直接访问。
我使用这两种键组合进行开发,并且感觉要实现实心星形或雪花模式,具有聚集索引的代理通常是我的首选。
因此,对于 OP 和其他人的看法:如果您想保持 db 与您的开发(Hibernate 擅长)保持不变 - 使用代理方法,并且当数据读取趋于缓慢时,或者您注意到某些查询耗尽性能,恢复到您的特定数据库,并添加优化查询顺序的复合聚集索引。
不要混淆主键和唯一索引。如果您使用自然键,则将您的键链接到您的业务、业务数据;它不是那么好。因此,即使可以使用一组数据来定义复合键,也不建议这样做。在我看来,复合键主要在您拥有现有模式时可用