MySQL 外键约束和表关系相关总结

目录
  • 外键(Foreign Key)
  • 如何确定表关系
  • 如何建立表关系
    • 一对多关系 - 员工表和部门表
    • 多对多
    • 一对一
  • 表关系总结

外键(Foreign Key)

按照上述所说,一张表存储员工信息会极大的浪费资源,重复数据太多,这个问题就类似于将所有的代码都写在了一个py文件中,因此我们可以将一个表拆成不同的表,在这不同的表之间建立关联,而建立关联就需要使用外键foreign key。外键也属于约束条件的一种。

如何确定表关系

表与表之间的关系有三种一对多、多对多、一对一。那么如何确定表与表之间的关系呢?

在确定表与表之间的关系时建议换位思考,什么意思呢?就是分别站在两张表的角度去考虑,比如员工表和部门表的关系:

先站在员工表的角度:员工表中一个员工能否属于多个部门呢?答案是不能

再站在部门表的角度:部门表中一个部门能否有多个员工呢?答案是可以

因此员工表与部门表是单向的一对多,那么员工表和部门表就是一对多的关系。

如何建立表关系

在建立表关系时,表与表之间的关联通常以主键id作为关联字段。

一对多关系 - 员工表和部门表

在MySQL的关系在没有多对一的概念,一对多和多对一都是一对多。在创建一对多表关系时需要遵循以下几点:

第一,外键字段建立在多的一方,即员工表

第二,在创建表的时候,一定要先创建被关联一方,即部门表

第三,在录入数据的时候也必须先录入被关联表的数据,即部门表的数据

第四,当不同的表建立关系时,需要进行级联更新和删除也可以称为同步更新同步删除,如果不建立级联更新和删除的话,无法对被关联表中被关联的数据进行删除或者修改id的操作,因为两张表是相互关联的。

-- 创建被关联表,部门表
mysql> create table bm(
    id int primary key auto_increment,
    bm_name varchar(10),
    bm_desc char(64)
);
Query OK, 0 rows affected (0.01 sec)

mysql> desc bm;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| bm_name | varchar(10) | YES  |     | NULL    |                |
| bm_desc | char(64)    | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

-- 创建外键所在的表,员工表
mysql> create table yg(
    id int primary key auto_increment,
    yg_name varchar(6),
    bm_id int,
    foreign key(bm_id) references bm(id)  -- 表示bm_id是外键字段,关联到bm表中的id字段
    on update cascade  # 级联更新
    on delete cascade  # 级联删除
);
Query OK, 0 rows affected (0.10 sec)

mysql> desc yg;
+---------+------------+------+-----+---------+----------------+
| Field   | Type       | Null | Key | Default | Extra          |
+---------+------------+------+-----+---------+----------------+
| id      | int(11)    | NO   | PRI | NULL    | auto_increment |
| yg_name | varchar(6) | YES  |     | NULL    |                |
| bm_id   | int(11)    | YES  | MUL | NULL    |                |
+---------+------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

-- 插入数据
mysql> insert into bm (bm_name, bm_desc) values ('python', '人生苦短'),('go', 'let us go');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from bm;
+----+---------+--------------+
| id | bm_name | bm_desc      |
+----+---------+--------------+
|  1 | python  | 人生苦短     |
|  2 | go      | let us go    |
+----+---------+--------------+
2 rows in set (0.00 sec)

mysql> insert into yg (yg_name, bm_id) values ('xu', 1), ('zhuang', 2), ('lili', 1);
Query OK, 3 rows affected (0.09 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from yg;
+----+---------+-------+
| id | yg_name | bm_id |
+----+---------+-------+
|  2 | xu      |     1 |
|  3 | zhuang  |     2 |
|  4 | lili    |     1 |
+----+---------+-------+
3 rows in set (0.00 sec)

-- 外键关联的数据必须在被关联表中存在否则会报错哦~
mysql> insert into yg (yg_name, bm_id) values ('xu', 3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))

