使用MySQL和PHP进行用户定义的排序


User defined ordering using MySQL and PHP

这更多的是一个方法论问题。假设我有一张桌子

id int auto_increment primary key,
name text not null

我有许多条目,我想以某种任意的方式订购。我可以创建一个界面,允许我更改名称在某个页面上显示的顺序。当我读出表格中的条目时,它们会根据我的选择进行排序。我认为有三种可能的方法。第一种方法是添加一个字段

order int not null

当我更改顺序时,我必须更新每一行,或者至少每一行的顺序都高于我正在更改的最低顺序。这似乎是错误的方法,因为它需要在for循环中执行SQL语句。第二种方法是创建另一个表,通过id 链接

id int not null
order int not null

但我在这里也会遇到同样的问题。如果我添加了一个名称并想把它们放在第一位,我将不得不更改每行中的订单条目。我可以看到第三种可能的方法,即将id和order之间的一些关联存储在一列中,甚至存储在一个平面文件中。我可以看到使用JSON格式来实现这一点。

我的问题是。使用MySQL和PHP最好的方法是什么。

是的,sorting列工作正常。你不需要for循环。

执行插入操作时,首先递增其他排序值。

UPDATE foo
  SET sorting = sorting + 1
  WHERE sorting >= :sorting;
INSERT INTO foo
  SET name = :name, sorting = :sorting;

让它发挥作用

更新时,将特定记录的sorting列设置为新索引,并递增/递减其他记录的sorting,以形成有效序列。

SELECT @old_sorting:=sorting FROM foo WHERE id = :id;
UPDATE foo
  SET sorting = IF(id = :id, :sorting, sorting + IF(@old_sorting > :sorting, 1, -1))
  WHERE sorting BETWEEN LEAST(@old_sorting, :sorting) AND GREATEST(@old_sorting, :sorting);

让它发挥作用

:id:name:sorting的值应由您的mysql-lib

插入

您可以使用"weight"int,因为Order是一个保留字。至于避免不断更新,你必须编写一些逻辑来防止错误,但如果你把默认的权重增量保留为1以外的值,你可以把东西放在其他项目之间。

IE:

id重量项目

11岁左右的

2个10多岁的其他

添加介于两者之间的内容:

id重量项目

11岁左右的

3.5其他时间

2个10多岁的其他

诚然,第二个表或更简单的结构不太容易出错。