我需要能够在数据库中存储大量订购商品。到目前为止,这很简单:
ID Position OtherFields 1 45 ... 2 4736 ... 3 514 ... ...
在查询中,我总是只需要获取一些项(基于OtherFields进行过滤),但顺序正确。同样容易,将索引放在Position上并使用“按位置排序”。
现在的问题是 :项目频繁地更改其位置,而不仅仅是1或2。如果ID 2将位置从4736更改为2000,我需要更新其位置以及旧位置2000和4735之间的所有元素的位置,并加1在每一行中。不仅每个交易会更改一个ID,而且每个交易会更改一个ID,并且在短时间内可以有很多交易。
我认为处理 更新 问题的最优雅方法是使用链接列表而不是Position列,在该列中,我可以通过将ID 2与其前任链接到其后继者来从其旧位置中删除ID 2,然后通过在ID 2之间将其链接起来而将其插入其他位置新的前任和继任者。这将是每个Position更改的恒定且少量更新,这也是我处理更改的首选方式(在Java中为例)。但是,这提出了以正确顺序 查询 的N + 1问题-即使对于某些元素,在最坏的情况下,我也必须遍历整个列表以找出其正确顺序。
所以我的问题是 :您建议如何在必要的更新和查询性能之间取得良好的平衡?
到目前为止,我看到了两个有希望的方向:
是否有一个DBMS(理想情况下为OpenSource)不仅可以使用语法糖来处理链接列表,而且还可以具有良好的性能,例如通过对链接元素使用内部索引来处理?
也许只有一个BLOB可以存储整个链表,这也是一个选择!这样的链表可以得到多大的空间/它将在数据库中使用多少内存,以及何时获取(例如说1.000.000条目)?我正在使用Java + Hibernate,以防万一。我想在获取BLOB之后甚至处理内存中的整个列表都应该非常快!
但是当然也欢迎其他想法!
如果您放宽了该Position列必须包含从1到N的整数的约束,而是允许它包含任何数字,那么您可以高效地进行搜索和更新。
Position
您可以通过计算平均值(A + B)DIV 2将一个项目插入位置为A和B的其他两个项目之间。例如,如果A为10000,B为12000,则新位置为11000。有时您会用尽所有空白由于群集的原因,这时您可以遍历整个表以更均匀地重新分配位置。