一尘不染

在数据库中的一组记录上存储排序顺序的最有效方法是什么?

algorithm

假设使用PHP / MYSQL,但我不一定需要实际的代码,我只是对它背后的理论感兴趣。

一个很好的用例是Facebook的照相馆页面。您可以将照片拖放到页面上,这会引发Ajax事件以保存新的排序顺序。我正在实现非常相似的东西。

例如,我有一个数据库表“ photos”,其中包含大约一百万条记录:

照片 id:int,用户id:int, 相册 ID:int,排序顺序:int,文件名:varchar,标题:varchar

假设我有一张包含100张照片的相册。我将照片拖放到新位置,然后触发Ajax事件以保存在服务器上。

我是否应该将照片ID的整个数组传递回服务器并更新每条记录?假设输入验证通过“ WHERE userid=
loggedin_id”,因此恶意用户只能弄乱自己照片的排序顺序

我是否应该传递照片ID,其先前的排序索引和新的排序索引,检索这两个索引之间的所有记录,对其进行排序,然后更新其顺序?

如果在一个图库中有成千上万张照片并且更改了排序顺序,该怎么办?


阅读 664

收藏
2020-07-28

共1个答案

一尘不染

仅使用integer定义顺序的列怎么办?默认情况下,您分配的数字* 1000,例如1000、2000、3000
....,如果在1000和2000之间移动3000,则将其更改为1500。因此,在大多数情况下,您根本不需要更新其他数字。我使用这种方法,并且效果很好。您也可以使用,double但是这样就无法控制精度和舍入误差,因此请不要使用它。

因此该算法看起来像
:假设您将B移至A之后的位置。首先执行select查看记录在A旁边的顺序。如果它比A的顺序至少高出+2,则只需设置B的顺序即可介于两者之间。但是,如果仅高+1(A后面没有空格),则选择B的边界记录以查看这一边有多少空间,除以2,然后将此值加到A之间所有记录的顺序和B。就是这样!

(请注意,对于包含多个查询的任何算法,都应使用事务/锁定,因此这也适用于这种情况。最简单的方法是使用InnoDB事务。)

2020-07-28