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 つのアプリケーション シナリオは異なります。次に例を示します。
友達サークルを削除すると、以下のコメントも一緒に削除されるため、友達サークルの削除操作はカスケード操作を使用できます。
クラスを解散する場合、クラス内の生徒はまだ存在しており、後で新しいクラスが生徒に割り当てられるため、生徒のクラス情報を空に設定できます。そのため、クラスを解散する操作で空の操作を追加できます。 。