8

私は多対多の関係を持っており、MySQLの関連付けテーブルで実装されています。子供用のテーブルと親用のテーブルがあります。子は複数の親を持つことができ、IDとともにparent_child_link関連付けテーブルに保存されます。

子はHTMLフォームを介して更新でき、親はHTMLの複数選択にあります。データベースのレコードを更新する必要がありますが、私のソリューションはあまり効率的ではありません。これが私がしていることの擬似コードです:

  1. child_id=xの子情報を更新します
  2. child_id=xであるparent_child_link内の現在の関連付けをすべて削除します
  3. 新しい関連付けを挿入します

このソリューションはうまく機能しますが、親が変更されていない場合、たとえば子の名前のみが変更された場合、2つの不要なクエリが実行されます。これらの不要なクエリを回避するにはどうすればよいですか?複数選択の親が変更されていないかどうかを確認する方法はありますか?

もちろん、これはすでに機能しているので、この面倒なことはすべて無視できますが、可能な限り効率を維持したいと思っています。

4

4 に答える 4

10

同じ質問があり、読んでいるときに解決策を見つけました。

送信されたエントリを処理する準備ができたら、まずクエリを実行して現在の関連付けを取得し、その配列 $original_list を呼び出します。提出されたリストを $submitted_list と呼びます。

$original_list = array(3,5,7);
$submitted_list = array(1,2,3);

次に、1) 削除するアイテム (存在しない) と 2) 追加するアイテム (新しい関連付け) を把握する必要があります。両方のリストの項目には触れません。

$delete_list = array_diff($original_list, $submitted_list);
$insert_list = array_diff($submitted_list, $original_list);

foreach($delete_list as $item) {
    // delete $item from DB
}

foreach($insert_list as $item) {
    // insert item in db
}

他の人がこれが有効な解決策であると感じているかどうか知りたい.

于 2012-06-05T15:42:59.267 に答える
0

子テーブルの定義でON UPDATE CASCADEandを使用して、アプリケーション層ではなく、データベースで解決してみてください。ON DELETE CASCADE

MySQL サイトからのわずかに修正された例:

CREATE TABLE parent (id INT NOT NULL,
                     PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (id INT, parent_id INT,
                    INDEX par_ind (parent_id),
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
                      ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB;

こちらのドキュメントをご覧ください: http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

編集:多対多の関係では、次のようなものを使用できます。

CREATE TABLE parent_child_link (
                    parent_id INT NOT NULL,
                    child_id INT NOT NULL,
                    PRIMARY KEY(parent_id, child_id),
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
                      ON DELETE CASCADE ON UPDATE CASCADE,
                    FOREIGN KEY (child_id) REFERENCES child(id)
                      ON DELETE CASCADE ON UPDATE CASCADE
);

お役に立てれば。

于 2012-05-05T13:34:14.920 に答える
0

あなたの解決策は問題ありません。
あなたの場合、クエリを作成して親を取得し、変更が発生したかどうかを複数選択データで確認することで、プロセスを「最適化」できます。
次に、必要に応じて、2 つの削除クエリと挿入クエリのみを実行します。これとは対照的に、実際に親を変更すると、クエリが 2 つではなく 3 つになるということです。
したがって、親を頻繁に変更する予定があるかどうかを確認する必要があります。この場合、余分な選択クエリを避けるために、元のソリューションに固執する必要があります。
親があまり頻繁に更新されないと思われる場合は、上記の解決策を使用できます。子情報のみを更新すると、1 つのクエリのみが実行されます。親も更新すると、3 つのクエリが実行されます。
2 番目のソリューションを使用する場合、削除クエリと挿入クエリを最適化して、必要なものだけを実行することもできます (親ではない親のみを削除し、新しい親リンクのみを挿入します)。
そのためには、PHP 配列関数が役立ちます。

于 2012-05-05T13:55:07.383 に答える
0

現在の方法を維持したいが、最適化のみを行いたい場合は、クエリを IF ステートメントでラップすることができます。

お気に入り:

if ( isset ( $parent_name_change )){ // run query }

于 2012-05-06T13:47:57.570 に答える