介绍
实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系,接下来我们将在单表的基础上,一起学习多表方面的知识。
一 多表关系
MySQL多表之间关系可以概括为:一对一,一对多/多对一,多对多。
▶ 一对一关系
▣ 一个学生只有一张身份证;一张身份证只能对应一学生。
▣ 在任一表中添加唯一外键,指向另一方主键,确保一对一关系。
▣ 一般一对一关系很少见,遇到一对一关系的表做好是合并表。
▶ 一对多关系/多对一关系
比如:部门和员工
分析:一个部门可以有多个员工,一个员工只能对应一个部门。
实现原则:在多的一方建立外键,指向一的一方的主键。
▶ 多对多关系
比如:学生和课程
分析:一个学生可以选择很多课程,一个课程也可以被很多学生选择。
原则:多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,将多对多的关系,拆成一对多的关系,中间表至少要有两个外键,这两个外键分别指向原来那两张表的主键。
二 外键约束
介绍
MySQL外键约束(FOREIGNKEY)是表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表)。
外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。比如,一个水果摊,只有苹果、桃子、李子、西瓜等4种水果,那么,你来到水果摊要买水果就只能选择苹果、桃子、李子和西瓜,其它的水果都是不能购买的。
▶ 特点
定义一个主键时,需要遵守下列规则:
1.主表必须已经存在于数据库中,或者是当前正在创建的表。
2.必须为主表定义主键。
3.主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
4.在主表的表名后面指定列明或列明组合。这个列或列的组合必须是主表的主键或候选键。
5.外键中列的数目必须和主表的主键中列的数目相同。
6.外键中列的数据必须和主表主键中对应的数据类型相同。
2-1.一对多关系
1.创建外键约束
方式一:在创建表时设置外键约束
constraint <外键名> foreign foreign key 字段名 [,字段名2,...] references <主表名> 主键列1 [,主键列2,...]
方式一:在创建表后设置外键约束
alter table <数据表名> add constraint <外键名> foreign key (<列名>) references <主表名> (<列名>);
示例演示
2.操作外键约束数据
1.插入数据
2.删除数据
3.删除外键约束
当一个表不需要外键约束时,就需要从表中将其删除。外键一旦删除,就会解除主表和从表的关联关系。
语法格式:
alter table <表名> drop foreign key <外键约束名>;
2-2.多对多关系
在多对多关系中,A表的一行对应B的多行,B表的一行对应A表的多行,我们要新增加一个中间表,来建立多对多关系。
1.创建多对多的关系
创建两个主表和一个从表,为从表添加外键约束。
2.修改或删除表
修改和删除表与上述的一对多的关系的操作语法一样,中间表(从表)可以随便删除和修改,但是两边的主表受从表依赖的数据不能删除或者修改。
三 多表联合查询
介绍
多表查询就是同时查询两个或两个以上的表,因为有的时候用户在查看数据的时候需要显示的数据来自多张表.多表查询有以下分类:
▶ 交叉连接查询[产生笛卡尔积,了解]
语法: select * from A,B;
▶ 内连接查询(使用的关键字inner join -- inner可以省略)
隐式内连接(SQL92标准) : select * from A,B where条件;
显示内连接(SQL99标准) : select * from A inner join B on条件;
▶ 外连接查询(使用的关键字outer join -- outer可以省略)
左外连接:left outer join
select* from A left outer join B on条件;
右外连接: right outer join
select * from A right outer join B on条件;
满外连接: full outer join
select * from A full outer join B on条件;
▶ 子查询
select的嵌套
▶ 表自关联:
将一张表当成多张表来用
数据准备
1.交叉连接查询
▶ 简介
交叉连接查询返回被连接的两个表所有数据行的笛卡尔积。
笛卡尔积可以理解为一张表的每一行去和另外一张表的任意一行进行匹配。假如A表有m行数据,B表有n行数据,则返回m*n行数据。
笛卡尔积会产生很多冗余的数据,后期的其他查询可以在该集合的基础上进行条件筛选。
▶ 格式
select * from 表1,表2,表3....
▶ 演示
2.内连接查询
内连接查询求多张表的交集:
▶ 格式
隐式内连接(SQL92标准) : select * from A,B where条件;
显示内连接(SQL99标准) : select * from A inner join B on条件;
▶ 演示
3.外连接查询
外连接分为左外连接(left outer join)、右外连接(right outer join),满外连接(full outer join)。
注意: oracle里面有full join,可是在mysql对full join支持的不好。我们可以使用union来达到目。
▶ 格式
left:主要显示左表内容,右表没有的话填充null;
right:主要显示右表内容,左表没有的话填充null;
▶ 演示
4.子查询
▶ 简介
子查询就是指的在一个完整的查询语句之中,嵌套若干个不同功能的小查询,从而一起完成复杂查询的一种编写形式,通俗一点就是包含select嵌套的查询。
▶ 特点
子查询可以返回的数据类型一共分为四种:
1.单行单列:返回的是一个具体列的内容,可以理解为一个单值数据;
2.单行多列:返回一行数据中多个列的内容;
3.多行单列:返回多行记录之中同一列的内容,相当于给出了一个操作范围;
4.多行多列:查询返回的结果是一张临时表。
▶ 演示
5.子查询关键字
在子查询中,有一些常用的逻辑关键字,这些关键字可以给我们提供更丰富的查询功能,主要关键字如下:
1.ALL关键字
2.ANY关键字
3.SOME关键字
4.IN关键字
5.EXISTS关键字
5-1.关键字ALL
▶ 格式
select ...from ...where c >all(查询语句)
等价于:
select ...from ... where c > resultl and c > result2 and c >result3
▶ 特点
1.ALL:与子查询返回的所有值比较为true则返回true
2.ALL可以与=、>、>=,<、=、<>结合是来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的其中的所有数据。
3.ALL表示指定列中的值必须要大于子查询集的每一个值,即必须要大于子查询集的最大值;如果是小于号即小于子查询集的最小值。同理可以推出其它的比较运算符的情况。
▶ 演示
5-2.关键字ANY和SOME
▶ 格式
select ...from ...where c >any(查询语句)
等价于:
select ...from ... where c > resultl or c > result2 or c >result3
▶ 特点
1.ANY:与子查询返回的任何值比较为true则返回true
2.ANY可以与=、>、>=-、<、<=,<>结合是来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的其中的任何一个数据。
3.表示制定列中的值要大于子查询中的任意一个值,即必须要大于子查询集中的最小值。同理可以推出其它的比较运算符的情况。
4.SOME和ANY的作用一样,SOME可以理解为ANY的别名
▶ 演示
5-3.关键字IN
▶ 格式
select ...from ...where c in(查询语句)
等价于:
select ...from ... where c = resultl or c = result2 or c = result3
▶ 特点
1.IN关键字,用于判断某个记录的值,是否在指定的集合中.
2.在IN关键字前边加上not可以将条件反过来.
▶ 演示
5-3.关键字EXISTS
▶ 格式
select ...from ...where exists(查询语句)
▶ 特点
1.该子查询如果“有数据结果”(至少返回一行数据),则该EXISTS()的结果为“true",外层查询执行
2.该子查询如果“没有数据结果”(没有任何数据返回),则该EXISTS()的结果为“false",外层查询不执行
3.EXISTS后面的子查询不返回任何实际数据,只返回真或假,当返回真时 where条件成立4.注意,EXISTS关键字,比IN关键字的运算效率高,因此,在实际开发中,特别是大数据量时推荐使用EXISTS关键字
▶ 演示
6.自关联查询
▶ 概念
MySQL有时在信息查询时需要进行对表自身进行关联查谊,即一张表自己和自己关联,一张表当成多张表来用。注意自关联时表必须给表起别名。
▶ 格式
select 字段列表 from 表1 a , 表1 b where 条件;
或者
select 字段列表 from 表1 a [left] join 表1 b on 条件;
▶ 演示
我们先创建一个表使其自关联:
插入数据:
自关联查询演示: