我知道这违反了关系数据库的原则,但让我描述一下情况。
我有一个页面,用户将在其中放置许多项目。
________________
| -Item1 |
| -Item2 |
| -Item3 |
| -Item4 |
|________________|
这些项目必须按照用户给它们的顺序排列。但是,此顺序可能会被用户更改任意次数。
________________
| -Item1 |
| -Item4 |
| -Item2 |
| -Item3 |
|________________|
方法一
我最初的想法是给项目一个索引来代表他们在列表中的位置
Page Item
----------- ---------------
FK | pid FK | pid
| name PK | iid
| index
| content
使用此解决方案,您可以选择where pid = Page.pid
和order by index
的项目,这很方便。但是,每次更改顺序时,您都必须在其他项目(最好的情况)和所有其他项目(最坏的情况)之间的任何位置进行更改。
方法二
我还考虑制作一个类似数据结构的“链表”,其中每个项目都指向列表中的下一个项目。
Page Item
----------- ---------------
FK | pid FK | pid
| name PK | iid
| next
| content
这可能会降低更改订单的成本,但我们将不得不依靠前端编程来提取订单。
有没有我没有想到的方法?请告诉我。
最佳答案
解决方案:将 index
设为字符串(因为字符串本质上具有无限的“任意精度”)。或者,如果您使用 int,请将 index
增加 100 而不是 1。
性能问题是这样的:两个排序项之间没有“中间”值。
item index
-----------------
gizmo 1
<<------ Oh no! no room between 1 and 2.
This requires incrementing _every_ item after it
gadget 2
gear 3
toolkit 4
box 5
相反,这样做(下面更好的解决方案):
item index
-----------------
gizmo 100
<<------ Sweet :). I can re-order 99 (!) items here
without having to change anything else
gadget 200
gear 300
toolkit 400
box 500
更好的是:这是 Jira 解决这个问题的方法。他们的“排名”(您称之为索引)是一个字符串值,允许排名项目之间有大量的喘息空间。
这是我使用的 jira 数据库的真实示例
id | jira_rank
---------+------------
AP-2405 | 0|hzztxk:
ES-213 | 0|hzztxs:
AP-2660 | 0|hzztzc:
AP-2688 | 0|hzztzk:
AP-2643 | 0|hzztzs:
AP-2208 | 0|hzztzw:
AP-2700 | 0|hzztzy:
AP-2702 | 0|hzztzz:
AP-2411 | 0|hzztzz:i
AP-2440 | 0|hzztzz:r
注意这个例子 hzztzz:i
。字符串排名的优点是您用完了两个项目之间的空间,您仍然不必重新排名任何其他内容。您只需开始向字符串追加更多字符以缩小焦点。
编辑:如评论中所述,您不能在 0|hzztzz:
和 0|hzztzz:a
之间插入任何内容。我想这就是为什么我看到 jira 的数据库定期自动在末尾附加 :i
而不是 :a
以避免这种情况。如果你真的想防止出现问题,那么我认为你可以改变你的算法,这样(例如)每次你在末尾插入 :a
时,你改为插入:人工智能
。通过这种方式,您在逻辑上保证没有排名会以字母 a
结尾——这应该意味着您将始终有“空间”来插入更多项目,而无需重新排序任何东西。
关于database - 数据库中有序列表的最佳表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9536262/