4

这更像是一个方法论问题。说我有一张桌子

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 执行此操作的最佳方法是什么。

4

2 回答 2

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);

看它工作

:id的值应该由你的 mysql 库插入:name:sorting

于 2013-02-19T18:44:47.493 回答
0

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

IE:

id 重量项目

1 1 东西

2 10 其他

在两者之间添加一些东西:

id 重量项目

1 1 东西

3 5 someOtherThing

2 10 其他

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

于 2013-02-19T18:40:03.447 回答