-1

2つのテーブルのデータベースに保存されている従来の販売注文について考えてみます。

SALE_ORDER                   SALE_ORDER_ITEM
----------                   ---------------
id       integer             ...
...                           order_id        integer references sale_order (id)
                              item_id         integer references item (id)
                              quantity        integer
                              ...

この質問の目的のために、別のテーブルへのitem_id参照を無視してください-それは無関係です。

次のような注文を含むクラスがあります。

public class SaleOrder {
    private int orderId;
    ...
    private List<BoughtItem> items;
    ....
}

注文は変更される可能性があり(私の要件)、変更にはリスト内のアイテム(追加、削除、または数量変更)が含まれる可能性があります。データベースでこの順序を更新するとき、最も簡単な方法はdelete from sale_order_item where order_id=<my_order_id>、リストを通過する行を挿入することです。ただし、これは、特にリストに(潜在的に)何百もの異なるアイテムが含まれている可能性があることを考えると、非常に非効率に思えます。(背景:これらはスーパーマーケットから卸売製品サプライヤーへの注文です。)

別の方法は、データベースにクエリを実行してから、リストをカーソルと比較し、必要に応じて追加、削除、または更新することです。これは、少なくとも同じように非効率的です。

  1. より効率的な別の(3番目の?)アプローチはありますか?
  2. そうでない場合は、2つのうちどちらが優れていますか?私はいつも最初のものを使用しました(すべて削除してから再挿入しますが、今は自分自身を疑うようになりました。

更新:データベースはsqlite3です(それが重要な場合はAndroid上で)

4

4 に答える 4

0

アイテムIDの元のリストがない場合は、リストに含まれなくなったアイテムを少なくともすべて削除する必要があります。

DELETE FROM sale_order_item
WHERE order_id = ?
  AND item_id NOT IN (id1, id2, ...)

レコードが変更されたかどうかがわからない場合は、レコードの更新を避けることはできません。

ただし、既存のレコードの挿入を回避することは可能です。(order_id、item_id)列に適切な主キーがある場合は、INSERT OR REPLACEコマンドを使用できます。

ただし、これはすべて、単純なものよりも効率的ではありませDELETEINSERT

于 2013-01-17T18:50:38.833 に答える
0

まだ持っていない場合は、sale_order_itemにPKが必要です。

データベースを更新するときに再生できるダーティバッファを保持します。したがって、ユーザーがアイテムを変更した場合は、エントリ'update sale_order_item set item_id = "1234" where sale_order_item.id="2222"'を追加します。

次に、データベースとの通信に関しては、それらの変更を再生します。変更をどのように記録するかは重要ではありません(SQLの記録は最も効率的ではありません)。重要なのは、各アイテムの変更点、またはアイテムの追加/削除を認識し、それに基づいてSQLを作成できることです。

それがあなたにアイデアを与えることを願っています。

于 2013-01-17T17:40:29.303 に答える
0

アイテムを更新するか、単に再挿入するかによって大きく異なります。更新を行う必要がない場合は、既存の項目を句に追加すると、削除 + 挿入で問題ありません (したがって、新しいリストにあるものを削除しません)。

新しいリストが常にゴールデンである場合、既にデータがあるため、カーソルを使用しても意味がありません。削除/再挿入に固執してください。カーソルほど非効率的ではありません。

例: t-sql

insert into sale_order_item(columns..)
select field1, 2, etc. from your_new_list a 
where not exists (select 1 from sale_order_item where item_id = a.item_id)
于 2013-01-17T17:42:36.003 に答える
0
  1. フィールド recordState を追加: enum {rfNone, rfInserted, rfUpdated, rdDeleted}.
  2. 次のような適切なコードをすべてのセッター メソッドに追加します。

    public void setData(String value) {
        if (!this.data.equals(value)) {
            this.data = value;
            if (getRecordState() == rfNone)
                setRecordState(rfUpdated);
        }    
    }
    

    このコードは、レコード クラスのいずれかの値が変更された場合にレコード オブジェクトを更新済みとしてマークすることを保証します。もちろん、このオブジェクトが新しく構築されていない場合

  3. データベースから読み取られるすべてのレコードは、initialy である必要があります: recordState = rfNone

  4. 新しく追加されたレコードはマークする必要があります: 作成時に recordState = rfInserted
  5. 削除されたレコードは、次のようにマークする必要があります: recordState = rfDeleted (すぐに削除しないでください)
  6. 最後に、レコード オブジェクトのリストをトラバースし、recordState 値に基づいて適切なアクションを実行します。
于 2014-04-16T12:11:25.727 に答える