用于处理数据库中可排序项的高效且正确的策略

src*_*091 3 sorting algorithm database-design

在Web应用程序中,我在数据库中有一组实体,其中一个数字字段负责它们的排序.在客户端,这些实体显示为可排序列表,允许用户更改其订单.

截至目前,我有两个管理订单更新的解决方案,但没有一个满足我.

第一个很简单:每次用户更改某个项目顺序时,遍历更新列表,将所有项目ID转换为数组,将其发送到服务器并发出一系列更新,其中每个项目顺序是它在数组中的ID索引.
这种方法的缺点是:许多不必要的更新,无法正确处理发送到服务器的项目数组不包含所有实体ID时的情况.

第二个如下:当用户更改项目订单时,更改项目的ID将与ID"的项目ID"一起发送到服务器,这些项目将"更新"项目位于列表中的新位置.在服务器项目的新订单计算方法(previous.order + next.order) / 2.因此,如果订单3的项目在订单5和6的项目之间移动,则新订单变为5.5
此解决方案每次更改只需要一次更新,但也存在严重问题:由于使用了算法,每次更改都会增加订单号中的小数部分迟早它需要更高的精度然后我的数据库可以提供(我使用MongoDB这种情况,但我想它并不重要).

我的问题是,是否存在任何其他更有效和正确的方法,或者我现在的方法可能会以某种方式得到改善?

Tom*_*son 5

使用序数描述数据库中的顺序,该序号从第一项开始为0,对于每个后续项开始增加1.然后,您只需要发送已移动项目的序数,以及其新上一个邻居的序号.然后你做(我用$来标记变量 - 你需要将它们传递给代码中的查询):

-- if $moved > $previous, and it's moving backwards, move everything between the new previous neighbour and the item forward one
update items
set ordinal = ordinal + 1
where ordinal > $previous
and ordinal < $moved;

-- else $moved < $previous, and it's moving forwards, move everything between the item and the new previous neighbour backwards one
update items
set ordinal = ordinal - 1
where ordinal > $moved
and ordinal <= $previous;

-- then move the item
update items
set ordinal = $previous + 1
where ordinal = $moved;
Run Code Online (Sandbox Code Playgroud)

您可以向序数列添加唯一约束以帮助确保完整性,但您必须更加清楚如何进行更新.