如何存储经常改变DB位置的订购商品

Jör*_*yer 28 sql indexing recursion linked-list data-structures

我需要能够在DB中存储大量订购商品.到目前为止,这是直截了当的:

ID Position OtherFields
 1     45      ...
 2   4736      ...
 3    514      ...
 ...
Run Code Online (Sandbox Code Playgroud)

在查询中,我总是需要获得一些项目(基于OtherFields过滤),但顺序正确.也很容易,在位置上放置一个索引并使用"按位置排序".

现在问题是:项目经常更改其位置,而不仅仅是1或2.如果ID 2将位置从4736更改为2000,我需要更新其位置和旧位置2000和4735之间所有元素的位置,添加1在每一行.并且不仅每个事务更改一个ID而且还有一些ID,并且在短时间内可以有许多事务.

我认为处理更新问题最优雅的方法是使用链接列表而不是位置列,我可以通过将其前任链接到其后继者,然后通过在其之间链接将其插入其他位置,从而将ID 2从其旧位置移除新的前任和继任者.这将是每个职位变更的持续和少量更新,它也是我处理变更的首选方式(在我的案例中是Java).然而,这引起了N + 1问题查询正确的顺序-甚至几元,我不得不通过整个名单在最坏的情况下找出正确的顺序.

所以我的问题是:您建议在必要的更新和查询性能之间取得良好的平衡?

到目前为止,我看到两个有希望的方

  1. 是否存在DBMS(理想情况下是OpenSource),它不仅可以处理链接列表,而且还可以处理具有良好性能的链接列表,例如通过使用链接元素的内部索引?

  2. 也许只有一个BLOB可以选择存储整个链接列表!这样的链接列表有多大/它在数据库中使用了多少内存,并且当获取时让我们说1.000.000条目?我正在使用Java + Hibernate以防万一.我想在获取BLOB后处理内存中的整个列表应该非常快!

但当然也欢迎其他想法!

Mar*_*ers 28

如果放宽约束,Position列必须包含从1到N的整数,而是允许它包含任何数字,那么您可以有效地进行搜索和更新.

你可以通过计算平均值(A + B)DIV 2在位置A和B的两个其他项目之间插入一个项目.例如,如果A是10000而B是12000,那么你的新位置是11000.偶尔你会用完空白由于聚类,此时您可以遍历整个表格,更均匀地重新分配位置.

  • @Marcus Adams:可能,但你仍然会遇到由于精度和舍入错误而没有差距的问题. (7认同)
  • 我只是把它丢在那里.可以将Position定位为浮点列吗?您总是可以将一个数字分成两半.:) (2认同)
  • 无论如何想想都很有趣。 (2认同)

Abe*_*ler 5

如何使用小数位?如果这样做,您可以使用以下方法将其放在其他位置之间:

原始记录是:

ID    Position  Otherfields
--------------------------
1     1.0
2     2.0
.
.
.
5000  5000.0
Run Code Online (Sandbox Code Playgroud)

然后说你将ID 1移到5000之前

ID    Position  Otherfields
--------------------------
1     4999.9
2     2.0
.
.
.
5000  5000.0
Run Code Online (Sandbox Code Playgroud)

现在假设您要将ID 2放在1到5000之间:

ID    Position  Otherfields
--------------------------
1     4999.9
2     4999.91
.
.
.
5000  5000.0
Run Code Online (Sandbox Code Playgroud)

这样你只需改变一条记录......

更新:

重新阅读@Mark Byers的建议后,我们的解决方案似乎非常相似,但使用小数似乎对我来说简单得多......