[MySQL] 外部キー制約と外部キー戦略

1. 外部キー制約とは何ですか?

        外部キー制約( FOREIGN KEY、略称 FK ) は、データベース テーブルの参照整合性を実装するために使用されます。外部キー制約を使用すると、特に変更または削除のカスケード操作の場合に、2 つのテーブルを緊密に組み合わせることができ、これによりデータの整合性が保証されます。
        外部キーとは、テーブル内のフィールドの値が別のテーブル内のフィールドの値に依存し、依存するフィールドには主キー制約または一意制約が必要であることを意味します。依存テーブルは通常、親テーブルまたはメインテーブルと呼ばれ、外部キー制約のあるテーブルは子テーブルまたはセカンダリテーブルと呼ばれます。

2. 外部キー制約の例

        学生とクラスの関係を表現したい場合は、まず学生テーブルとクラス テーブルという 2 つのテーブルが必要です。次に、学生テーブルに stu_class というフィールドがあります (このフィールドは学生が属するクラスを示します)。 、このフィールドの値の範囲はクラスによって決まります。テーブルの主キー cla_no フィールドの値 (このフィールドはクラス番号を表します) が決まります。次に、クラス テーブルがメイン テーブル、学生テーブルがスレーブ テーブル、stu_class フィールドが学生テーブルの外部キーになります。Student テーブルと Class テーブルの間の関係は、stu_class フィールドを通じて確立されます。

学生テーブルがこのように設計されている場合、次の 2 つの欠点があります。

  • デメリット1:データが重複してしまう
  • 欠点 2: クラスデータを変更する場合、複数のレコードを変更する必要がある

学生テーブルは次のように設計できます。

以上,

クラス テーブルは親テーブルと呼ばれ、クラス番号がその主キーになります。

Student テーブルは子テーブルと呼ばれ、クラス名はその外部キーです。

3. 外部キー制約の SQL 表示

1. 子テーブルは親テーブルに依存するため、最初に親テーブルを作成します。

create table t_class(
	cno int(4) primary key auto_increment,
	cname varchar(10) not null,
	room char(4)
);

2. テーブル クラスにデータを追加します。

insert into t_class values (null,'Python一班','r803');
insert into t_class values (null,'Python二班','r416');
insert into t_class values (null,'Java一班','r103');

3. サブテーブルを作成します:student テーブル t_student

外部キーを作成する場合、列名は異なっていてもかまいませんが、列のタイプとその長さは主キーと一致している必要があります。

create table t_student(
	sno int(6) primary key auto_increment,
	sname varchar(5) not null,
	classno int(4)
);

4. 生徒情報を追加する

insert into t_student values (null,'张三',1);
insert into t_student values (null,'李四',1);
insert into t_student values (null,'王五',1);

5. マスターテーブルとスレーブテーブルを関連付けます。

外部キー制約を追加する必要があります。外部キー制約はテーブル レベルの制約のみで、列レベルの制約は追加できません。

外部キー制約をサブテーブル t_student に追加し、制約名を fk_stu_classno として指定し、t_student の外部キー classno を t_class の主キー cno に関連付けます。

alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno);

6. 関連付けが成功したかどうかをテストする

現在、学生テーブルは次のようになります。

クラステーブルは次のとおりです。

テスト 1: t_class テーブルのクラス 1 を削除します。

期待される結果: クラス テーブルに関連付けられた学生テーブルにはクラス 1 の学生が存在するため、削除は不可能であるはずですが、学生にはクラス 2 と 3 がないため、クラス 2 と 3 は削除できるはずです。

delete from t_class cno=1;

実行すると 1451 エラーが返されます。

> 1451 - 親行を削除または更新できません: 外部キー制約が失敗します (`database_me`.`t_student`, CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))

外部キー制約の影響を受けるためです。

テスト 2: クラス 2 の削除

正常に削除されました。

テスト 3: 学生テーブルにデータを追加します。この学生はクラス 3 に属しており、クラス 3 を削除してみます。

insert into t_student values (null,"老六",3);

クラス 3 を削除します。

delete from t_class where cno=3;

