一、FOREIGN KEY 的定义分为两种:列级约束和表级约束
1、列及约束的话,可以在列定义的同时,定义外键约束。比如
如果有2张表,主表:T1(A1 int primary key ,A2 varchar(10))
要在从表T2中定义外键列这可以:
Create table T2(
B1 int,
B2 char(10) [FOREIGN KEY] references T1(A1)
)
/*这里的“[FOREIGN KEY] references T1(A1)”就是外键定义了,[]是可
选项,就是可以省略*/
2、如果是表级约束的话,则可以
CREATE TABLE T2(
B1 INT,
B2 CHAR(10),
[Constraint(约束名)] FOREIGN KEY(B1) references T1(A1)

/*这里是在所有列定义之后,在进行约束定义,这里要注意,表定义一定要在约束后面带上你所定义的列名,如:FOREIGN KEY(B1)
还要注意的是,[Constraint(约束名)]是可选项,每个约束都是有名字的,如果你不添加,系统是会自动为你添加约束名的,作为一个合格DBA的话,建议还是自己添加约束名,有助于以后的操作(比如修改约束,删除约束等)*/ 二、如果之前表已经存在,要给其中一个列添加约束的话,就属于alter操作了
ALTER TABLE T2
ADD [CONSTRAINT(约束名)] FOREIGN KEY(B1) references T1(A1)
/*相信不用我多解释了*/ 但是还有一点需要注意,如果在你添加之前,B1已经有了外键约束,那么就要先删除之前的约束,再添加,否则是不成功的。

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

外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除
父表——被外键引用的表
子表——引用父表中的健作为外健的表
on updata 参数 、 on delete 参数
这是数据库外键定义的一个可选项,用来设置当主键表中的被参考列的数据发生变化时,外键表中响应字段的变换规则的。

update 则是主键表中被参考字段的值更新,delete是指在主键表中删除一条记录:
on update 和 on delete 后面可以跟的词语有四个
no action , set null , set default ,cascade
no action 表示 不做任何操作,
set null 表示在外键表中将相应字段设置为null
set default 表示设置为默认值
cascade 表示级联操作,就是说,如果主键表中被参考字段更新,外键表中也更新,主键表中的记录被删除,外键表中改行也相应删除

重点:

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

单字段代码:

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

多字段代码:

 create table  表名(
username varchar(24),
password char(32),
email varchar(40),
primary key(username,email)
);

外键:

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

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

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

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

举个例子:

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

父表代码:

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

子表代码:

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

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

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

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

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

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

代码:

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

终端测试的全部代码:

 mysql> create database mysql;
Query OK, 1 row affected (0.00 sec) mysql> use mysql;
Database changed
mysql> create table 工程职工工时表(
-> 工程ID integer,
-> 姓名 varchar(20) not null,
-> primary key(工程ID)
-> );
Query OK, 0 rows affected (0.07 sec) mysql> create table haha(
-> 工程ID integer,
-> foreign key(工程ID) references 工程职工工时表(工程ID) on delete cascade on update cascade);
Query OK, 0 rows affected (0.15 sec) mysql> insert into 工程职工工时表 values(23,'haohao');
Query OK, 1 row affected (0.04 sec) mysql> desc haha;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| 工程ID | int(11) | YES | MUL | NULL | |
+----------+---------+------+-----+---------+-------+
1 row in set (0.01 sec) mysql> select*from haha;
Empty set (0.00 sec) mysql> select*from 工程职工工时表;
+----------+--------+
| 工程ID | 姓名 |
+----------+--------+
| 23 | haohao |
+----------+--------+
1 row in set (0.00 sec) mysql> select*from haha;
Empty set (0.00 sec)
mysql> insert into haha values(3434);
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) mysql> alter table 工程职工工时表 engine=InnoDB;
Query OK, 0 rows affected (0.21 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table haha engine=InnoDB;
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> insert into haha values(23)
-> ;
Query OK, 1 row affected (0.01 sec) mysql> select*from haha;
+----------+
| 工程ID |
+----------+
| 23 |
+----------+ mysql> drop table 工程职工工时表;
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails 1 row in set (0.00 sec) mysql> delete from 工程职工工时表 where 工程ID=23;
Query OK, 1 row affected (0.12 sec)
mysql> select*from 工程职工工时表;
Empty set (0.03 sec) mysql> select*from haha;
Empty set (0.00 sec) mysql> insert into 工程职工工时表 values(33,'yuan');
Query OK, 1 row affected (0.00 sec) mysql> select*from 工程职工工时表;
+----------+--------+
| 工程ID | 姓名 |
+----------+--------+
| 33 | yuan |
+----------+--------+
1 row in set (0.00 sec) mysql> select*from haha;
Empty set (0.00 sec)

MySQL级联删除的问题的更多相关文章

  1. mysql级联删除更新

    首先,目前在产品环境可用的MySQL版本(指4.0.x和4.1.x)中,只有InnoDB引擎才允许使用外键,所以,我们的数据表必须使用InnoDB引擎. 下面,我们先创建以下测试用数据库表: CREA ...

  2. mysql级联删除

    一个building对应多个rooms,building删除----级联删除相关的rooms 第一步, 创建buildings表,如下创建语句: USE testdb; CREATE TABLE bu ...

  3. MySQL级联删除和级联修改

    1.新建主键table create table demo1_zhujian ( id int primary key auto_increment, name )); 2.新建外键table cre ...

  4. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  5. MySQL中利用外键实现级联删除、更新

    MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作 ...

  6. MySQL外键及级联删除 && 表的存储引擎与创建索引 && 删除数据库和表

    Messages表: mysql>create table Messages( ->message_id int auto_increment primary key, ->user ...

  7. mysql数据库主外键级联删除脚本RESTRICT --> CASCADE

    在项目中,我们一般在数据库设计的时候做主外键关联设计,要么就不做.但是这样不符合规范,呵呵. 建立主外键关系的时候,默认是不能级联删除的.而出现往往在删除主表的数据时报错, 需要先删除从表然后再删除主 ...

  8. mysql内部级联删除

    1,创建user表 属性:id,name 2,创建userInfo表 属性:id,age 在userInfo表中创建外键id,如下图: 在user表中插入两个用户信息 (1,'1'),(2,'2') ...

  9. Mysql实现级联操作(级联更新、级联删除)

    一.首先创建两张表stu,sc create table stu( sid int UNSIGNED primary key auto_increment, name ) not null) TYPE ...

