如果我开始使用HiLo生成器为表分配ID,然后决定增加或减少容量(即最大'lo'值),这是否会导致与已分配ID的冲突?
我只是想知道是否需要在数字上加上一个大红旗,上面写着"永远不要改变这个!"
注意 - 不是特定于NHibernate,我只是对一般的HiLo算法感到好奇.
Jus*_* L. 20
HiLo算法通常基本上将两个整数映射到一个整数ID.它保证每个数据库的数字对是唯一的.通常,下一步是保证唯一的数字对映射到唯一的整数ID.
在之前的SO答案中给出了HiLo概念上如何工作的一个很好的解释
更改max_lo将保留您的数字对将是唯一的属性.但是,它是否会确保映射的ID是唯一且无冲突的?
我们来看看Hibernate的HiLo实现.他们似乎使用的算法(从我收集到的算法)是:(并且我可能不在技术上)
h = high sequence (starting at 0)
l_size = size of low block
l = low sequence (starting at 1)
ID = h*l_size + l
Run Code Online (Sandbox Code Playgroud)
所以,如果您的低块是100,那么您的保留ID块将会是1-100,101-200,201-300,301-400 ......
您的高序列现在是3.现在,如果您突然将l_size更改为10,会发生什么?你的下一个区块,你的高位增加了,你就得到了4*10+1 = 41
哎呀.这个新值绝对属于"保留块" 1-100.高序列为0的人会认为,"好吧,我1-100只为我保留了范围,所以我只需放下一个41,因为我知道这是安全的."
降低 l_max 时,碰撞的可能性非常高.
相反的情况呢,提高它?
回到我们的例子,让我们将l_size提高到500,将下一个键转换为4*500+1 = 2001,保留范围2001-2501.
在提高你的l_max 时,在HiLo的这个特定实现中看起来会避免碰撞.
当然,您应该自己做一些自己的测试,以确保这是实际的实现,或接近它.一种方法是将l_max设置为100并找到前几个键,然后将其设置为500并找到下一个键.如果这里提到的巨大跳跃,你可能会安全.
但是,我绝不建议在现有数据库上提高l_max是最佳做法.
自行决定; HiLo算法并不是一个考虑到不同l_max的算法,并且根据您的确切实现,您的结果最终可能无法预测.也许那些有过提高l_max并找到麻烦经验的人可以证明这一点是正确的.
总而言之,即使从理论上讲,Hibernate的HiLo实现很可能在l_max被提升时避免冲突,但它可能仍然不是一个好习惯.你应该编码好像l_max不会随着时间的推移而改变.
但如果你感到幸运......