記事: 1-3、4-6、7-9、10-13、14-15
この記事の情報は、マニュアルの5番目の部分を参照しています。
コメントでは、ユーザーの1人が理由もなくカスケードデータの削除に関する情報の欠如を非難しました。 ギャップを埋めます。 記事の著者はこのトピックに関する情報を持っていないので、私はそれについて短い記事を書きました。 指定されたサイクルに論理的に適合します。
まず、混乱が生じないように、カスケードデータの削除だけでなく、カスケードデータの削除が含まれる参照整合性と外部キーのトピックについても話していることは価値があります。
はじめに
データベースを開発する人の哲学的な立場から始めると、外部キーは便利で生活を簡素化します(ほとんどの場合、常に例外があります)。 データベースのリレーショナル理論に無知であっても、その開発の特定の段階で外部キーを使用する必要性は、開発にまだとどまって考え続けているほとんどすべての開業医(声明は初心者を指します)にもたらされます。 必要なものが外部キー関係と呼ばれることをまだ知らない場合でも、特定の方法でデータを独立して整理し、別々のテーブルに分割し、それらをリンクし始めます。 それで明らかになります。
ただし、外部キーを使用する場合、そのような定義がわからなくても、接続されているデータを監視する必要があります。 この記事の主題は、私がそう言うかもしれないが、そのようなデータ編成に従う一種の衛星です。 この場合、理論を知ることははるかに便利です。なぜなら、 これにより、データベースを操作するプロセスの寿命が大幅に簡素化されます。
ポイントに近い。
翻訳で伝えられた外部キーについては、これにこだわらない。 「衛星」について説明します。
理論がわからない場合は、自分でデータの関係に従う必要があります。 別の方法は、このタスクをデータベースに配置することです。 いわゆるデータリンクの追跡とは何ですか? 理解するには、例が必要です。
いくつかあります。 それらは散在しており、それらの多くがあります。 整理整頓をしたいのです。 注文は、多くの場合、分類(分類)および在庫です。 私たちは秩序が欲しいのですが、データベースを扱うことができ、紙に何かを書きたくないのです。 すべてのものを列に書きます。 次に、リストを見て、物が属するカテゴリを決定します。
これを私たちのものの一部としましょう、残りは考慮されません:
- ブック1
- ブック2
- ブック3
- コンピューターのマウス
- キーボード
- ペン
- ホッチキス
私たちは以下を決定します:
本1、本2、本3は、奇妙なことに本です。
コンピューターのマウス、キーボードはコンピューターの周辺機器です。
ペン、ホッチキスは文房具です。
データベースに2つのテーブル、 category(categories)とstuff(things)を作成します。
カテゴリー
category_id | お名前
1 | 本
2 | コンピュータ周辺機器
3 | 文房具
スタッフ(スタッフ)
stuff_id | category_id | お名前
1 | 1 | ブック1
2 | 1 | ブック2
3 | 1 | ブック3
4 | 2 | コンピューターのマウス
5 | 2 | キーボード
6 | 3 | ペン
7 | 3 | ホッチキス
habrastorage.orgからのPSイメージは表示されません。
合計:本、コンピューター周辺機器、文房具があります。
私たちはすべての本を捨てるか寄付したかったのです。これらのことを家庭のカテゴリーとして見たくはありません。電子書籍が好きです。 カテゴリテーブルから「books」カテゴリを削除します。 同時に、別のテーブルにこのカテゴリの項目がまだあります。これらのカテゴリを項目のテーブルで参照します。 これは、 参照整合性違反と呼ばれます 。 カテゴリがないため、書籍はないように思われますが、物事表のエントリは残り、多くの物事があり、将来、状況が再発する可能性があり、その後、混乱、多くの不要な情報、およびすべての結果が発生します情報を扱う際の利便性と、データベースを扱う際の技術的な部分(情報検索など)の両方で。 ここで、2つのテーブルを操作する必要があるという理解があります。どの場合に接続が壊れ、壊れて、ある種の身体の動きをするかを監視し、2つのオプションがあります。データベースの頭痛。
リレーショナルデータモデル内では、カテゴリテーブルは祖先であり、物事テーブルは子孫です。 ここでは、親と子としてすべてが明確です。 さらに、接続が切断される可能性のあるケースも特定されます(私たちが採用しています)。 私たちの場合だけではありません。
次の場合、関係が壊れる可能性があります(「正しい」言語を言うと、参照整合性が壊れる可能性があります)。
- 子孫行で外部キーが更新されます(カテゴリテーブルの識別子へのリンク)。 何らかの理由でカテゴリ(このカテゴリの番号、識別子)を更新していますが、そのようなカテゴリは存在しません。 そして...空中にぶら下がっているものがあります。
- 新しい子孫行が追加されます。 新しいものを追加してください。それはどのカテゴリにも属していません。 ところで、何もせずにカテゴリを追加できます。 私たちのデータベースは、モノがカテゴリーなしで存在することはできないように配置されています。
- 祖先文字列を削除します。 これがまさに私たちのケースで起こったことです。 カテゴリを削除しましたが、物事は残りました。
- 祖先文字列の主キーを更新します。 カテゴリ識別子を変更し、特定のものは以前の識別子を参照しています。 結論:いくつかの問題が再び発生しています。
SQLの参照整合性を維持する手段( 必要に応じてすぐに理解します。MySQLRDBMSについて話す場合、これらのツールを外部キーと一緒に使用できるのはInnoDBテーブルのみです。外部キーはMyISAMで使用でき、特定のデータ構造を作成しますが、通信を追跡するためのすべての頭痛の種はユーザーにあります )、これらのケースを処理できます。
そして、これらの問題を解決する方法を以下に示します(リスト順)。
- 更新時に、新しい外部キー値が子テーブルでチェックされます。 指定された値が祖先テーブルの主キーに含まれていない場合、エラーが返されます。
私たちの場合、モノのカテゴリ番号を変更しても、存在しません。 - 新しい子行を追加するとき。 示された外部キー値が祖先テーブルの主キー間に存在しない場合、エラーが返されます。
私たちの場合、モノを追加し、存在しないカテゴリ番号を指定した場合。
今最後の2つ。 ここで状況はより興味深いです。
- 祖先行を削除します。 私たちの場合、カテゴリを削除すると、事物の表でそれが参照されます。 この問題にはいくつかの解決策があります。 それらのどれがデータベース開発者によって決定されます(指定します)。
1)カテゴリを削除するとき、それに関連するすべてのものを削除できます。
2)カテゴリを参照している間はカテゴリの削除を禁止する。
3)削除するカテゴリーを参照するものについては、カテゴリーへの参照としてNULL値を指定します。
4)削除するカテゴリを参照するものについては、NULL以外のデフォルト値を指定します。
- 先祖文字列の主キーを更新する場合、前のものと同じオプション。
さて、冒頭で述べたカスケードデータの削除について。
SQLで削除および(または)更新のルールを定義する場合、特定の構文構造が使用されます。
FOREIGN KEY [key_name] (col1, …) REFERENCES table (table_col, …)
[ON DELETE {CASCADE|SET NULL|NO ACTION|RESTRICT|SET DEFAULT}]
[ON UPDATE {CASCADE|SET NULL|NO ACTION|RESTRICT|SET DEFAULT}]
オプションのON DELETEおよびON UPDATEコンストラクトを使用すると、上記で説明した問題のまさにその解決策を指定できます。 そして、これらのキーワードはそれらに名前を付けます:
CASCADE-主キーを含む祖先テーブルのレコードを削除または更新すると、子孫テーブルのこの値へのリンクを持つレコードが自動的に削除または更新されます。 この場合、カテゴリを削除すると、物事表内のこのカテゴリに関連するすべてのものも削除されます。 カテゴリの識別子を更新すると、このカテゴリを参照したものについて、識別子も新しいものに変更されます。
同じカスケードですが、ご覧の通り、取り外しだけではありません。
SET NULL-主キーを含む祖先テーブルのエントリを削除または更新すると、子孫テーブルの外部キー値はNULLに設定されます。
この場合、カテゴリテーブルのカテゴリ識別子を削除または更新すると、参照されたすべての項目について、カテゴリ識別子を持つフィールドのこのカテゴリに属しているものがNULLに設定されます。
NO ACTION-主キーを含む祖先テーブルのレコードを削除または更新する場合、子孫テーブルでアクションは実行されません。
この場合、カテゴリテーブルのカテゴリ識別子を削除または更新しても、これは物事テーブルに影響しません。
RESTRICT-子孫テーブルの既存の主キーを参照する子孫テーブルのレコードがある場合、祖先テーブルの主キーを持つレコードを削除または更新するときにエラーが返されます。
この場合、このカテゴリに関連するものがあるにもかかわらず、カテゴリ識別子を更新または変更しようとすると、エラーが発生します。
SET DEFAULT-主キーを含む祖先テーブルのレコードを削除または更新すると、対応するレコードの子孫テーブルにデフォルト値が設定されることは名前から明らかです。 「BUT」が1つあります。 MySQL RDBMSはこのキーワードを使用しません。
そして再び-カスケードデータの削除へ。 なぜ聞くのは本当にですか? それが1つだけであるという事実にもかかわらず、なぜ彼について最初に尋ねられたのか。 おそらく、カスケードデータの削除が問題の最も一般的な解決策であるためです。