web-dev-qa-db-ja.com

「ON UPDATE CASCADE」を使用する場合

私は定期的に "ON DELETE CASCADE"を使っていますが、どのような状況で役に立つのかよくわからないので "ON UPDATE CASCADE"は使いません。

議論のためにいくつかのコードを見てみましょう。

__コード__

"ON DELETE CASCADE"の場合、idを持つ親が削除されると、CREATE TABLE parent ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ); CREATE TABLE child ( id INT NOT NULL AUTO_INCREMENT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ); を持つ子のレコードは自動的に削除されます。これは問題ないはずです。

  1. これは、親のidが更新されたときに "ON UPDATE CASCADE"が同じことをすることを意味しますか?

  2. (1)が真であれば、parent_id = parent.idparent.idである場合や常にTIMESTAMPに設定されている場合のようにAUTO_INCREMENTが更新可能でない(または更新されない)場合は、 "ON UPDATE CASCADE"を使用する必要はありません。その通りですか?

  3. (2)が当てはまらない場合、他のどのような状況で "ON UPDATE CASCADE"を使用すべきですか?

  4. 何らかの理由でchild.parent_idを存在しないものに更新した場合、自動的に削除されますか?

私が知っているように、上記の質問のいくつかは理解するためにプログラム的にテストすることができますが、これのどれかがデータベースベンダに依存しているかどうかも知りたいです。

少し光を当ててください。

381
NawaMan

主キーが単なるID値の自動増分である場合、ON UPDATE CASCADEを実際に使用することはできません。

ただし、主キーは10桁のUPCバーコードであり、拡張のため、13桁のUPCバーコードに変更する必要があるとしましょう。その場合、ON UPDATE CASCADEを使用すると主キー値を変更でき、その値への外部キー参照を持つテーブルはそれに応じて変更されます。

#4を参照して、子IDを親テーブルに存在しないものに変更した場合(および参照整合性がある場合)、外部キーエラーが発生するはずです。

429
C-Pound Guru
  1. そうです、例えば、もしあなたがUPDATE parent SET id = 20 WHERE id = 10すべての子のparent_idが10なら、20も更新されるということです。

  2. 外部キーが参照するフィールドを更新しないのであれば、この設定は必要ありません。

  3. 他の用途は考えられません。

  4. 外部キー制約が失敗するため、それはできません。

78
Zed

私はあなたがほとんどポイントを決めたと思います!

データベース設計のベストプラクティスに従い、あなたの主キーが決して更新可能でない場合(私は常にそうであるべきだと思います)、あなたは本当にON UPDATE CASCADE節を必要としません。

Zedは、ナチュラルキーを使用した場合は、たとえば、データベーステーブルの通常のフィールドを主キーとして使用している場合は、主キーを更新する必要がある場合があります。もう1つの最近の例は、ISBN(国際標準図書番号)で、10桁から13桁の数字に変更されました。

主キーとして代理(例:人工的にシステム生成された)キーを使用することを選択した場合は、これは当てはまりません。しかし、最も稀な機会です。

つまり、結局のところ、主キーが変更されないのであれば、ON UPDATE CASCADE句は必要ありません。

マーク

27
marc_s

数日前、私はトリガーに関する問題を抱えていました、そして私はON UPDATE CASCADEが役に立つことができると考えました。この例(PostgreSQL)を見てください。

CREATE TABLE club
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE band
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE concert
(
    key SERIAL PRIMARY KEY,
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE,
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE,
    concert_date DATE
);

私の問題で私はコンサートのテーブルを更新するためにいくつかの追加の操作(トリガー)を定義しなければなりませんでした。これらの操作はclub_nameとband_nameを修正する必要がありました。参考のため、できませんでした。私はコンサートを修正してからクラブやバンドのテーブルを扱うことができませんでした。他の方法でもできませんでした。 ON UPDATE CASCADEが問題を解決するための鍵でした。

15
Ariel Grabijas

私のコメントは主にポイント#3を参照しています。親キーが更新可能でないと仮定した場合、どのような状況下でON UPDATE CASCADEが適用可能ですか?これが1つのケースです。

私は複数の衛星データベースをマスターとマージする必要があるという複製シナリオを扱っています。各サテライトは同じテーブルにデータを生成しているため、テーブルをマスターにマージすると一意性制約に違反します。私はそれぞれのマージ中にキーを再インクリメントするソリューションの一部としてON UPDATE CASCADEを使用しようとしています。 ON UPDATE CASCADEは、プロセスの一部を自動化することによってこのプロセスを単純化します。

4
ted.strauss

それは素晴らしい質問です、私は昨日同じ質問をしました。私はこの問題について考えました。具体的には "ON UPDATE CASCADE"のようなものがあった場合は検索し、幸いSQLの設計者もそれについて考えていました。私はTed.straussに同意します、そしてまた私はNoranの訴訟についてコメントしました。

いつ使用しましたか。 Tedが指摘したように、一度に複数のデータベースを処理していて、そのうちの1つを1つのテーブルに変更すると、Tedが「サテライトデータベース」と呼んでいるものに何らかの種類の再現があるIDなど、何らかの理由で、古いもののデータを更新できない場合(たとえば、アクセス権が原因で、または非常に短期間の場合は堅牢性を探している場合)に、新しいものを作成する必要があります。正規化の規則全体を絶対的かつ完全に尊重する価値はありません。これは単に非常に短命なユーティリティになるからです)

だから、私は2つの点で同意する:

(A.)はい、多くの場合、より良い設計でそれを回避できます。しかし

(B.)移行、データベースの複製、または緊急事態の解決の場合、それが存在していたならば、検索に行ったときに幸運にもそこにいたのはGREAT TOOLです。

3
David L