mysql外键约束使用详解

MySQL有两种常用的引擎类型:MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束。InnoDB中外键约束定义的语法如下:

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION  外键的使用需要满足下列的条件:

  1. 两张表必须都是InnoDB表,并且它们没有临时表。

  2. 建立外键关系的对应列必须具有相似的InnoDB内部数据类型。

  3. 建立外键关系的对应列必须建立了索引。

  4. 假如显式的给出了CONSTRAINT symbol,那symbol在数据库中必须是唯一的。假如没有显式的给出,InnoDB会自动的创建。

  如果子表试图创建一个在父表中不存在的外键值,InnoDB会拒绝任何INSERT或UPDATE操作。如果父表试图UPDATE或者DELETE任何子表中存在或匹配的外键值,最终动作取决于外键约束定义中的ON UPDATE和ON DELETE选项。InnoDB支持5种不同的动作,如果没有指定ON DELETE或者ON UPDATE,默认的动作为RESTRICT:

  1. CASCADE: 从父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。

  2. SET NULL: 从父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。

  3. NO ACTION: InnoDB拒绝删除或者更新父表。

  4. RESTRICT: 拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的。

  5. SET DEFAULT: InnoDB目前不支持。

  外键约束使用最多的两种情况无外乎:

  1)父表更新时子表也更新,父表删除时如果子表有匹配的项,删除失败;

  2)父表更新时子表也更新,父表删除时子表匹配的项也删除。

  前一种情况,在外键定义中,我们使用ON UPDATE CASCADE ON DELETE RESTRICT;后一种情况,可以使用ON UPDATE CASCADE ON DELETE CASCADE。

  InnoDB允许你使用ALTER TABLE在一个已经存在的表上增加一个新的外键:

ALTER TABLE tbl_name
    ADD [CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

  InnoDB也支持使用ALTER TABLE来删除外键:
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;

约束

约束保证数据的完整性与一致性
约束分为表级约束和列级约束
约束类型包括 -- NOT NULL (非空约束) -- PRIMARY KEY (主键约束) -- UNIQUE KEY (唯一约束) -- DEFAULT (默认约束) -- FOREIGN KEY (外键约束)

外键约束的要求解析

FOREIGN KEY 保证数据的一致性,完整性. 实现一对一或一对多关系

父表与子表必须使用相同的存储引擎,而且禁止使用临时表.
数据表的存储引擎只能为InnoDB
外键列和参照列必须具有相似的数据类型.其中数字的长度或者是否有符号位必须相同;而字符的长度则可以不同.
外键列和参照列必须创建索引.如果外键列不存在索引的话,MySQL将自动创建索引

显示数据表的创建数据

SHOW CREATE TABLE tbl_name;

显示数据表索引

SHOW INDEXES FROM tbl_name;

创建两个表并且进行外键约束

``` CREATE TABLE provinces( id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pname VARCHAR(20) NOT NULL );

CREATE TABLE users( id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, username VARCHAR(10) NOT NULL, pid SMALLINT UNSIGNED, FOREIGN KEY(pid) REFERENCES provinces(id) );

``` 外键与主键数据类型必须的一直 比如 pname SMALLINT 对应的 pid SMALLINT 而且符号位也必须相同 有外键的表称为子表 子表参照的表称为附表 参照列自动创建了索引

外键约束的参照操作

CASCADE:从父表删除或更新且自动删除或更新子表中匹配的行
SET NULL:从父表删除或更新行,并设置子表中的外键列为NULL.如果使用该选项,必须保证子表列没有指定NOT NULL.
RESTRICT:拒绝对父表的删除或更新操作.
NO ACTION:标准的SQL关键字,在MYSQL中与RESTRICT相同.
外键约束仅仅支持innodb引擎

CREATE TABLE user1( id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, username VARCHAR(10) NOT NULL, pid SMALLINT UNSIGNED, FOREIGN KEY(pid) REFERENCES provinces(id) ON DELETE CASCADE ); 参照操作需要开启ON DELETE后再加上参数

添加数据

``` INSERT provinces(pname) VALUES("A"); INSERT provinces(pname) VALUES("B"); INSERT provinces(pname) VALUES("C");

//插入用户数据

INSERT user1(username,pid) VALUES("Tom",3); ``` 插入用户数据只需要对应设置外键的id即可.

如果记录没有写入成功,但是编号会自动递增

删除记录

删除provinces id为3的记录 DELETE FROM provinces WHERE id = 3; 那么相应的子表中外键id为3的也会删除.

表级约束与列级约束

对一个数据列建立的约束,称为列级约束.
对多个数据列建立的约束,称为表级约束.
列级约束既可以在列定义时声明,也可以在列定义后声明.
表级约束只能在列定义后声明.
修改数据表

添加单列

ALTER TABLE tbl_name ADD [COLUMN] col_name column_definition [FIRST|AFTER col_name] FIRST 指的是插入的这一列会在最前面.AFTER col_name则是在某一列后面

添加单列数据

SHOW COLUMNS FROM user1; ALTER TABLE user1 ADD age INT UNSIGNED NOT NULL DEFAULT 10; ALTER TABLE user1 ADD password VARCHAR(32) NOT NULL AFTER username;//插入某列后面 ALTER TABLE user1 ADD truename VARCHAR(20) NOT NULL FIRST; DEFAULT:未明确表明数据的时候.默认指定的数据 UNSIGNED:针对数值型类型 是否有符号

添加多列

添加多列无法指定位置

ALTER TABLE tbl_name ADD [COLUMN] (col_name column_definition);

给user1添加多列数据

ALTER TABLE user1 ADD( num INT UNSIGNED NOT NULL DEFAULT 1, sex ENUM("男","女") NOT NULL DEFAULT "男" );

删除列

ALTER TABLE user1 DROP truename;

删除多列

ALTER TABLE user1 DROP truename,DROP password;

修改列的时候可以删除的时候再添加.中间通过逗号分隔.

删除的同时再添加列

ALTER TABLE user1 DROP num, ADD pm FLOAT UNSIGNED DEFAULT 15;

添加主键约束

ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type](index_col_name,...)

