基本的な操作のMySQLデータベース(VI)

 

外部キー制約

外部キーを作成します。

       クエリは、それらの間の関係について、彼らは異なるクラスであってもよく、異なるクラスが別のクラスの先生を持っているように、我々が作成した学生のテーブルとして、表形式の前で話しているが、テーブルとテーブル間のプロジェクトは関連しています:これは、各クラスにはより多くの学生に対応し、各学生は、唯一のクラスに対応しています。教師のテーブルを作成し、このテーブルはメインテーブルである必要があり、そのテーブルの学生が子テーブルであるので、あなたはクラス情報を追加する必要があります。

CREATE  TABLE Classhost(

       ID TINYINT  PRIMARY  KEYのAUTO_INCREMENT、
       名前VARCHAR20 )、
       年齢INT 
       is_marrigedブール値
)。
INSERT INTO Classhost(名前、年齢、is_marriged)VALUES( "丽丽"、220 )、 "莉莉"、240 )、 "李丽"、220)、 ( "李莉"、200 ); CREATE TABLEの学生( ID INT PRIMARY KEY AUTO_INCREMENT、 名前VARCHAR20 )、 HOST_IDの TINYINT )ENGINE = INNODBします。 INSERT INTO学生(名前、HOST_IDVALUES( "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操作,这个也作一个了解就行。

 

おすすめ

転載: www.cnblogs.com/pengfy/p/10901227.html