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

时间:2013-02-27 17:16:47

标签: sql sql-server data-structures

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

目前,他们只有三列:id(pk),userIdsomeFkRefuserId上有一个索引,允许我快速选择用户的收藏夹。

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

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

这很可能是坏事。

在我花费数年时间尝试量化确切的差异之前,我想知道是否有一个更好的基于表格的表示,使用我在上面描述的各种操作操作更便宜。

3 个答案:

答案 0 :(得分:6)

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

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

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

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

答案 1 :(得分:3)

如果您不需要能够跨用户操作someFkRef(例如,获取对某些内容感兴趣的用户列表),那么每个用户只能有一条记录,并且有一个有序列表someFkRef(refA, REFB)。

但这是一种去标准化的形式,因为它有一些缺点,它实际上取决于你的需求(以及你未来的需求,这就是问题所在)

答案 2 :(得分:1)

不确定您的依赖引用可能对ID字段有什么影响,但是您是否考虑过覆盖它?我认为有一个SET IDENTITY INSERT = ON,或者你可以做的一些。

我意识到这是一个奇怪的建议,但考虑到你要做的事情,它可能有意义,并且导致最少的开销。