1

個人情報の作成と更新に使用する Web フォームがあります。保存時に、すべての情報を大きな多次元JSON配列に収集します。データベースを更新する場合、情報は潜在的に 3 つの部分で構成されます。作成する新しい行、更新する必要がある行、および削除する必要がある行。これらの行は、約 5 つのテーブルにもまたがります。

私の質問はこれです。MySQL クエリにどのようにアプローチすればよいですか? 私の最初の考えは、DELETEすべてのテーブルからすべての情報を取得し、INSERTすべての新しい情報を一度にクリーンアップすることでした。他のアプローチは、3 つのクエリを実行することだと思いUPDATEます。既存の ID を持つすべてのクエリ。DELETE削除対象としてマークされたINSERTすべてのデータと、新しく作成されたすべてのデータ (既存の ID のないデータ)。

これらのアプローチのどれが最適でしょうか、またはこれを行うためのより良い方法はありますか? アドバイスをありがとう。それは有り難いです。

4

2 に答える 2

9

すべてを削除してすべてを挿入することは絶対に行わないでください。

理由:

  1. 費用がかかりすぎます。ほとんどの場合、ユーザーが編集を行います。ほんの数回の更新で、1 回の削除と 100 回の挿入を行いました。
  2. 削除時のカスケード外部キーで大混乱を引き起こします。
  3. 明らかに触れられていない場合でも、自動インクリメントフィールドを混乱させます。

unit-of-workを実装する必要があります。どの言語を使用しているかはわかりませんが、一部の言語には組み込みのサポートがあります。dot-net には DataSet があります。

基本:

  1. データベースから取得した各レコードを追跡します。各レコードのフラグを秘密裏に維持して、どれがデータベースから読み込まれたか (つまり、変更されていないか)、どれが変更されているか (更新クエリが必要)、どれが新しく追加されたかを記録します。削除されたレコードについては、別のリスト (おそらく ID) を維持します。この偉業を達成する方法は、別の議論の問題です。
  2. ユーザーが [保存] をクリックすると、データベース トランザクションが開始されます。これは厳密には現在の議論の一部ではありませんが、ほとんどの場合、同様の条件で行われます。
  3. トランザクションでは、最初に削除済みアイテムの配列をループします。それらのそれぞれに対して削除クエリを起動します。
  4. 次に、変更された項目配列をループします。変更された項目ごとに、すべての列を最新の値に更新するだけです。列の数が多すぎる (>30) 場合は、状況が少し変わります。
  5. 次に、新しく作成されたアイテムが表示されます。それらのそれぞれに対して1つのインサートを発射します。
  6. 最後にトランザクションをコミットします。

プログラミングしている言語が try/catch ブロックをサポートしている場合は、上記のすべての手順を (トランザクションの開始後に) try/catch で実行します。catch ブロックでトランザクションをロールバックします。

このアプローチはより複雑に見え、単純な削除/挿入/すべてのアプローチよりも多くのクエリを発行するように見えますが、私たちがそこにいて、それを行ってから、行われたすべてを元に戻すために眠る夜を過ごしたことを信じてください. 本当に正当化できない限り、削除/挿入の方法には決して行かないでください。

変更追跡を行う方法については、使用している言語とアプリケーションの種類に大きく依存します。dot-net の場合でも、デスクトップ アプリケーションと Web アプリケーションではアプローチが異なります。削除の追跡は簡単です。新しい挿入を追跡するように。更新マークは、そのフィールドの任意の列で編集イベントをトラップすることによって適用されます。

編集

データは約 5 つのテーブルにまたがっています。したがって、3 つのループ (削除/更新/挿入) は、テーブルごとに 1 回ずつ、5 回実行する必要があります。最初にテーブル間の関係を描きます。トップテーブルを最初に処理します。次に、トップレベルのテーブルに直接接続されているテーブルなどを処理します。テーブル間に循環関係がある場合は、特に注意する必要があります。

保存操作に対するコードは、かなり長くなりそうです。5x3=15 操作、それぞれに独自の SQL があります。これらの操作はどれも再利用可能であるとは想定されていないため、それらを別々のメソッドに入れることは無駄です。すべてが大きな手続きブロックに入ろうとしています。したがって、宗教的にコードにコメントしてください。テーブルの境界と操作をマークします。

于 2013-06-05T18:29:43.083 に答える