范例一

CREATE TABLE user2( username VARCHAR(20) NOT NULL, pid SMALLINT UNSIGNED ); //增加主键 ALTER TABLE user2 ADD id SMALLINT UNSIGNED; //增加主键约束 ALTER TABLE user2 ADD CONSTRAINT PK_user2_id PRIMARY KEY (id); CONSTRAINT:用来起别名

添加唯一约束

ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type](index_col_name,...)

范例一

ALTER TABLE user2 ADD UNIQUE (username);

添加外键约束

范例一

user2中pid参照provinces; ALTER TABLE user2 ADD FOREIGN KEY (pid) REFERENCES provinces (id);

添加/删除默认约束

ALTER TABLE tbl_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}

范例一

ALTER TABLE user2 ADD age TINYINT UNSIGNED NOT NULL; ALTER TABLE user2 ALTER age SET DEFAULT 15; 给age添加默认约束

删除主键约束

任何一个表有且只有一个主键 ALTER TABLE user2 DROP PRIMARY KEY;

删除主键索引

ALTER TABLE user2 DROP INDEX username; 删除的仅仅是索引

显示索引列表名称

SHOW INDEXes FROM user2;

删除外键约束

删除约束是删除约束的名称 ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbok

范例

``` //查询外键名称

SHOW CREATE TABLE user2; //找到pid的外键名称为 user2_ibfk_1;然后进行删除

ALTER TABLE user2 DROP FOREIGN KEY user2_ibfk_1;

虽然外键不在了,但是索引还是存在的 如果不想要索引则删除即可 ALTER TABLE user2 DROP INDEX pid; ```

修改列定义和更名数据表

修改列定义

ALTER TABLE tbl_name MODIFY [COLUMN] col_name column_definition [FIRST |AFTER col_name]

修改列顺序

ALTER TABLE user2 MODIFY id SMALLINT UNSIGNED NOT NULL FIRST; column_definition指的是列定义 不变

修改列定义-范例

ALTER TABLE user2 MODIFY id TINYINT UNSIGNED NOT NULL; 修改列定义的时候有可能会造成数据的丢失.

修改列名称

ALTER TABLE tbl_name CHANGE [COLUMN] old_col_name new col_name column_definition [FIRST |AFTER col_name]

修改id的类型与名称 ALTER TABLE user2 CHANGE pid p_id TINYINT UNSIGNED NOT NULL;

数据表更名

一. ALTER TABLE tbl_name RENAME [TO|AS] new_tbl_name;

二. RENAME TABLE tbl_name TO new_tbl_name [,tbl_name2 TO new_tbl_name2];

范例 ``` ALTER TABLE user2 RENAME users2;

RENAME TABLE users2 TO user2; ```

多个外键存在:
product_order表对其它两个表有外键。
一个外键引用一个product表中的双列索引。另一个引用在customer表中的单行索引:
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) TYPE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
                      PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                      product_category INT NOT NULL,
                      product_id INT NOT NULL,
                      customer_id INT NOT NULL,
                      PRIMARY KEY(no),
                      -- 双外键
                      INDEX (product_category, product_id),
                      FOREIGN KEY (product_category, product_id)
                        REFERENCES product(category, id)
                        ON UPDATE CASCADE ON DELETE RESTRICT,
                      -- 单外键
                      INDEX (customer_id),
                      FOREIGN KEY (customer_id)
                       REFERENCES customer(id)) TYPE=INNODB;
(6) 说明:
1.若不声明on update/delete,则默认是采用restrict方式.
2.对于外键约束,最好是采用: ON UPDATE CASCADE ON DELETE RESTRICT 的方式.

总结

约束 - 按功能化为:NOT NULL,PRIMARY KEY, UNIQUE KEY, DEFAULT,FOREIGN KEY - 按数据列的数目化为:表级约束,列级约束