随机推荐

  1. Appium+Robotframework实现Android应用的自动化测试-6:一个简单的例子

    万事具备,只欠编码! 下面看一个简单的示例,这个示例验证Android手机自带的通讯录的添加联系人的操作是否成功.这个例子是Appium官网自带的示例,有兴趣的同学也可以自己下载来研究和学习,下载地址 ...

  2. 【转】.so兼容32位和64位

    本文转自:http://blog.csdn.net/fwt336/article/details/51700300 安卓的兼容性是一个很令人头疼的问题,这几天又遇到了,还好还是解决了. 我遇到的问题是 ...

  3. ACM/ICPC 之 递归(POJ2663-完全覆盖+POJ1057(百练2775)-旧式文件结构图)

    POJ2663-完全覆盖 题解见首注释 //简单递推-三个米诺牌(3*2)为一个单位打草稿得出规律 //题意-3*n块方格能被1*2的米诺牌以多少种情况完全覆盖 //Memory 132K Time: ...

  4. Effective C++ -----条款37:绝不重新定义继承而来的缺省参数值

    绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数-----你唯一应该覆写的东西-----却是动态绑定.

  5. linux线程的实现

    首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个分身可以处理一件特定事情.这在处理异步事件如异步IO时特别有用.内核线程的使用是廉价的,唯一使用 ...

  6. linux 解压缩

    tar f 使用档案名字,这个参数是最后一个参数,后面只能接档案名 c 建立压缩档案 x 解压 t 查看内容 r 向压缩归档文件末尾追加文件 u 更新原压缩包中的文件 z 有gzip属性的 j 有bz ...

  7. Divide and conquer:Matrix(POJ 3685)

    矩阵 题目大意:矩阵里面的元素按i*i + 100000 * i + j*j - 100000 * j + i*j填充(i是行,j是列),求最小的M个数 这一题要用到两次二分,实在是二分法的经典,主要 ...

  8. WP8 双击返回键退出

    bool isExit = false; // 构造函数 public MainPage() { InitializeComponent(); isExit = false; // 用于本地化 App ...

  9. Dynamic Invok Webservice

    来源:网络,自己做修改 CSharpCodeProvider csc = new CSharpCodeProvider(); ICodeCompiler icc = csc.CreateCompile ...

  10. 轻轻送送为你的App加点特效

    前言 今天突然在一个应用中看到一个转场动画,蛮有意思的 退出动画 进入动画 ActivityOptionsCompat options = ActivityOptionsCompat.makeScal ...