我在创建用于在 MySQL 数据库中上移/下移记录的函数时遇到了问题。我当前的表如下所示:
Id UNSIGNED INT AI PRIMARY | Some other columns | Sort UNSIGNED INT INDEX
假设我有一些数据:
1 | FirstRecord | 1
2 | Second | 2
3 | Third | 3
4 | 4th | 4
Much more data...
在对“Id = 4”执行“向上移动”操作后,我希望“Id = 4”获得“Id @above”的“排序”,“Id @above”获得“Id = 4”的“排序”
我在开始时有什么:
- 我要移动的记录ID
- 我要移动的方向(上/下)
我到底想拥有什么
- 我的记录向上或向下移动(交换“排序”值)
- “排序”列中的连续数字
我想怎么做
- 因为我使用的是 php5.4 我可以使用这种语言的一些代码,而不仅仅是纯 sql
- 我必须为高负载和同时请求做好准备
- 我不想创建 MySQL 过程或函数。最好的方法是在一个简单的查询中完成
我尝试过的
- 最简单的方法是使用 php 和:
- 获取当前 Id 的“排序”(第一个查询)
- 查找上方/下方列的 ID(第二个查询)
- 获取此列的“排序”(第三次查询)
- 交换“排序”值(第 4 和第 5 个查询)
优点是这种方法非常简单,我认为仅此而已。
缺点 是暂时两行具有相同的“排序”值。另一个是当2个脚本同时运行时,结果可能是不可预测的。同样删除任何一条记录后,会出现计算漏洞。
- 比较复杂,也是用php
- 将“排序”更改为 FLOAT(在开始时,而不是每次)
- 从记录中减去或添加 1.5。
- 在SQL查询中更新或记录,使数字连续
优点:无需阅读关于下一个/上一个记录的任何内容。在每次移动之后,我们确信“排序”数字是可以的。我们可以在排序时使用 UNIQUE。
缺点:在巨大的表中分配新的排序编号会占用大量 CPU 时间。我对吗?我们还有与 Id 不同类型的“排序”...
- 与上一个相似
- 从/中减去/加 1 到我们要移动的记录。
- 使用我们的 Id 作为第二个排序参数,通过查询分配连续的数字。
优点:同上,但无法使用 UNIQUE。但是我们有与 Id 相同类型的“排序”
缺点:有一段时间两条记录具有相同的“排序”,CPU 使用率高(?)
到目前为止,这些是我所知道的最好的方法。你们中有人认识其他人吗,把所有的优点都联系起来,没有缺点?
感谢您的回放。
最佳答案
您需要对要移动的记录进行 1 次查询才能获得排序索引。然后,您应该将新的排序索引作为排序 UI 的输入。
如果您只是交换两个项目,您可以在一个查询中完成:
UPDATE table SET sort_index = IF(id === ?id?, ?new_sort_index?, ?old_sort_index?) WHERE id = ?id? OR sort_index = ?new_sort_index?
使用 IF
一次更新两条记录。
如果您可以将一个项目移动到许多地方,您需要进行范围更新。首先弄清楚方向:向上/向下。然后执行如下查询:
UPDATE table SET sort_index = sort_index + 1 WHERE sort_index >= ?new_sort_index? AND sort_index < ?old_sort_index?
这在 ?new_sort_index? 处创建了一个空间并在 ?old_sort_index? 处删除了一个空格
然后最后一个查询为移动的记录设置新的排序索引。
即使您的索引稀疏(即存在空洞),后一种方法也有效,但前者无效,因此请记住这一点。
关于php - 在按列表排序的表中移动记录的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18575360/