-- 如果不使用级联更新和删除的话会出现下面的错误,下述的SQL语句后面的文章都会介绍。。。
mysql> update bm set id=5 where id=2;  -- 将bm表中id=2的记录改为id=5
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))

mysql> delete from bm where id =2;  -- 删除bm表中id为2的那条记录
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))

多对多

多对多的关系以书籍和作者为例进行详细介绍,为什么书籍和作者属于多对多的关系呢?

先站在书籍表的角度:一本书是否可以有多个作者?答案是可以

再站在作者表的角度:一个作者是否可以写多本书?答案是可以

书籍表和作者表是双向的一对多那么这两张表的关系就是多对多。

我们先来创建两张表:

-- 创建书籍表
create table book(
    id int primary key auto_increment,
    title varchar(32),
    price int,
    author_id int,
    foreign key(author_id) references author(id)
    on update cascade
    on delete cascade
);

-- 创建作者表
create table author(
    id int primary key auto_increment,
    name varchar(32),
    age int,
    book_id int,
    foreign key(book_id) references book(id)
    on update cascade
    on delete cascade
);

如果按照上述方式创建表的话肯定是不可能成功的,在创建一对多的表关系时我我们说要先创建被关联表,也就是没有外键的表,可是多对多关系是双向的一对多,每张表中都会有外键的存在,怎么办呢?解决方案就是创建第三张表,这第三张表用来专门存储多对多关系的两张表的关联。

-- 创建书籍表
mysql> create table book(
    id int primary key auto_increment,
    name varchar(10),
    price int
);
Query OK, 0 rows affected (0.01 sec)

-- 创建作者表
mysql> create table author(
    id int primary key auto_increment,
    name varchar(6),
    age int
);
Query OK, 0 rows affected (0.01 sec)

-- 创建第三章表,存储book和author表的关联关系
mysql> create table book2author(
    id int primary key auto_increment,
    author_id int,
    book_id int,
    foreign key(author_id) references author(id)
    on update cascade
    on delete cascade,
    foreign key(book_id) references book(id)
    on update cascade
    on delete cascade);
Query OK, 0 rows affected (0.02 sec)

一对一

如果一张表的字段特别多,每次查询数据时又不是所有的字段都能用的到,我们就可以将表一一分为二,比如说用户信息表,用户的信息包括用户名 密码 用户的年龄 用户的性别 地址 电话等等,可能经常用的只有用户的用户名和密码,这种情况我们就可以将一张用户信息表拆分成用户基本信息表和用户详细信息表,同样判断这两张表的关系还是通过换位思考:

首先看用户基本信息表:一个用户能否有多个详细信息?答案是不可以;

再看用户详情表:一个用户详情能否属于多个用户?答案是不可以;

单向的一对多都不成立,那么两者之间的表关系就是一对一或者没有关系。

使用SQL语句建立一对一的外键关系时,外键建在任意一方都可以,但是推荐将外键建在查询频率较高的表中,同样的,在创建表时还是先创建被关联表。

-- 创建用户详情表
create table authordetail(
	id int primary key auto_increment,
	phone int,
	addr varchar(64)
);

-- 用户基本信息表
create table author(
	id int primary key auto_increment,
    name varchar(32),
    age int,
    authordetali_id int,
    foreign key(authordetali_id) references authordetali(id)
    on update cascade
    on delete cascade
);

表关系总结

表关系建立需要使用外键foreign key,判断表与表之间的关系通过换位思考的方式。

一对多表关系:外键建在多的一方

一对一表关系:外键建在任意一方都可以,推荐建在查询频率高的一方

多对多表关系:需要单独创建第三张表存储两张表的关联关系

以上就是MySQL 外键约束和表关系相关总结的详细内容,更多关于MySQL 外键约束和表关系的资料请关注我们其它相关文章!

(0)

