在数据库中存储可重新排序项的有效方法

spe*_*der 10 sql sql-server data-structures

所以我有一个用户收藏夹表.它们有几百万行.

目前,它们只有三列:id(pk),userIdsomeFkRef.有一个索引userId允许我快速选择用户的收藏夹.

目前这些是按顺序排序的id,实际上只是插入顺序.我们希望为用户提供重新订购收藏的机会,最有可能通过某种拖放式互动.

我的第一个(我怀疑天真)方法,这将是简单地增加一个order列,并在一个综合指数userId,order.但是,在反射时,当用户将其项目移动到列表上一定距离时,项目的起始位置和结束位置之间的所有中间行都需要order重新计算其列,因此也需要重新计算索引.

这(很可能)很糟糕.

在我花了很多年的时间试图量化到底有多糟糕之前,我想知道是否有一个更好的基于表格的表示,用我上面描述的各种操作来操作更便宜.

Gor*_*off 6

对于拖放交互,更好的选择是优先级.您将从优先级1,2,3等开始,就像排序顺序一样.

但是,用户想要将项目5移动到1和2之间.瞧!给它1.5的值.没有其他值需要改变.索引更新负责其余部分.

为此,优先级需要存储为浮点数.这可能是一个问题.此外,足够多的更改可能会导致浮动点的限制.因此,如果用户试图获取最后一个元素并将其插入前两个元素之间,那么他/她可以使用它几十次左右.

您可以使用从1开始定期为一个(或所有用户,如果是批处理)重新分配编号的流程来解决此问题.

  • @SamuelEUSTACHI 指数并不是最糟糕的部分。最糟糕的是,浮点数的精度是有限的,经过大约 53 次精心设计的移动后,可能会破坏排序逻辑。是的,你总是可以有一个计数器和一个触发器来重新规范化这个列表,但我很不确定它是否会成为一个更有效的解决方案。 (3认同)

Sam*_*CHI 3

如果您不需要能够跨用户操作 someFkRef(例如,获取对某事感兴趣的用户列表),那么每个用户只能有一条记录,其中包含 someFkRef(refA、refB)的有序列表。

但这是一种非规范化形式,并且由于它有一些缺点,因此它实际上取决于您的需求(以及您未来的需求,这就是麻烦所在)