71

過去数年間に何度も遭遇した問題に対して、誰かが良い解決策を持っているかどうか疑問に思っていました。

私はショッピング カートを持っていますが、顧客はその注文が重要であることを明示的に要求しています。したがって、注文をDBに永続化する必要があります。

明らかな方法は、番号 0 を N に割り当て、そのように並べ替える OrderField を挿入することです。

しかし、そうすると再注文が難しくなり、この解決策は壊れやすく、いつか戻ってくるだろうと感じています。

(NHibernate と SQL Server 2005 で C# 3,5 を使用しています)

ありがとうございました

4

12 に答える 12

50

これは、このスレッドに沿って発生した誰にとってもプログラミングを簡単にするための私の解決策です。トリックは、1 回の更新で挿入/削除の上または下のすべての注文インデックスを更新できることです。

SQL クエリでサポートされている、テーブル内の数値 (整数) 列の使用

CREATE TABLE myitems (Myitem TEXT, id INTEGER PRIMARY KEY, orderindex NUMERIC);

orderindex 6 のアイテムを削除するには:

DELETE FROM myitems WHERE orderindex=6;    
UPDATE myitems SET orderindex = (orderindex - 1) WHERE orderindex > 6;

2 つのアイテム (4 と 7) を交換するには:

UPDATE myitems SET orderindex = 0 WHERE orderindex = 4;
UPDATE myitems SET orderindex = 4 WHERE orderindex = 7;
UPDATE myitems SET orderindex = 7 WHERE orderindex = 0;

つまり、0 は使用されないため、あいまいな項目を避けるためにダミーとして使用します。

3 に挿入するには:

 UPDATE myitems SET orderindex = (orderindex + 1) WHERE orderindex > 2;
 INSERT INTO myitems (Myitem,orderindex) values ("MytxtitemHere",3)
于 2012-04-27T19:26:08.620 に答える
32

最善の解決策は、二重リンクリストです。インデックス付けを除くすべての操作のO(1)。必要なアイテムのwhere句を除いて、SQLのインデックスをすばやく作成することはできません。

0、10、20タイプは失敗します。シーケンス列のものは失敗します。フロートシーケンス列はグループ移動で失敗します。

二重リンクリストは、追加、削除、グループ削除、グループ追加、グループ移動の同じ操作です。単一のリンクリストも問題なく機能します。私の意見では、SQLの方がダブルリンクの方が優れています。単一のリンクリストでは、リスト全体が必要です。

于 2011-03-31T18:03:48.797 に答える
25

FWIW、あなたが提案する方法(つまり、注文をデータベースにコミットする)は、問題の悪い解決策ではないと思います。また、おそらく最も安全で信頼できる方法だと思います。

于 2008-12-01T10:45:09.580 に答える
10

リンクされたリストの実装を使用するのはどうですか? 1 つの列があると、次のアイテムの値 (注文番号) が保持されます。間にオーダーを挿入する場合は、これが最も使いやすいと思います。番号を付け直す必要はありません。

于 2010-02-19T01:09:17.717 に答える
5

残念ながら、これに対する特効薬はありません。SELECTorder by 句がないと、ステートメントの順序を保証できません。列を追加し、その周りにプログラムする必要があります。

リストのサイズとサイトのヒット数によっては、注文シーケンスにギャップを追加することをお勧めするかどうかはわかりませんが、ロジックを処理するオーバーヘッドはほとんど得られない可能性があります (まだ必要です)。すべてのギャップが使い果たされた場合に対応するため)。これがあなたの状況にどのような利益をもたらすかを詳しく見ていきます。

申し訳ありませんが、これ以上のものを提供することはできません。

于 2008-12-01T10:54:11.573 に答える
3

A、AA、B、BA、BBのアプローチはまったくお勧めしません。階層を決定するために多くの余分な処理が必要であり、その間にエントリを挿入することはまったく楽しいことではありません。

OrderField、整数を追加するだけです。ギャップを使用しないでください。ギャップを使用しないでください。次の中間挿入で非標準の「ステップ」を使用するか、最初にリストを再同期してから新しいエントリを追加する必要があります。

0 ... Nを指定すると、並べ替えが簡単になります。SQLの外部で配列メソッドまたはリストメソッドを使用してコレクション全体を並べ替えることができる場合は、各エントリを更新するか、挿入先を特定できます。それに応じて、エントリの前後に各エントリを+1または-1します。

小さなライブラリを作成したら、それは簡単なことです。

于 2008-12-02T18:59:34.870 に答える
1

私は次のように実用的に解決しました:

  1. 順序は UI で定義されます。

  2. バックエンドは、リスト内のすべての項目の ID と対応する位置を含む POST 要求を取得します。

  3. トランザクションを開始し、すべての ID の位置を更新します。

終わり。

したがって、順序付けにはコストがかかりますが、順序付けられたリストの読み取りは非常に安価です。

于 2015-07-21T12:47:51.680 に答える
1

カート項目の上の抽象化のレベルでは、CartOrder (CartItem と 1-n を持つ) としましょう。itemOrder というフィールドを維持できます。それを解析し、それに応じて項目モデルを配置する必要があるのは、アプリケーション層になります。このアプローチの大きな利点は、注文の再編成の場合です。個々のオブジェクトには変更がない可能性がありますが、注文は注文アイテム テーブルの行内のインデックス フィールドとして保持されるため、それぞれに対して更新コマンドを発行する必要があります。インデックス フィールドを更新する行。このアプローチに対するあなたの批判を教えてください。これがどのように失敗するか知りたいです。

于 2009-08-03T07:19:09.453 に答える
1

注文フィールドを挿入するだけです。最も簡単な方法です。顧客がフィールドを並べ替えることができる場合、または途中で挿入する必要がある場合は、そのバッチ内のすべてのアイテムの注文フィールドを書き換えるだけです.

挿入と更新のパフォーマンスが低いためにこの制限が発生する場合は、整数ではなく varchar フィールドを使用できます。これにより、挿入時の精度が非常に高くなります。たとえば、アイテム 'A' と 'B' の間に挿入するには、'AA' として注文されたアイテムを挿入できます。ただし、これはほぼ間違いなく、ショッピング カートにとってやり過ぎです。

于 2008-12-01T11:38:14.013 に答える
0

注文番号に隙間を空けることをお勧めします。1、2、3 などではなく、10、20、30 を使用してください。もう 1 つのアイテムを挿入する必要がある場合は、すべてを並べ替えるのではなく、15 に設定できます。その時点で。

于 2008-12-01T10:47:59.730 に答える
0

ええと、簡単な答えは次のとおりです。

cartcontents テーブルに autoidentity の主キーを作成し、正しい上から下の順序で行を挿入します。次に、主キー autoidentity 列による順序でテーブルから選択すると、同じリストが得られます。これを行うと、カートの内容が変更された場合に備えて、すべてのアイテムを削除してから再挿入する必要があります。(しかし、それはまだかなりきれいな方法です)それが不可能な場合は、他の人が提案したように注文列を使用してください.

于 2008-12-01T11:48:59.030 に答える
-1

を使用していHibernateて、 a の順序を保存する必要がある場合は、 ではなく a@OneToManyを使用します。MapList

@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL)
@MapKey(name = "position")
@OrderBy("position")
private Map<Integer, RuleAction>    actions             = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this }));

この Java の例では、positionは の Integer プロパティであるRuleActionため、順序はそのように保持されます。C# では、これはかなり似ていると思います。

于 2014-12-25T19:01:51.033 に答える