Rob*_*ebe 17 oracle database-design
这是我最近一直在考虑的另一个.我们在之前的讨论中得出结论:"自然主键是坏的,人工主键是好的." 之前使用Hibernate我已经看到Hibernate默认为所有表创建一个序列.起初我对此感到困惑,你为什么要这样做.但后来我看到了它使父母和孩子联系起来的优势.由于没有表具有相同的主键值,因此意外地将父项与不是子项的表链接不会产生任何结果.
有没有人看到这种方法的任何缺点.我只看到一个:你的数据库中不能有超过999999999999999999999999999的记录.
Ton*_*ews 11
所有代码从单个序列中获取值可能会出现性能问题 - 请参阅此Ask Tom线程.
根据序列在数据库中的实现方式,始终点击相同的序列可能更好或更差.当只有少数或仅一个线程请求新值时,将不会出现锁定问题.但糟糕的实施可能会导致拥堵.
另一个问题是回滚事务:序列不会被回滚(因为其他人可能已经请求了更高的值),因此您可能会有很大的间隙,这会比您预期的更快地占用您的数字空间.OTOH,需要一些时间才能吃掉2到40亿个ID(如果你"只"使用32位(有符号)的int),所以在实践中它很少成为问题.
最后,如果必须,您无法轻松重置序列.但是如果您需要重启序列(例如,自午夜以来的记录数),您可以告诉Hibernate创建/使用第二个序列.
一个主要优点是您可以通过ID唯一地识别数据库中任何位置的对象.这意味着您可以严格删除在生产系统中编写的日志信息,如果只有ID,仍然可以找到一些内容.
我更喜欢每桌有一个序列.这来自一个普遍观察:一些表("主表")具有相对较小的行数并且必须"永久"保持.例如,ERP中的客户表.
在其他表("事务表")中,永久生成许多行,但在一段时间之后,这些行可以存档(或简单地删除).最极端的例子是用于调试目的的跟踪表; 它可能会以每秒数百行的速度增长,但几天后每行都会过时.
主表中的小ID使得在直接在数据库上工作时更容易,例如用于调试目的.
select * from orders where customerid=415
Run Code Online (Sandbox Code Playgroud)
VS
select * from orders where customerid=89461836571
Run Code Online (Sandbox Code Playgroud)
但这只是一个小问题.更大的问题是骑自行车.如果对所有表使用一个序列,则根本无法让它重新启动.每个表有一个序列,您可以在归档或删除旧数据时重新启动事务表的序列.主表几乎没有问题,因为它们变得慢得多.
我认为对所有表只有一个序列没什么价值.到目前为止所说的论点并没有说服我.