4

これは方法論的な問題です。私はテーブルを持っていると言う

id int auto_increment primary key,
name text not null

任意の方法で注文したいエントリがいくつかあります。ページに表示される名前の順序を変更できるインターフェイスを作成できます。テーブルのエントリを読み上げると、選択した方法に従って並べ替えられます。考えられるアプローチは 3 つあります。最初のアプローチは、フィールドを追加することです

order int not null

順序を変更すると、すべての行、または少なくともすべての行を、変更している最低の順序よりも高い順序で更新する必要があります。これは、for ループで SQL ステートメントを実行する必要があるため、間違ったアプローチのように思えます。2番目のアプローチは、IDでリンクされた別のテーブルを作成することです

id int not null
order int not null

しかし、ここで同じ問題に遭遇します。名前を追加して最初に配置したい場合は、すべての行の注文エントリを変更する必要があります。id と order の間の関連付けを 1 つの列、またはフラット ファイルに保存するという 3 番目のアプローチが考えられます。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:nameおよび:sortingmysqllibによって挿入される必要があります

于 2013-02-19T18:44:47.493 に答える
0

Order は予約語であるため、「重み」int を使用できます。絶え間ない更新を回避するには、エラーを防ぐために何らかのロジックをコーディングする必要がありますが、デフォルトの重みの増分を 1 以外のままにしておくと、他のアイテムの間に物を入れることができます。

いいえ:

id 重量アイテム

1 1 何か

2 10 何かその他

2 つの間に何かを追加します。

id 重量アイテム

1 1 何か

3 5 someOtherThing

2 10 何かその他

確かに、2 番目のテーブルまたはより単純な構造の方が、エラーが発生しにくくなります。

于 2013-02-19T18:40:03.447 に答える