这更像是一个方法论问题。说我有一张桌子
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执行此操作的最佳方法是什么。
答案 0 :(得分:8)
是的,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);
您的mysql lib应插入:id
,:name
和:sorting
的值
答案 1 :(得分:0)
你可以使用“weight”int,因为Order是一个保留字。至于避免不断更新,你必须编写一些逻辑来防止错误,但如果你保留默认的权重增量不是1,你可以把东西放在其他项目之间。
IE:
id weight item
1 1件事
2 10 somethingElse
在两者之间添加一些东西:
id weight item
1 1件事
3 5 someOtherThing
2 10 somethingElse
当然,第二个表或更简单的结构不易出错。