数据库SQL语句之外键
数据库的关系模型中包括了①主键②外键③索引
本文主要讲解的是外键
一对一模型
即一个表的记录对应到另一个表的唯一一个记录
例如,students
表的每个学生可以有自己的联系方式,如果把联系方式存入另一个表contacts
,我们就可以得到一个“一对一”关系:
id | student_id | mobile |
---|---|---|
1 | 1 | 135xxxx6300 |
2 | 2 | 138xxxx2209 |
3 | 5 | 139xxxx8086 |
既然是一对一关系,那为啥不给students
表增加一个mobile
列,这样就能合二为一了?
如果业务允许,完全可以把两个表合为一个表。但是,有些时候,如果某个学生没有手机号,那么,contacts
表就不存在对应的记录。实际上,一对一关系准确地说,是contacts
表一对一对应students
表。
还有一些应用会把一个大表拆成两个一对一的表,目的是把经常读取和不经常读取的字段分开,以获得更高的性能。例如,把一个大的用户表分拆为用户基本信息表user_info
和用户详细信息表user_profiles
,大部分时候,只需要查询user_info
表,并不需要查询user_profiles
表,这样就提高了查询速度。
一对多模型
当用主键标识时,我们可以在students表里唯一标识任意一个学生的记录(在关系模型中,这两个表的关系可以称为“一对一”)
id | name | other columns... |
---|---|---|
1 | 小明 | ... |
2 | 小红 | ... |
我们还可以在classes
表中确定任意一个班级记录:
id | name | other columns... |
---|---|---|
1 | 一班 | ... |
2 | 二班 | ... |
但是我们如何确定students表中student属于哪一个班级的呢?
由于一个班级可以有多个学生,在关系模型中,这两个表的关系可以称为“一对多”,即一个classes
的记录可以对应多个students
表的记录。
为了表达这种一对多的关系,我们需要在students
表中加入一列class_id
,让它的值与classes
表的某条记录相对应:
id | class_id | name | other columns... |
---|---|---|---|
1 | 1 | 小明 | ... |
2 | 1 | 小红 | ... |
5 | 2 | 小白 | ... |
- 小明的
class_id
是1
,因此,对应的classes
表的记录是id=1
的一班; - 小红的
class_id
是1
,因此,对应的classes
表的记录是id=1
的一班; - 小白的
class_id
是2
,因此,对应的classes
表的记录是id=2
的二班。
在students
表中,通过class_id
的字段,可以把数据与另一张表关联起来,这种列称为外键
。
外键并不是通过列名实现的,而是通过定义外键约束实现的:
ALTER TABLE students
ADD CONSTRAINT fk_class_id //外键约束的名称fk_class_id可以任意
FOREIGN KEY (class_id) //FOREIGN KEY (class_id)指定了class_id作为外键
REFERENCES classes (id); //REFERENCES classes (id)指定了这个外键将关联到classes表的id列(即classes表的主键)
通过定义外键约束,关系数据库可以保证无法插入无效的数据。即如果classes
表不存在id=99
的记录,students
表就无法插入class_id=99
的记录。
由于外键约束会降低数据库的性能,大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性。这种情况下,class_id
仅仅是一个普通的列,只是它起到了外键的作用而已。
要删除一个外键约束,也是通过ALTER TABLE
实现的:
ALTER TABLE students
DROP FOREIGN KEY fk_class_id;
注意:删除外键约束并没有删除外键这一列。删除列是通过DROP COLUMN ...
实现的。
多对多模型
例如,一个老师可以对应多个班级,一个班级也可以对应多个老师,因此,班级表和老师表存在多对多关系。
多对多关系实际上是通过两个一对多关系实现的,即通过一个中间表,关联两个一对多关系,就形成了多对多关系:
teachers
表:
id | name |
---|---|
1 | 张老师 |
2 | 王老师 |
3 | 李老师 |
4 | 赵老师 |
classes
表:
id | name |
---|---|
1 | 一班 |
2 | 二班 |
中间表teacher_class
关联两个一对多关系:
id | teacher_id | class_id |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 1 |
4 | 2 | 2 |
5 | 3 | 1 |
6 | 4 | 2 |
通过中间表teacher_class
可知teachers
到classes
的关系:
- teacher_id
=1
的张老师对应class_id=1,2
的一班和二班; - teacher_id
=2
的王老师对应class_id=1,2
的一班和二班; - teacher_id
=3
的李老师对应class_id=1
的一班; - teacher_id
=4
的赵老师对应class_id=2
的二班。
同理可知classes
到teachers
的关系:
- class_id
=1
的一班对应teacher_id=1,2,3
的张老师、王老师和李老师; - class_id
=2
的二班对应teacher_id=1,2,4
的张老师、王老师和赵老师;
因此,通过中间表,我们就定义了一个“多对多”关系。
本文参考自外键 - 廖雪峰的官方网站 (liaoxuefeng.com)
仅供个人学习记录,侵权删除
2022.7.12
数据库SQL语句之外键相关推荐
- 建立学生选课表 mysql 语句_学生选课数据库SQL语句45道练习题整理及mysql常用函数(20161019)...
学生选课数据库SQL语句45道练习题: 一. 设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四 ...
- 数据库三级考mysql还是sqlse_计算机三级考试数据库SQL语句整理
计算机三级考试数据库SQL语句整理 本文是关于计算机三级考试数据库SQL语句整理,包括创建数据库.删除数据库.备份sql server.创建新表等,供同学们参考学习!想了解更多相关信息请持续关注我们应 ...
- 各数据库SQL语句差异
因为数据库SQL语句在各大产品中带有"方言性",即SQLSERVER SYBASE都是用了T-SQL,Mysql是用的标准SQL,Oracle有有自己的PL/SQL.由于这种&qu ...
- oracle数据库----SQL语句的实践(应用实例)
oracle数据库----SQL语句的实践(应用实例) 创建表工资表salary,包括员工号emp_id,员工名emp_name,员工月基本工资monthsal,员工月总发工资totalsal. cr ...
- MySQL删除s表命令_SQLServer数据库sql语句中----删除表数据drop、truncate和delete的用法...
本文主要向大家介绍了SQLServer数据库sql语句中----删除表数据drop.truncate和delete的用法,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助. 虽 ...
- mysql sql exists_数据库sql语句的exists总结
数据库sql语句的exists总结 sql exists in 学习 先来比较下语法: --deals=交易表,areas=地域表,例如香港:我们的目的:查看有交易的地域 select * from ...
- 计算机导论sql试题,数据库SQL语句练习题
一. 设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表( ...
- 数据库SQL语句课堂总结(2)——子查询
废话引言 我有一个梦想,有一天能跟上单大师敲sql的速度QAQ 本文数据库同数据库SQL语句课堂总结(1) 主要介绍子查询的相关语句 正文开始 子查询介绍 定义: 子查询允许把一个查询嵌套在另一个查询 ...
- mysql查询选课程的学生学号和姓名_数据库SQL语句中查询选修了全部课程的学生的学号和姓名理解...
首先头脑中有三点概念: 1.EXISTS子查询找到的提交 NOTEXISTS子查询中找不到的提交 说明:不要去翻译为存在和不存在,把脑袋搞晕. 2.建立程序循环的概念,这是一个动态的查询过程.如FOR ...
- 数据库sql语句的exists总结
数据库sql语句的exists总结 sql exists in 学习 先来比较下语法: --deals=交易表,areas=地域表,例如香港:我们的目的:查看有交易的地域 select * from ...
最新文章
- Delphi 中的颜色常量及效果图
- R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format)、如果没有指定行标识符号,则所有的字段都会放入variable变量中
- github总star超9K!一个超赞的 PyTorch 资源大列表,有人把它翻译成了中文版!
- BP神经网络与卷积神经网络(CNN)
- ML重要概念:梯度(Gradient)与梯度下降法(Gradient Descent)
- java吧王者_java单排上王者!(一) java内存
- echarts格式化tooltip数据
- C#:委托基础与事件
- pgsql数据库默认配置事务类型_postgreSql最佳配置详解(connection 申请、回收策略)...
- Dubbo服务端暴露全流程
- python动力学仿真_python滑坡动力学
- Win10验证USB Audio MIC(三)
- 向量空间的基和维数例题_向量空间基和维数的等价定义及求法
- 各种泵的图形符号_泵的图形符号
- 神经网络模型-ART 自适应共振网络
- (最详细)Cloudera Manager安装部署
- 【WLAN】【基础知识】WIFI那些事儿之PMF
- java台球游戏_java桌球小游戏项目
- 网络服务器未运行是什么原因是,Win7系统网络诊断提示诊断策略服务未运行怎么办?...
- js判断是否是微信扫描进入