Database 如何保存特定的、可变的;订单“;进入数据库

Database 如何保存特定的、可变的;订单“;进入数据库,database,sorting,database-design,Database,Sorting,Database Design,假设我有一些对象,我希望用户能够以他们希望的任何方式对它们重新排序,比如说,通过拖动它们。所以我会 奶酪 松饼 牛奶 然后用户将“牛奶”拖到顶部,做出新的订单 牛奶 奶酪 松饼 如何在数据库中存储这些对象的顺序,是否有最佳做法?简单的方法可能只是为每个对象存储一个名为“order”的数值,但这对我来说似乎太麻烦了,因为在大多数情况下,您都必须对order值进行调整。您建议的“简单”方法也是最佳做法 如果您希望以相同的顺序重新显示它们,并且希望它们能够在任何时候重新排序,我认为您都无法避免

假设我有一些对象,我希望用户能够以他们希望的任何方式对它们重新排序,比如说,通过拖动它们。所以我会

  • 奶酪
  • 松饼
  • 牛奶
然后用户将“牛奶”拖到顶部,做出新的订单

  • 牛奶
  • 奶酪
  • 松饼

如何在数据库中存储这些对象的顺序,是否有最佳做法?简单的方法可能只是为每个对象存储一个名为“order”的数值,但这对我来说似乎太麻烦了,因为在大多数情况下,您都必须对order值进行调整。

您建议的“简单”方法也是最佳做法

如果您希望以相同的顺序重新显示它们,并且希望它们能够在任何时候重新排序,我认为您都无法避免在数据库中存储一些指示显示优先级的值。我使用了您描述的方法来排序常见问题解答中的项目、与补助金相关的研究人员、菜单中的项目顺序,…

考虑到托尼·安德鲁斯的答案,您也可以为每个条目存储一个“下一个”索引。然后,当你把它们全部拉进去时,沿着链条在阵列中行走。这使得移动项目更容易,因为您最多只需触摸两行


这种方法的缺点是,如果您需要一个子集(例如前3个项),您仍然需要拉入所有项,或者使用SQL循环。因此,它介于更新期间影响所有行和读取期间访问所有项之间。和以往一样,测量速度,看看哪个更适合您的情况。

是的,在关系数据库中没有顺序,这是基本概念之一。所以没有数值之类的东西是不可能的

看看托尼·安德鲁(Tony Andrew)和马克(Mark)的答案,我似乎真的只有两个选择:

  • 保存“下一个”值,使对象的行为类似于链表(请参见Mark的答案)
    有了这个,更改订单很便宜,但我必须检索项目,然后按“下一个”值对它们进行排序,这很昂贵
  • 保存“订单”值(参见Tony Andrew的回答)
    这使得检索成本很低,但保存新订单的成本可能很高,因为在最坏的情况下,我必须更改所有订单值。克莱特斯指出,可以使用2^n形式的大数作为阶数乘数

梅塔:所有这些答案都是正确的,我应该选择哪一个作为正确答案?

在我的应用程序中,读取操作将比写入操作频繁得多。使用数值指示排序顺序,并处理重新排序项目的成本。这可以通过以下事实来弥补:您可以按照正确的顺序高效地检索项目以用于显示目的(在典型的应用程序中,这种情况发生的频率比重新调用更高)

此外,如前所述,如果检索数据的子集(按类型筛选或其他内容),则剩余的项仍处于正确的排序顺序


记住咒语K.I.S.S.

我发现处理这个问题的最好方法是使用浮点顺序字段。在其他两个项目之间移动某个项目时,请将该字段设置为其相邻项之间的中间位置


这在读写方面都很便宜。唯一的缺点是浮动越来越长:)

您可以使用以前的Id,每次新的插入都可以将上次插入的行Id设置为以前的Id,如下所示

表格,td{
边框:.2px纯黑
}

身份证件
名称
上一个ID
1.
第一项
无效的
2.
第二项
1.
3.
thid_项目
2.

理论上,如果希望以某个值获取特定元素,可以使用,或者通常使用某种B-树来存储值。如果它们发生更改,则在最坏的情况下,您正在更改
O(log n)
项。如果您有30000件商品,您只需更改4件或5件即可保留订单。

重复此项是否回答了您的问题?既然你问起了在数据库中存储的问题,我就投票支持“天真”的方法。。通过最初插入偏移量为100的对象,可以最大限度地减少重新排序碰撞(当您必须更改多个对象以重新插入到新位置时),两者都不是绝对100%的“最佳”。如果您的读操作比写操作多得多,那么检索速度可能是主要关注点。如果您有大量的写入操作或必须订购大量的项目,那么写入速度反而很重要。这是逐案判断。浮点数据类型+1。如果将初始顺序值设置为偏移100并使用浮点,则可以避免巨大的小数位数,并且仍然具有不需要调整冲突搜索的数据类型的优点。