如何将特定的,可变的"订单"保存到数据库中

win*_*ith 25 database sorting database-design

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

  • 起司
  • 松饼
  • 牛奶

然后用户将"牛奶"拖到顶部,进行新订单

  • 牛奶
  • 起司
  • 松饼

是否有最佳实践如何将这些对象的顺序存储在数据库中?天真的方法可能只是为每个对象存储一个称为"顺序"的数值,但这对我来说似乎太麻烦了,因为你必须在大多数时间里改变顺序值.

Sea*_*ess 16

我发现处理这个问题的最好方法是有一个浮点顺序字段.当您在其他两个项目之间移动某些内容时,请将该字段设置为其邻居之间的中间位置.

这在读取和写入上都很便宜.唯一的缺点是花车越来越长:)

  • +1 表示浮点数据类型。如果您将初始订单值设置为偏移 100 并使用浮点数,您可以避免出现巨大的小数位,并且仍然具有永远不需要调整搜索冲突的数据类型的好处。 (2认同)

Ton*_*ews 13

你建议的"天真"方法也是最好的做法!


Mar*_*ark 12

考虑到Tony Andrews的回答,您可以选择在每个条目中存储"下一个"索引.然后当你把它们全部拉进去时,按照链条走完阵列.这使得移动项目更容易,因为您只需要触摸最多两行.

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


win*_*ith 5

特别是看托尼·安德鲁和马克的答案,看来我真的只有两种选择:

  • 保存"下一个"值,使对象的行为类似于链接列表(请参阅Mark的答案)
    这样,更改订单很便宜,但我必须检索项目,然后按"下一个"值对其进行排序,太贵了
  • 保存"订单"值(请参阅Tony Andrew的回答)
    这使得检索成本低廉但保存新订单可能很昂贵,因为在最坏的情况下,我必须更改所有订单值.cletus指出,可以使用2 ^ n形式的大数字作为订单乘数.

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

  • 两者都绝对100%"最好".如果您的读取次数多于写入次数,则检索速度可能是主要考虑因素.如果您有大量写入或必须订购大量项目,则写入速度非常重要.这是一个逐案判断. (3认同)

Jim*_*kus 5

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

此外,正如已经提到的,如果您检索数据的子集(按类型或其他内容过滤),其余项目仍按正确的排序顺序。

记住口头禅 KISS