修改数据表 - 针对字段的操作:添加/删除字段,修改列定义,修改列名称等 - 针对约束的操作:添加/删除各种约束. - 针对数据表的操作:数据表更名(两种方式).

列级约束:只能应用于一列上。 表级约束:可以应用于一列上,也可以应用在一个表中的多个列上。

默认约束(DEFAULT)与非空约束(NOT NULL)不存在表级约束

时间: 2024-09-17 04:01:19

mysql外键约束使用详解的相关文章

Mysql外键约束设置使用方法

两个表必须是InnoDB表,MyISAM表暂时不支持外键 外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立: 外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以: 创建外键语法:  代码如下 复制代码 [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name, ...) REFERENCE

MYSQL外键约束的学习笔记

在项目中,很多时候我们建数据表单的时候,两个表示相关联的,并且一个表里面的数据是完全依赖另一张表的数据的, 外键约束语法 [CONSTRAINT [symbol]] FOREIGN KEY     [index_name] (index_col_name, ...)     REFERENCES tbl_name (index_col_name,...)     [ON DELETE reference_option]     [ON UPDATE reference_option] refer

详解MySQL中的外键约束问题_Mysql

使用MySQL开发过数据库驱动的小型web应用程序的人都知道,对关系数据库的表进行创建.检索.更新和删除等操作都是些比较简单的过程.理论上,只要掌握了最常见的SQL语句的用法,并熟悉您选择使用的服务器端脚本语言,就足以应付对MySQL表所需的各种操作了,尤其是当您使用了快速MyISAM数据库引擎的时候.但是,即使在最简单的情况下,事情也要比我们想象的要复杂得多.下面我们用一个典型的例子进行说明.假设您正在运行一个博客网站,您几乎天天更新,并且该站点允许访问者评论您的帖子. MySQL外键约束条件

mysql中关于外键约束的小问题

问题描述 mysql中关于外键约束的小问题 我想问,主表被references后不允许先删除记录,又说从表指定on delete cascade后删除主表记录时从表记录随之删除,你说这不矛盾吗?到底让不让删除? 例如下面这张图,student_table参考teacher_table,我却删不掉主表teacher_table 解决方案 嗯,这个问题已经解决啦,是我测试代码写错了,删除记录用del 我那个写成drop了 解决方案二: 你需要先解除外键约束 再删除表 解决方案三: MySQL外键约束

MySQL数据库中的外键约束详解

使用MySQL开发过数据库驱动的小型web应用程序的人都知道,对关系数据库的表进行创建.检索.更新和删除等操作都是些比较简单的过程.理论上,只要掌握了最常见的SQL语句的用法,并熟悉您选择使用的服务器端脚本语言,就足以应付对MySQL表所需的各种操作了,尤其是当您使用了快速MyISAM数据库引擎的时候.但是,即使在最简单的情况下,事情也要比我们想象的要复杂得多.下面我们用一个典型的例子进行说明.假设您正在运行一个博客网站,您几乎天天更新,并且该站点允许访问者评论您的帖子. 在这种情况下,我们的数

MySQL外键使用及说明详解_Mysql

一.外键约束 MySQL通过外键约束来保证表与表之间的数据的完整性和准确性. 外键的使用条件: 1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持): 2.外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立: 3.外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以: 外键的好处: 可以使得两张表关联,保证

深入mysql外键关联问题的详解_Mysql

今儿继续再看老师给推荐的深入浅出mysql数据库开发这本书,看到innodb数据库的外键关联问题时,遇到了一个问题,书上写的是可以对父表进行修改,从而同步到子表的外键上去,可是自己的实验却是没有能够. 复制代码 代码如下: mysql> show create table country\G*************************** 1. row ***************************       Table: countryCreate Table: CREATE

MySQL外键使用详解_Mysql

最近有开始做一个实验室管理系统,因为分了几个表进行存储·所以要维护表间的关联··研究了一下MySQL的外键. (1)只有InnoDB类型的表才可以使用外键,mysql默认是MyISAM,这种类型不支持外键约束 (2)外键的好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作: (3)外键的作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据. 使两张表形成关联,外键只能引用外表中的列的值! (4)建立外键的前提: 两个表必须是InnoDB表类型. 使用在外键关系的域必须为索

MySQL · 捉虫动态 · 并行复制外键约束问题二

背景 并行复制可以大大提高备库的 binlog 应用速度,内核月报也多次对并行复制特性进行介绍,感兴趣的朋友可以回顾下:5.6 并行复制实现分析.5.6 并行复制恢复实现 和 5.6并行复制事件分发机制. 在早期的内核月报,有一篇 并行复制外建约束问题,介绍阿里在 5.5 版本中自己实现并行复制时遇到的外键约束问题,本文接着前作继续介绍并行复制外键约束问题,这次场景不一样,并且目前官方 5.6 最新版本(5.6.30)中也有这个问题. 问题描述 一般情况的复制是 A->B 这样一主一备,本文要描