外部キー制約
外部キーを作成します。
クエリは、それらの間の関係について、彼らは異なるクラスであってもよく、異なるクラスが別のクラスの先生を持っているように、我々が作成した学生のテーブルとして、表形式の前で話しているが、テーブルとテーブル間のプロジェクトは関連しています:これは、各クラスにはより多くの学生に対応し、各学生は、唯一のクラスに対応しています。教師のテーブルを作成し、このテーブルはメインテーブルである必要があり、そのテーブルの学生が子テーブルであるので、あなたはクラス情報を追加する必要があります。
CREATE TABLE Classhost( ID TINYINT PRIMARY KEYのAUTO_INCREMENT、 名前VARCHAR(20 )、 年齢INT 、 is_marrigedブール値 )。
INSERT INTO Classhost(名前、年齢、is_marriged)VALUES( "丽丽"、22、0 )、 ("莉莉"、24、0 )、 ("李丽"、22、0)、 ( "李莉"、20、0 ); CREATE TABLEの学生( ID INT PRIMARY KEY AUTO_INCREMENT、 名前VARCHAR(20 )、 HOST_IDの TINYINT )ENGINE = INNODBします。 INSERT INTO学生(名前、HOST_ID)VALUES( "pengfy"、2 )、 ("pyq"、4 )、 ("xiaojiang"、1 ) ( "pyq2"、3 )、 ("pengfy2"、1 )、 ("pyq3"、3 )、 ("ユリ"、2)。
二つのテーブルの下に作成:
今リリーが辞任したと、私たちは、名前はリリーの教師で削除しよう:
削除 から classhost 名=「丽丽」。
本当に削除し、今の学生のテーブルを見てみましょうことは変わっていません。
xiaojaingとpengfy2教師IDまたは1を発見し、これは明らかに不適切で、教師がなくなって、学生情報が変更、または他のクラスに割り当てられた、または一緒に行く(特に教師を言っています)が、我々はまた、試してみてください教師を削除した後、生徒の情報は内部の学生でテーブルを挿入し、1に設定HOST_ID、それはOKです。どちらの場合も、ディスプレイは無理があるし、時間が外部キー、そして今の学生の概念の導入は、外部キーテーブルを追加します、我々は最初の二つのテーブルに関連付けられている場所を見つける必要があり、テーブルはその内側HOST_IDテーブル内の生徒と教師idは、我々は新しい学生テーブル2を見ていることを、関連付けられています。
CREATE TABLE student2( id INT PRIMARY KEY auto_increment, name VARCHAR (20), host_id TINYINT, --切记:作为外键一定要和关联主键的数据类型保持一致
FOREIGN KEY(host_id) REFERENCES classhost(id) )ENGINE=INNODB;
INSERT INTO Student2(name,host_id) VALUES ("pengfy",2),
("pyq",4),
("xiaojiang",4),
("pyq2",3),
("pengfy2",4),
("pyq3",3),
("lily",2);
这里新的学生信息也要改一下,把id为1的要改成其他的,不然会报错。现在再试一下,删掉id为2的班主任:
delete from classhost where id=2;
报错了,不让删除了,因为外键约束了,报错信息如下:
Cannot delete or update a parent row: a foreign key constraint fails (`test`.`student2`, CONSTRAINT `student2_ibfk_1` FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))
再试一下给id=1的老师加一个学生,看是否能添加成功:
insert into student2(name,host_id) values ('lucy',1); 报错信息: Cannot add or update a child row: a foreign key constraint fails (`test`.`student2`, CONSTRAINT `student2_ibfk_1` FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))
同样报错了 ,看一下报错信息里面有个东西,CONSTRAINT `student2_ibfk_1`这个东西我没有写过,后面的FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))才是我写的,那这个是什么呢?这个是外键名称,你不自定义的时候,会默认给你加上一个,所以给一个表增加一个外键完整的写法是这样的:
ALTER TABLE student ADD CONSTRAINT anyname FOREIGN KEY(host_id) REFERENCES classhost(id);
试着给我们学生表1增加一个外键:
Cannot add or update a child row: a foreign key constraint fails (`test`.`#sql-1110_2`, CONSTRAINT `anyname` FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))
也报错了,这是为什么呢?因为老师里面已经没有id=1的了,而学生表还存在,看来要修改一下学生表才行:
第三个和第五个改成4好了,
update student set host_id=4 where id=3 or id =5;
再试一下增加外键,看一下表结构:
添加成功,那么能增加就能删除嘛,试一下删除这个外键:
ALTER TABLE student DROP FOREIGN KEY anyname;
查看是否删除成功:
已经找不到外键了,删除成功喽。那现在的问题就是主表怎么正常删除数据,并且把子表的数据也一并删除。这就涉及下面要讲的INNODB支持的ON语句。
INNODB支持的ON语句
外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update
外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的on update/on delete子句
innodb支持的四种方式
1.cascade方式
在父表上update/delete记录时,同步update/delete掉子表的匹配记录,外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除,比如刚才在删除班主任的同事,也把学生删除,就应该在主键中加上一段ON DELETE CASCADE:
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id) ON DELETE CASCADE
我们再给student加上这么一个外键:
ALTER TABLE student ADD CONSTRAINT anyname FOREIGN KEY(host_id) REFERENCES classhost(id) ON DELETE CASCADE;
同时我们也要把student2这张表删除,因为主表也和这个表绑定了,外键没改到时候删除主表还是会报错的,删掉之后,试一下删除classhost表里面的一个内容:
成功了,没有报错啊,看看子表里面,原先我们的子表id=1和id=7都是host_id=2的:
现在子表里面绑定了host_id=2的信息也都一起删除了,除了这种,还有以下三种情况。
2.set null方式
在父表上update/delete记录时,将子表上匹配记录的列设为null,要注意子表的外键列不能为not null
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id) ON DELETE SET NULL
有兴趣可以试一下这种方式,就不演示了。
3.Restrict方式
拒绝对父表进行删除更新操作,这个很少用,相当于不让sql报错,了解一下就行了。
4.No action方式
在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作,这个也作一个了解就行。