热门标签 | 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是一种强大且灵活的Web开发语言,但开发者在使用过程中常会陷入一些典型的陷阱。本文旨在列出PHP开发中最为常见的10种错误,并提供相应的预防建议。 ... [详细]
  • 本文探讨了随着并发需求的增长,MySQL数据库架构如何从简单的单一实例发展到复杂的分布式系统,以及每一步演进背后的原理和技术解决方案。 ... [详细]
  • 本文详细介绍了如何使用 PHP 编程语言输出 99 乘法表,包括使用不同的循环结构如 do-while、for 循环等方法,并提供了具体的代码示例。 ... [详细]
  • 深入理解Java MySQL数据库连接池实现
    尽管利用Apache Commons DBCP等工具可以轻松构建数据库连接池,但本文详细解析了数据库连接池的工作机制,提供了详尽的注释,帮助开发者深入理解其内部运作。这不仅有助于提高数据库操作的效率,还能增强应用程序的稳定性和性能。 ... [详细]
  • HTML网页出现乱码的主要成因及解决策略
    本文深入分析了HTML网页出现乱码的各种可能原因,并提供了相应的解决方案,帮助开发者有效避免和处理此类问题。 ... [详细]
  • 今天发现Mysql的主从数据库没有同步先上Master库:mysqlshowprocesslist;查看下进程是否Sleep太多。发现很正常。showmaster ... [详细]
  • 本文探讨了Java编程中MVC模式的优势与局限,以及如何利用Java开发一款基于鸟瞰视角的赛车游戏。 ... [详细]
  • 本文介绍了MySQL数据库的安全权限管理思想及其制度流程,涵盖从项目开发、数据库更新到日常运维等多个方面的详细流程控制,旨在通过严格的流程管理和权限控制,有效预防数据安全隐患。 ... [详细]
  • 本文详细解析了 SUCTF 2019 中的 EasySQL 题目,重点探讨了堆叠注入与 UNION 注入的区别及其应用条件。 ... [详细]
  • 本文提供了一个详细的PHP用户认证和管理的代码示例,包括用户登录验证、数据库连接、错误处理等关键部分的实现。 ... [详细]
  • 本文详细探讨了Xshell6评估版到期后无法使用的常见问题,并提供了有效的解决方案,包括如何合法购买授权以继续使用。 ... [详细]
  • AJAX技术允许网页在不重新加载整个页面的情况下进行异步更新,通过向服务器发送请求并接收JSON格式的数据,实现局部内容的动态刷新。 ... [详细]
  • 本文探讨了如何在 Spring 3 MVC 应用程序中配置 MySQL 数据库连接,通过 XML 配置实现 JDBC 直接操作数据库,而不使用 Hibernate 等额外框架。 ... [详细]
  • 本文提供了2023年最新的解决方案,帮助用户了解如何在移动设备上顺利访问和浏览PHP网页,涵盖从基础设置到高级技巧的全方位指导。 ... [详细]
  • 在Android应用开发过程中,经常需要在SQLite数据库中快速插入大量数据。本文通过实例探讨了不同插入方法的效率,并提供了优化建议。 ... [详细]
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社区 版权所有