这更多的是一个方法论问题。假设我有一张桌子
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多岁的其他
诚然,第二个表或更简单的结构不太容易出错。