什么是Hi / Lo算法?
我在NHibernate文档中找到了这个(它's one method to generate unique keys, section 5.1.4.2), but I haven' t找到了它如何工作的一个很好的解释 .
我知道Nhibernate处理它,我不需要知道内部,但我只是好奇 .
什么是Hi / Lo算法?
我在NHibernate文档中找到了这个(它's one method to generate unique keys, section 5.1.4.2), but I haven' t找到了它如何工作的一个很好的解释 .
我知道Nhibernate处理它,我不需要知道内部,但我只是好奇 .
5 回答
hi / lo算法将序列域分成“hi”组 . 同步分配“hi”值 . 每个“hi”组都被赋予最大数量的“lo”条目,可以通过离线分配而不必担心并发重复条目 .
“hi”令牌由数据库分配,并且两个并发调用保证看到唯一的连续值
一旦检索到“hi”标记,我们只需要“incrementSize”(“lo”条目的数量)
标识符范围由以下公式给出:
并且“lo”值将在以下范围内:
从起始值应用:
您可以在this article中找到更详细的说明:
这种视觉呈现也很容易理解:
虽然hi / lo优化器适用于优化标识符生成,但它不能很好地与其他系统在我们的数据库中插入行,而不了解我们的标识符策略 .
Hibernate提供了pooled-lo优化器,它将hi / lo生成器策略与互操作性序列分配机制相结合 . 该优化器既高效又可与其他系统互操作,是比以前的传统hi / lo标识符策略更好的候选者 .
基本思想是你有两个数字来组成一个主键 - 一个“高”数字和一个“低”数字 . 客户端基本上可以递增“高”序列,因为它知道它可以安全地从具有各种“低”值的先前“高”值的整个范围生成密钥 .
例如,假设您有一个“高”序列,当前值为35,“低”数字在0-1023范围内 . 然后客户端可以将序列递增到36(对于其他客户端,当它使用35时能够生成密钥)并且知道密钥35 / 0,35 / 1,35 / 2,35 / 3 ... 35/1023是全部可用 .
能够在客户端设置主键非常有用(特别是使用ORM),而不是在没有主键的情况下插入值,然后将它们提取回客户端 . 除了其他任何东西,它意味着您可以轻松地 Build 父/子关系,并在执行任何插入之前将所有键都放在适当的位置,这使得批处理更简单 .
根据我的经验,我发现Hi / Lo算法非常适合具有复制方案的多个数据库 . 想象一下 . 你有一个服务器在纽约(别名01)和另一个服务器在洛杉矶(别名02)然后你有一个PERSON表...所以在纽约当一个人创建...你总是使用01作为HI值并且LO值是下一个secuential . 例子 .
010000010杰森
010000011大卫
010000012 Theo
在洛杉矶,你总是使用HI 02.例如:
020000045鲁珀特
020000046奥斯瓦尔德
020000047马里奥
因此,当您使用数据库复制(无论什么品牌)时,所有主键和数据都可以轻松自然地组合,而无需担心重复的主键,冲突等 .
这是此方案中的最佳方式 .
除了Jon的回答:
它用于能够断开连接 . 然后,客户端可以向服务器请求hi数字并创建增加lo数量的对象 . 在lo范围用完之前,它不需要联系服务器 .
比Hi-Lo分配器更好的是“线性块”分配器 . 这使用了类似的基于表的原则,但是分配了小的,方便大小的块并产生了良好的人性化值 .
要分配下一个,比方说20个密钥(然后将其作为服务器中的范围保存并根据需要使用):
如果您可以提交此事务(使用重试来处理争用),您已经分配了20个密钥并可以根据需要进行分配 .
该方案的块大小仅为20,比从Oracle序列分配快10倍,并且在所有数据库中都是100%可移植的 . 分配性能相当于hi-lo .
与Ambler的想法不同,它将键空间视为连续的线性数字线 .
这避免了复合键的推动(这从来就不是一个好主意),并避免在服务器重新启动时浪费整个lo-words . 它生成“友好”的人类关键值 .
相比之下,Ambler先生的想法是分配高16位或32位,并且随着hi-words增量产生大的人类不友好的键值 .
分配键的比较:
我实际上是在90年代与Ambler先生通信,向他提出了这个改进方案,但他太过坚持并且顽固地承认使用线性的优点和简单明了号线 .
在设计方面,他的解决方案在数字线(复合键,大型hi_word产品)上基本上比Linear_Chunk更复杂,同时没有实现相对的好处 . 因此,他的设计在数学上被证明是有缺陷的 .