zoukankan      html  css  js  c++  java
  • MySQL级联删除的问题

     1 一、FOREIGN KEY 的定义分为两种:列级约束和表级约束
     2 1、列及约束的话,可以在列定义的同时,定义外键约束。比如
     3 如果有2张表,主表:T1(A1 int primary key ,A2 varchar(10))
     4 要在从表T2中定义外键列这可以:
     5 Create table T2(
     6 B1 int,
     7 B2 char(10) [FOREIGN KEY] references T1(A1)
     8 ) 
     9 /*这里的“[FOREIGN KEY] references T1(A1)”就是外键定义了,[]是可
    10 选项,就是可以省略*/
    11 2、如果是表级约束的话,则可以
    12 CREATE TABLE T2(
    13 B1 INT,
    14 B2 CHAR(10),
    15 [Constraint(约束名)] FOREIGN KEY(B1) references T1(A1)
    16 17 /*这里是在所有列定义之后,在进行约束定义,这里要注意,表定义一定要在约束后面带上你所定义的列名,如:FOREIGN KEY(B1)
    18 还要注意的是,[Constraint(约束名)]是可选项,每个约束都是有名字的,如果你不添加,系统是会自动为你添加约束名的,作为一个合格DBA的话,建议还是自己添加约束名,有助于以后的操作(比如修改约束,删除约束等)*/
    19 
    20 二、如果之前表已经存在,要给其中一个列添加约束的话,就属于alter操作了
    21 ALTER TABLE T2
    22 ADD [CONSTRAINT(约束名)] FOREIGN KEY(B1) references T1(A1)
    23 /*相信不用我多解释了*/
    24 
    25 但是还有一点需要注意,如果在你添加之前,B1已经有了外键约束,那么就要先删除之前的约束,再添加,否则是不成功的。

    首先得理解概念,什么叫级联删除?

    外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除
    父表——被外键引用的表
    子表——引用父表中的健作为外健的表

    on updata 参数 、 on delete 参数
    这是数据库外键定义的一个可选项,用来设置当主键表中的被参考列的数据发生变化时,外键表中响应字段的变换规则的。
    
    update 则是主键表中被参考字段的值更新,delete是指在主键表中删除一条记录: on updateon delete 后面可以跟的词语有四个 no actionset nullset defaultcascade no action 表示 不做任何操作, set null 表示在外键表中将相应字段设置为null set default 表示设置为默认值 cascade 表示级联操作,就是说,如果主键表中被参考字段更新,外键表中也更新,主键表中的记录被删除,外键表中改行也相应删除

    重点:

    一个表只能有一个主键,一个主键又可以分为保存单个字段(单字段键)多字段(叫联合主键)

    单字段代码:

    1 create table  表名(
    2 user_id int(11) auto_increment,     //user_id int(11) auto_increment primary key,还有这种写法不知可不可以,有兴趣自行尝试
    3 username varchar(24),
    4 password char(32),
    5 primary key(user_id)
    6 );

    多字段代码:

    1 create table  表名(
    2 username varchar(24),
    3 password char(32),
    4 email varchar(40),
    5 primary key(username,email)
    6 );

    外键:

    好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作

    作用:保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值!

    1 在子表中声明 一个外键的代码:
    2 //数据类型一定要匹配
    3 格式:foreign key(子表的字段) references  父表的表名(父表的主键字段) on delete cascade on update cascade
    4 // on update cascade on delete cascade 的意思是 父表的主键改变时,子表外键也跟着改变,父表的主键的值删除时,子表的外键的值也删除。这就是级联。

     如果没有on update cascade 这句的,如果想更新父表或者子表都会报错,除非删除子表的引用再修改父表。有时候也可以省略foreign key 这个关键字,如:

    举个例子:

    我们创建一个父表   :工程职工工时表       子表:haha          ----声明显然名称没有必然联系,仅做测试用的,勿喷!

    父表代码:

    1  create table 工程职工工时表(
    2      工程ID integer,
    3      姓名 varchar(20) not null,
    4      primary key(工程ID)
    5      );

    子表代码:

    1  create table haha(
    2      工程ID integer,
    3     foreign key(工程ID) references 工程职工工时表(工程ID) on delete cascade on update cascade);

    给父表赋值:  insert into 工程职工工时表 values(23,'haohao'); 

    此时子表还是空的,为什么?按我的理解是,所谓的外键约束是,给定的父表的主键值后,子表的外键就必须与父表的主键值相同,不然就会报错(抛出异常),这可不是瞎说的,本文后面会献上完整的效果图以供参考。

    如果想删除父表的话就会出错:

    1 mysql> drop table 工程职工工时表;
    2 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails

     错误的大概意思是父表与子表有着级联的关系,不能删除父表。只能删除父表字段的值,子表的字段的值也会跟着删除。要想删除父表,得先删除子表或子表的约束再删除父表。

    代码:

    1 mysql> delete from 工程职工工时表 where 工程ID=23;
    2 Query OK, 1 row affected (0.12 sec)
    格式:delete from 表名 where 字段=条件
    

    终端测试的全部代码:

     1 mysql> create database mysql;
     2 Query OK, 1 row affected (0.00 sec)
     3 
     4 mysql> use mysql;
     5 Database changed
     6 mysql> create table 工程职工工时表(
     7     -> 工程ID integer,
     8     -> 姓名 varchar(20) not null,
     9     -> primary key(工程ID)
    10     -> );
    11 Query OK, 0 rows affected (0.07 sec)
    12 
    13 mysql> create table haha(
    14     -> 工程ID integer,
    15     -> foreign key(工程ID) references 工程职工工时表(工程ID) on delete cascade on update cascade);
    16 Query OK, 0 rows affected (0.15 sec)
    17 
    18 mysql> insert into 工程职工工时表 values(23,'haohao');
    19 Query OK, 1 row affected (0.04 sec)
    20 
    21 mysql> desc haha;
    22 +----------+---------+------+-----+---------+-------+
    23 | Field    | Type    | Null | Key | Default | Extra |
    24 +----------+---------+------+-----+---------+-------+
    25 | 工程ID   | int(11) | YES  | MUL | NULL    |       |
    26 +----------+---------+------+-----+---------+-------+
    27 1 row in set (0.01 sec)
    28 
    29 mysql> select*from haha;
    30 Empty set (0.00 sec)
    31 
    32 mysql> select*from 工程职工工时表;
    33 +----------+--------+
    34 | 工程ID   | 姓名   |
    35 +----------+--------+
    36 |       23 | haohao |
    37 +----------+--------+
    38 1 row in set (0.00 sec)
    39 
    40 mysql> select*from haha;
    41 Empty set (0.00 sec)
    42 mysql> insert into haha values(3434);
    43 ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mysql`.`haha`, CONSTRAINT `haha_ibfk_1` FOREIGN KEY (`工程ID`) REFERENCES `工程职工工时表` (`工程ID`) ON DELETE CASCADE ON UPDATE CASCADE)
    44 
    45 
    46 mysql> alter table 工程职工工时表 engine=InnoDB;
    47 Query OK, 0 rows affected (0.21 sec)
    48 Records: 0  Duplicates: 0  Warnings: 0
    49 
    50 mysql> alter table haha engine=InnoDB;
    51 Query OK, 0 rows affected (0.10 sec)
    52 Records: 0  Duplicates: 0  Warnings: 0
    53 
    54 mysql> insert into haha values(23)
    55     -> ;
    56 Query OK, 1 row affected (0.01 sec)
    57 
    58 mysql> select*from haha;
    59 +----------+
    60 | 工程ID   |
    61 +----------+
    62 |       23 |
    63 +----------+
    64 
    65 mysql> drop table 工程职工工时表;
    66 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
    67 
    68 1 row in set (0.00 sec)
    69 
    70 mysql> delete from 工程职工工时表 where 工程ID=23;
    71 Query OK, 1 row affected (0.12 sec)
    72 mysql> select*from 工程职工工时表;
    73 Empty set (0.03 sec)
    74 
    75 mysql> select*from haha;
    76 Empty set (0.00 sec)
    77 
    78 mysql> insert into 工程职工工时表 values(33,'yuan');
    79 Query OK, 1 row affected (0.00 sec)
    80 
    81 mysql> select*from 工程职工工时表;
    82 +----------+--------+
    83 | 工程ID   | 姓名   |
    84 +----------+--------+
    85 |       33 | yuan   |
    86 +----------+--------+
    87 1 row in set (0.00 sec)
    88 
    89 mysql> select*from haha;
    90 Empty set (0.00 sec)

    
    
  • 相关阅读:
    文本效果
    C# 将数据导出到Execl汇总[转帖]
    using方法的使用
    存储过程的相关记录
    Dictionary 泛型字典集合[转帖]
    JS验证
    浅谈AutoResetEvent的用法 [转帖]
    聊聊xp和scrum在实战中的应用问题
    字体下载
    [转] 前端开发工程师如何在2013年里提升自己
  • 原文地址:https://www.cnblogs.com/qq1871707128/p/6043510.html
Copyright © 2011-2022 走看看