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


420

私は「ON DELETE CASCADE」を定期的に使用していますが、「ON UPDATE CASCADE」を使用することはありません。

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

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
);

「ON DELETE CASCADE」の場合、を持つ親idが削除されると、を持つ子のレコードはparent_id = parent.id自動的に削除されます。これは問題ありません。

  1. これはid、親の更新時に「ON UPDATE CASCADE」が同じことを行うことを意味しますか?

  2. (1)がtrueの場合、parent.id更新可能でない(または更新されない)場合AUTO_INCREMENTや、常にに設定されている場合は、「ON UPDATE CASCADE」を使用する必要がないことを意味しますTIMESTAMP。そうですか?

  3. (2)が真でない場合、「ON UPDATE CASCADE」をどのような状況で使用する必要がありますか?

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

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

光を当ててください。


回答:


468

主キーが自動インクリメントされるID値だけの場合は、ON UPDATE CASCADEを実際に使用することはできません。

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

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


6
ON UPDATE CASCADE自動インクリメントキーを使用しない古いテーブルの主キーを更新するために自分自身を使用する必要がありました
BlueRaja-Danny Pflughoeft

86
  1. はい、たとえば、UPDATE parent SET id = 20 WHERE id = 10すべての子を実行すると、10のparent_idも20に更新されます

  2. 外部キーが参照するフィールドを更新しない場合、この設定は不要です

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

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


29

ポイントはほぼ達成されたと思います!

データベース設計のベストプラクティスに従い、主キーが更新可能でない場合(とにかく常にそうであると思います)、そのON UPDATE CASCADE句は本当に必要ありません。

自然なキー(データベーステーブルの通常のフィールドなど)を主キーとして使用する場合、主キーを更新する必要がある特定の状況が発生する可能性があることをZedが指摘しました。最近のもう1つの例は、ISBN(国際標準図書番号)で、10桁から13桁+文字に変更されたのはそれほど昔ではありません。

これは、代理キー(たとえば、システムで生成されたもの)を主キーとして使用することを選択した場合には当てはまりません(ほとんどの場合を除いて、これが私の推奨される選択です)。

したがって、最終的には、主キーが変更されない場合は、ON UPDATE CASCADE句は必要ありません。

マーク


「人工的にシステムが生成した」キーとは何ですか?UUID?
HPWD 2018年

1
@HPWD:システムによって生成されただけで、「人工」キー(に基づいて、またはあなたの実際のデータから導出されていない値) -それはすることができ、本当にか何か- - GUID、またはINT、またはBIGINTのdoesn関係ない。ポイントは、その値はあなた自身の実際のデータとはまったく関係がなく、システムがその値を自動的に生成しているということです。
marc_s 2018年

@ marc-sは、時間をかけてそれを書いてくれてありがとう。あなたの答えは完璧な意味がありました。
HPWD 2018年

2
自然なキーを持つ単一列のテーブルは、(少なくともMySQL DBフレーバーでは)私の見解では、列挙型の優れたクリーンな代替手段です。たとえば、表を考えるcolors行とbluepurpleyellow、、テーブルproductsproduct_colorにFK'edされるカラム、colorsテーブル。これは列挙型のような選択を制限しますが、自動インクリメント整数とは異なり、色名を取得するために結合を必要としません。そのような場合、代わりに呼び出す必要があるとon update cascade判断した場合は、良い考えです。purpleviolet
okdewit

18

数日前、トリガーに問題があり、それ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問題を解決する鍵でした。


3
良いコメント。アップデートカスケードも便利です。いずれにしても、IDを変更する必要があります。私はまた、この変更がそれほど典型的であってはならないことについて他の人々にも同意します。たとえば、引用した場合、大量のデータでは、おそらくテキストフィールドを使用して外部キーを関連付けると、データベースエンジンのパフォーマンスが最速にならない可能性があると思います。コンサートテーブルの外部リレーションがclub.SERIALとband.SERIALを使用している場合、名前の変更がテーブル間のリレーションに影響しないことに注意してください。ただし、ON UPDATE CASCADEは緊急事態を解決するための優れたツールです。よろしくお願いします
デビッドL

4
これは疑わしいデザインですが、かなり不自然な例です。各テーブルの主キーの代わりにs を参照する場合、2つのSERIAL列を主キーとして保持する意味は何ですか?clubbandname
sm

つまり、他のテーブルからフィールドを複製していて、それを最新にする必要がある場合に、これは便利です。
カミルトムシク

4

私のコメントは主にポイント#3に関連しています:親キーが更新可能でないと想定している場合、どのような状況でON UPDATE CASCADEが適用されますか?ここに1つのケースがあります。

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


3

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

いつ使用しましたか?Tedが指摘したように、一度に複数のデータベースを処理していて、そのうちの1つ、1つのテーブルを変更すると、Tedが「衛星データベース」と呼んでいるものになんらかの複製があり、非常に元のデータベースでは維持できません。 ID、および何らかの理由で古いもののデータを更新できない場合(たとえば、権限が原因で、または非常に短命である場合に堅牢性を検索している場合)非常に短命なユーティリティになるという理由だけで、正規化の全体的なルールを絶対的かつ完全に尊重する価値はありません)

したがって、私は2つの点で同意します。

(A.)はい、多くの場合、優れた設計はそれを回避できます。だが

(B.)移行、データベースの複製、または緊急事態の解決の場合、それが存在するかどうかを検索したときに幸いにもそこにあったのは素晴らしいツールです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.