我需要能够在DB中存储大量订购商品。到目前为止,这是直截了当的:
ID Position OtherFields
1 45 ...
2 4736 ...
3 514 ...
...
在查询中,我总是需要获得一些项目(基于OtherFields过滤),但顺序正确。也很简单,在位置上放置一个索引并使用“按位置排序”。
现在问题:项目频繁更改其位置,而不仅仅是1或2.如果ID 2将位置从4736更改为2000,我需要更新其位置和所有位置旧位置2000和4735之间的元素,每行添加1。而且,每个交易不仅会更改一个ID,而且会在短时间内发生许多交易。
我认为处理更新问题的最优雅的方法是使用链接列表而不是位置列,我可以通过将ID 2从其前任链接到其后继者来从旧位置删除ID 2然后通过在新的前任和后继者之间链接它将其插入其他地方。这将是每个职位变更的持续和少量更新,它也是我处理变更的首选方式(在我的案例中是Java)。然而,这会以正确的顺序引发查询的N + 1问题 - 即使对于一些元素,我必须在最坏的情况下查看整个列表以找出正确的顺序。
所以我的问题是:您建议在必要的更新和查询效果之间取得良好的平衡?
到目前为止,我看到了两个有希望的方向:
是否有DBMS(理想情况下是OpenSource)可以处理链接列表,不仅具有语法糖,而且具有良好的性能,例如:通过使用链接元素的内部指数?
也许只有一个BLOB可以存储整个链接列表的选项!这样的链接列表有多大/它在数据库中使用了多少内存,并且当获取时让我们说1.000.000条目?我正在使用Java + Hibernate以防万一。我想在获取BLOB后处理内存中的整个列表应该非常快!?
但当然也欢迎其他想法!
答案 0 :(得分:28)
如果放宽约束,Position
列必须包含从1到N的整数,而是允许它包含任何数字,那么您可以有效地进行搜索和更新。
您可以通过计算平均值(A + B)DIV 2在位置A和B的两个其他项目之间插入一个项目。例如,如果A是10000而B是12000,那么您的新位置是11000.偶尔您会运行由于聚类导致的间隙不足,此时您可以通过整个表格更均匀地重新分配位置。
答案 1 :(得分:5)
使用小数位置怎么样?如果这样做,您可以使用以下方法将其置于其他位置之间:
原始记录是:
ID Position Otherfields
--------------------------
1 1.0
2 2.0
.
.
.
5000 5000.0
然后说你将ID 1移到5000之前
ID Position Otherfields
--------------------------
1 4999.9
2 2.0
.
.
.
5000 5000.0
现在假设你想把ID 2放在1到5000之间:
ID Position Otherfields
--------------------------
1 4999.9
2 4999.91
.
.
.
5000 5000.0
这样你只会改变一条记录......
更新:
重新阅读@Mark Byers的建议后,似乎我们的解决方案非常相似,但使用小数似乎对我来说简单得多......
答案 2 :(得分:0)
另一种解决方案是使用词汇排名。只要两个字符串之间没有值,就可以简单地添加一个新字符。唯一的缺点是,与数值解答相比,它消耗更多的内存,而数值解答在其他答案中都有提及。
对没有错误的数据库而言,规范化不是必需的,但可以选择执行归一化以减少字符串长度。
这是一段有趣的视频,详细解释了它:https://www.youtube.com/watch?v=OjQv9xMoFbg&feature=youtu.be
答案 3 :(得分:-1)
以下内容可能会有所帮助。它没有直接回答你的问题,但可以说明如何做到这一点(如果你的要求可能):