相关推荐

  • MySQL与Oracle数据类型对应关系(表格形式)

    MySQL与Oracle两种数据库在工作中,都是用的比较多的数据库,由于MySQL与Oracle在数据类型上有部分差异,在我们迁移数据库时,会遇上一定的麻烦,下面介绍MySQL与Oracle数据库数据类型的对应关系. 一.常见数据类型在MySQL与Oracle数据库中的表现形式 说明 mysql oracle 变长字符串 VARCHAR[0-65535] 定义长度默认按字符长度计算,如果是GBK编码的汉字将占用2个字节 VARCHAR2[1-4000] VARCHAR是VARCHAR2的同义词

  • MySQL创建数据表并建立主外键关系详解

    前言 为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引,如果外键列不存在索引,mysql将自动创建索引. 一.SQL语句创建数据表并设置主外键关系 create table demo.ChineseCharInfo ( ID int not null auto_increment, Hanzi varchar(10) not null, prima

  • MySQL删除有外键约束的表数据方法介绍

    在MySQL中删除一张表或一条数据的时候,出现 [Err] 1451 -Cannot deleteorupdatea parent row: aforeignkeyconstraintfails (...) 这是因为MySQL中设置了foreign key关联,造成无法更新或删除数据.可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. 禁用外键约束,我们可以使用: SETFOREIGN_KEY_CHECKS=0; 然后再删除数据 启动外键约束,我们可以使用: SETFOREIG

  • MySQL外键约束常见操作方法示例【查看、添加、修改、删除】

    本文实例讲述了MySQL外键约束常见操作方法.分享给大家供大家参考,具体如下: 1. 查看数据库表创建的sql语句 show create table vip 2. 查看外键的约束名 CREATE TABLE `vip` ( `id` int(11) NOT NULL AUTO_INCREMENT, `address` varchar(255) DEFAULT NULL, `code` varchar(255) DEFAULT NULL, `mobile` varchar(255) DEFAUL

  • MySQL删除表的时候忽略外键约束的简单实现

    删除表不是特别常用,特别是对于存在外键关联的表,删除更得小心.但是在开发过程中,发现Schema设计的有问题而且要删除现有的数据库中所有的表来重新创建也是常有的事情:另外在测试的时候,也有需要重新创建数据库的所有表.当然很多自动化工具也可以做这样的事情. 删除表的时候有时会遇到这样的错误消息: ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails 这是因为你尝试删除的表中的

  • MySQL 关闭子表的外键约束检察方法

    准备: 定义一个教师表.一个学生表:在学生表中引用教师表ID create table teachers(teacherID int not null auto_increment primary key,teacherName varchar(8)); create table students(studentID int not null auto_increment primary key,teacherID int not null,studentName varchar(8), con

  • 详解MySQL 外键约束

    官方文档: https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html 1.外键作用: MySQL通过外键约束来保证表与表之间的数据的完整性和准确性. 2.外键的使用条件 两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持) 外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立: 外键关系的两个表的列必须

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

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

  • MySQL外键约束的禁用与启用命令

    MySQL外键约束的禁用与启用: MySQL外键约束是否启用是通过一个全局变量标示的: FOREIGN_KEY_CHECKS=0; 禁用状态 FOREIGN_KEY_CHECKS=1; 启用状态 查看当前FOREIGN_KEY_CHECKS的值可用如下命令: SELECT @@FOREIGN_KEY_CHECKS; 禁用外键约束: SET FOREIGN_KEY_CHECKS=0; 启用外键约束: SET FOREIGN_KEY_CHECKS=1; 以上这篇MySQL外键约束的禁用与启用命令就是

  • MySQL外键约束的实例讲解

    MySQL的外键约束是用来在两个表之间建立链接的,其中一个表发生变化,另外一个表也发生变化.从这个特点来看,它主要是为了保证表数据的一致性和完整性的. 对于两个通过外键关联的表,相关联字段中主键所在的表是主表,也称之为父表,外键所在的表是从表,也称之为子表,定义外键的时候需要遵守几个规则: 1.父表必须已经存在于数据库中,或者是当前正在创建的表.如果是后一种情况,则父表与子表是同一个表,这样的表称为自参照表,这种结构称为自参照. 2.必须为父表定义主键. 3.主键不能包含空值,但允许在外键中出现

随机推荐