1

我在创建一个用于在 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 查询中更新或记录以使数字连续

优点:无需阅读关于下一条/上一条记录的任何内容。每次移动后,我们确信“排序”数字会正常。我们可以在 Sort 上使用 UNIQUE。

缺点:在巨大的表中,分配新的排序号需要大量的 CPU 时间。我对吗?我们还有与 Id 不同类型的“排序”...

  • 和上一个类似
    • 从 / 减去 / 加 1 到我们要移动的记录。
    • 使用我们的 Id 作为第二个排序参数,通过查询分配连续的数字。

优点:与上面相同,但无法使用 UNIQUE。但是我们有与 Id 相同类型的“排序”

缺点:有一段时间,两条记录都具有相同的“排序”,CPU 使用率高(?)

到目前为止,这些是我所知道的最好的方法。你们中的任何人都知道其他人,将所有优点联系起来并且没有缺点吗?

感谢您的重播。

4

1 回答 1

0

您需要对要移动的记录进行 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? 处删除了一个空格?

然后是最后一个查询,为移动的记录设置新的排序索引。

即使您的索引稀疏(即有孔),后一种方法也有效,因此请记住这一点。

于 2013-09-02T14:31:19.467 回答