【发布时间】:2011-03-24 21:03:18
【问题描述】:
我需要能够在数据库中存储大量订购项目。到目前为止,这是直截了当的:
ID Position OtherFields
1 45 ...
2 4736 ...
3 514 ...
...
在查询中,我总是需要以正确的顺序获取一些项目(根据 OtherFields 过滤)。也很简单,在位置上放置一个索引并使用“按位置排序”。
现在的问题:项目经常改变它们的位置,而不仅仅是 1 或 2。如果 ID 2 将位置从 4736 更改为 2000,我需要更新它的位置和所有的位置旧位置 2000 和 4735 之间的元素,每行加 1。而且每笔交易改变的不仅仅是一个ID,而是几个,短时间内可以有很多笔交易。
我认为处理 update 问题的最优雅的方法是使用链表而不是 Position 列,在该列中,我可以通过将其前身链接到其后继者来从其旧位置删除 ID 2然后通过在其新的前任和继任者之间链接它来将其插入其他地方。这将是每次位置更改的恒定且少量的更新,这也是我处理更改的首选方式(在我的情况下是 Java)。但是,这会引发以正确顺序进行 查询 的 N+1 问题 - 即使对于少数元素,在最坏的情况下我必须遍历整个列表才能找出它们的正确顺序。
所以我的问题是:为了在必要的更新和查询性能之间取得良好的平衡,您有什么建议?
到目前为止,我看到了两个有希望的方向:
是否有一个 DBMS(理想情况下是开源的)可以处理链表,不仅具有语法糖,而且具有良好的性能,例如通过使用链接元素的内部索引?
也许只使用一个 BLOB 来存储整个链接列表也是一种选择!这样的链接列表可以有多大/它在数据库中使用多少内存以及何时获取1.000.000个条目?我正在使用 Java + Hibernate 以防万一。我想在获取 BLOB 之后处理内存中的整个列表应该非常快!?
当然也欢迎其他想法!
【问题讨论】:
-
Bill Karwin 对此有很好的回答,您可能想看看:stackoverflow.com/questions/192220/…
-
我认为比尔的“树”解决方案不合适。虽然数据是分层的,但它是一个单一的大树路径,每次插入后都必须更新,这相当于重新索引。
-
我也读过这个问题,起初它对我来说似乎很有希望,但后来我意识到,例如对于总共 2000 个位置 1000 的条目,您必须在 Closure Table 中创建 1000 个后代条目。总的来说,我认为这将为 2000 个职位提供大约 2.000.000 个条目,并进行大量必要的更新——对于一个简单的列表来说,写作方面的工作和性能太多,所以我同意 Marcus。
-
在软件工程网站上类似:Storing a re-orderable list in a database
标签: sql data-structures recursion indexing linked-list