热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

MySql:多表设计---外键

在实际开发过程中,一张表显然是不能满足我们的需求,通常我们需要多张表来存储数据。那么下面就举个栗子~一家公司有多个部门,而每个部门有多个员工,现在我们来新建一个部门表:dept
在实际开发过程中,一张表显然是不能满足我们的需求,通常我们需要多张表来存储数据。那么下面就举个栗子~
一家公司有多个部门,而每个部门有多个员工,现在我们来新建一个部门表:dept   以及一个员工表:emp。
建表的操作这里不再演示,如有需要请参考:
《MySql:操作表的语句以及常用的字段类型》 http://blog.csdn.net/javy_codercoder/article/details/49099271
以下为dept表的结构:
+-------+-------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra                  |
+-------+-------------+------+-----+---------+----------------+
| id      | int(11)         | NO   | PRI  | NULL    | auto_increment |
| name| varchar(20) | NO   |        | NULL     |                            |
+-------+-------------+------+-----+---------+----------------+
以下为emp表的结构:
+--------+-------------+------+-----+---------+----------------+
| Field  | Type           | Null | Key | Default | Extra                   |
+--------+-------------+------+-----+---------+----------------+
| id      | int(11)         | NO   | PRI | NULL    | auto_increment |
| dept  | varchar(20) | YES  |       | NULL    |                             |
| name | varchar(20) | YES  |      | NULL    |                             |
| salary | double       | YES  |       | NULL    |                             |
+--------+-------------+------+-----+---------+----------------+
接下来就插入数据,插入数据也不再多说,有需要的可以看:
《MySql:增删改查(CRUD)以及乱码编码解决(1)》 http://blog.csdn.net/javy_codercoder/article/details/49121459
以下为dept表的数据:
+----+--------+
| id | name   |
+----+--------+
|  1 | 人事部 |
|  2 | 后勤部 |
|  3 | 财务部 |
|  4 | 行政部 |
+----+--------+
假设有两位员工分别叫做:小明和小芳分别属于人事部 和后勤部。
有一天老板发现后勤部没什么用然后就把后勤部砍掉了,对于数据库来说就是dept表把id为2的这一行数据删掉。
到了发工资的日期,小芳来到财务部领工资,那么财务部的妹子在电脑上发现没有后勤部啊。这个时候小芳就蒙蔽了~~我人还在部门就没了~~~
显然这种多表设计是可行的,但是是不完善的,不严谨的。
为了能够无时无刻维持着两个表的关系,我们需要引入一种叫做外键约束的技术。
我们在创建表时候可以声明表和表之间的关系,命令数据库帮我们维持这种关系。
如果有外键约束的话就不会发生以上案例的事情。在表dept删除id为2的数据时候会发生错误,因为在emp表还有一个小芳对应着dept表中id为2的数据。
显然上面的emp表是要重新建表了,因为在开始建表的时候没有加入外键约束,
那么我们来看看emp表的正确建表语句是怎样的:
create table emp(
id int primary key auto_increment,
name varchar(20),
dept_id int,
salary double,
foreign key(dept_id  ) references dept (id)
);
新建的emp表:
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| name    | varchar(20) | YES  |     | NULL    |                |
| dept_id | int(11)     | YES  | MUL | NULL    |                |
| salary  | double      | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
接下来我们插入两条数据:
insert into emp values(null,'曹操',1,2000);
insert into emp values(null,'荀彧',2,2000);
现在表里面的数据是这样的:
+----+------+---------+--------+
| id | name | dept_id | salary |
+----+------+---------+--------+
|  1 | 曹操 |       1 |   2000 |
|  2 | 荀彧 |       2 |   2000 |
+----+------+---------+--------+
我们依旧要删除掉二号部门:
delete from dept where id=2;
然后就会发现抛出一下错误:
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constrai
nt fails (`mydb`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dept_id`) REFERENC
ES `dept` (`id`))

显然不然我们删除。这就是外键约束,能够避免人还在部门就没了的事情,那么外键约束能否避免无中生有的事情发生呢?
也就是我们尝试插入一个隶属于5号部门的员工到emp表中,注意这个时候dept表只有四个部门而已。
我们试试:
insert into emp values(null,'郭嘉',5,2000);
会发现也会抛出错误:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f
ails (`mydb`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dept_id`) REFERENCES `
dept` (`id`))

要删除2号部门必须要确保emp表没有属于2号部门的员工,要插入属于5号部门的员工必须确保dept表有5号部门。

多表设计:
要懂得多表设计就要先明白什么是多对一,多对多,一对一这三种关系。而且要清楚什么情况是多对一,多对多,一对一。
这里就不再叙述,可以百度一下~
多对一:
在多对一的情况下则在“多”的一方那个表参照”一“的那个表,也就是说在”多“的那个表设计一个外键关联”一“的那个表。
一对一:
而一对一的这种情况,是随意的~那个表参照哪个表都是没有所谓的。
多对多:
多对多这种情况就比较复杂,显然无论哪一方保存另一方的id都不合适,一个比较经典的案例就是老师和学生之间的关系,要保存哪个老师教过哪些学生怎么保存呢?一个学生可能被多个老师教过,而一个老师也不可能只教一个学生,那么对于这种情况怎么解决呢?
这个时候就需要新建多一张表出来,用于分别保存学生和老师的id作为外键:

id    stu_id   teach_id
1       1             6 
2       2             3
3       3             2
4       3             1
5       3             3
6       6             1

如上表所示,如果需要查询3号学生被哪些老师教过~那么就查stu_id=3的~就能查出1,2,3这三位老师都教过3号学生
如果想查1号老师教过哪些学生那么只需查teach_id=1的数据就能查出3,6学生被1号老师教过~





推荐阅读
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • Navicat Premium 15 安装指南及数据库连接配置
    本文详细介绍 Navicat Premium 15 的安装步骤及其对多种数据库(如 MySQL 和 Oracle)的支持,帮助用户顺利完成软件的安装与激活。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ... [详细]
  • 本文详细介绍 Go+ 编程语言中的上下文处理机制,涵盖其基本概念、关键方法及应用场景。Go+ 是一门结合了 Go 的高效工程开发特性和 Python 数据科学功能的编程语言。 ... [详细]
  • QBlog开源博客系统:Page_Load生命周期与参数传递优化(第四部分)
    本教程将深入探讨QBlog开源博客系统的Page_Load生命周期,并介绍一种简洁的参数传递重构方法。通过视频演示和详细讲解,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了如何在BackTrack 5中配置和启动SSH服务,确保其正常运行,并通过Windows系统成功连接。涵盖了必要的密钥生成步骤及常见问题解决方法。 ... [详细]
  • This guide provides a comprehensive step-by-step approach to successfully installing the MongoDB PHP driver on XAMPP for macOS, ensuring a smooth and efficient setup process. ... [详细]
author-avatar
陈怡淑611947
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有