この時点で、主キーがすでに外部キーによって制約されていることを示す 1451 エラーが返されます。

テスト 4: クラス 4 のクラスメートを外部キーを使用して子テーブルに追加する

insert into t_student values (null,"小七",4);

1452 エラーを返します。

> 1452 - 子行を追加または更新できません: 外部キー制約が失敗します (`database_me`.`t_student`、CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))

メインテーブルにクラス4がないからです。

4番目に、マスター/スレーブテーブルを削除します。

最初にスレーブ テーブルを削除し、次にマスター テーブルを削除する必要があります。そうしないと、マスター テーブルを削除できません。

最初にメインテーブルを削除すると、次のエラーが返されます。

> 3730 - テーブル 't_student' の外部キー制約 'fk_stu_classno' によって参照されているテーブル 't_class' を削除できません。

5、外部キー戦略

一部の操作によりクラス テーブルと学生テーブルのデータに混乱が生じたため、次のデモ用にこれら 2 つのテーブルを再作成します。

要件:クラス2を削除したい

ただし、外部キー制約があるため、直接削除することはできません。外部キー戦略を追加することを検討できます。

1. 戦略 1: アクションなし 操作は許可されません

まず、クラス 2 の生徒のクラス番号を null に変更します。

update t_student set classno=null where classno=2;

再度削除 

delete from t_class where cno=2;

2. 戦略 2: カスケード カスケード操作: マスター テーブルを操作すると、スレーブ テーブルの外部キー情報に影響を与えます。

カスケード操作を追加する前に、クラス番号を更新してみてください。

update t_class set cno=5 where cno=3;

1451 エラーを返します。

> 1451 - 親行を削除または更新できません: 外部キー制約が失敗します (`database_me`.`t_student`, CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))

カスケード カスケード操作を使用するには、以前の外部キー制約を削除する必要があります。

alter table t_student drop foreign key fk_stu_classno;

次に、外部キー制約を再度追加します。

alter table t_student
    add constraint fk_stu_classno
        foreign key (classno) references t_class (cno)
            on update cascade on delete cascade
;

on update cascade on delete cascade は、更新および削除時にカスケード操作が行われることを意味します。

クラス番号を再度更新してみます。

update t_class set cno=5 where cno=3;

削除操作を試して、クラス番号が 5 のクラスを削除します。削除する前に、student テーブルに 5 人の学生がいることがわかります。

クラス テーブルから 5 つのクラスを削除します。

delete from t_class where cno=5;

クラステーブルを表示します。

もう一度学生テーブルを見てください。

カスケード操作のマスターテーブルが変更されると、それに応じてスレーブテーブルのデータも変更されることがわかります。カスケード操作は実稼働ライブラリに大きな影響を与えるため、注意して使用する必要があります。

3. 戦略 3: null 設定操作

以前の外部キー制約を削除します。

alter table t_student drop foreign key fk_stu_classno;

外部キー戦略の null 操作を使用して、新しい外部キー制約を追加します。


alter table t_student add constraint 
	fk_stu_classno foreign key (classno) references t_class (cno) 
		on update set null on delete set null
		;	

クラス テーブルのクラス番号を更新してみます。

update t_class set cno=8 where cno=1;

クラステーブルを表示します。

学生テーブルを表示するには:

戦略 2 のカスケード操作と戦略 3 のブランキング操作は組み合わせて使用​​できます。たとえば、カスケード操作は更新操作に追加され、ブランキング操作は削除操作に追加されます。

alter table t_student add constraint
	fk_stu_classno foreign key (classno) references t_class (cno)
		update cascade on delete set null
		;

2 つのアプリケーション シナリオは異なります。次に例を示します。

友達サークルを削除すると、以下のコメントも一緒に削除されるため、友達サークルの削除操作はカスケード操作を使用できます。

クラスを解散する場合、クラス内の生徒はまだ存在しており、後で新しいクラスが生徒に割り当てられるため、生徒のクラス情報を空に設定できます。そのため、クラスを解散する操作で空の操作を追加できます。 。

おすすめ

転載: blog.csdn.net/hold_on_qlc/article/details/130127739