@@ -1153,7 +1153,7 @@ SELECT DISTINCT
11531153FROM
11541154 <left_table> <join_type>
11551155JOIN
1156- <right_table> ON <join_condition>
1156+ <right_table> ON <join_condition> -- 连接查询在多表查询部分详解
11571157WHERE
11581158 <where_condition>
11591159GROUP BY
@@ -1603,18 +1603,18 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
16031603
16041604
16051605
1606-
1607-
16081606***
16091607
16101608
16111609
16121610
16131611
1614- # # 约束操作
1612+ # # 多表操作
16151613
16161614# ## 约束分类
16171615
1616+ # ### 约束介绍
1617+
16181618约束:对表中的数据进行限定,保证数据的正确性、有效性、完整性!
16191619
16201620约束的分类:
@@ -1635,7 +1635,7 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
16351635
16361636
16371637
1638- # ## 主键约束
1638+ # ### 主键约束
16391639
16401640* 主键约束特点:
16411641
@@ -1687,7 +1687,7 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
16871687
16881688
16891689
1690- # ## 主键自增
1690+ # ### 主键自增
16911691
16921692主键自增约束可以为空,并自动增长。删除某条数据不影响自增的下一个数值,依然按照前一个值自增。
16931693
@@ -1733,7 +1733,7 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
17331733
17341734
17351735
1736- # ## 唯一约束
1736+ # ### 唯一约束
17371737
17381738唯一约束:约束不能有重复的数据
17391739
@@ -1765,7 +1765,7 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
17651765
17661766
17671767
1768- # ## 非空约束
1768+ # ### 非空约束
17691769
17701770* 建表时添加非空约束
17711771
@@ -1795,7 +1795,7 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
17951795
17961796
17971797
1798- # ## 外键约束
1798+ # ### 外键约束
17991799
18001800 外键约束:让表和表之间产生关系,从而保证数据的准确性!
18011801
@@ -1850,9 +1850,14 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
18501850 DELETE FROM USER WHERE NAME='王五';
18511851 ` ` `
18521852
1853-
18541853
1855- # ## 外键级联
1854+
1855+
1856+ ***
1857+
1858+
1859+
1860+ # ### 外键级联
18561861
18571862级联操作:当把主表中的数据进行删除或更新时,从表中有关联的数据的相应操作,包括 RESTRICT、CASCADE、SET NULL 和 NO ACTION
18581863
@@ -1892,16 +1897,12 @@ SELECT * FROM emp WHERE name REGEXP '[uvw]';-- 匹配包含 uvw 的name值
18921897
18931898
18941899
1895- # # 多表操作
1896-
18971900# ## 多表设计
18981901
18991902# ### 一对一
19001903
19011904多表:有多张数据表,而表与表之间有一定的关联关系,通过外键约束实现,分为一对一、一对多、多对多三类
19021905
1903-
1904-
19051906举例:人和身份证
19061907
19071908实现原则:在任意一个表建立外键,去关联另外一个表的主键
@@ -2003,37 +2004,41 @@ INSERT INTO stu_course VALUES (NULL,1,1),(NULL,1,2),(NULL,2,1),(NULL,2,2);
20032004
20042005
20052006
2006- # ## 多表查询
2007+ # ## 连接查询
20072008
2008- # ### 查询格式
2009+ # ### 连接原理
20092010
2010- 多表查询分类:
2011+ 连接查询的是两张表有交集的部分数据,如果结果集中的每条记录都是两个表相互匹配的组合,则称这样的结果集为笛卡尔积
20112012
2012- * 内连接查询
2013- * 外连接查询
2014- * 子查询
2015- * 自关联查询
2013+ 查询原理:两张表分为驱动表和被驱动表,首先查询驱动表得到数据集,然后根据数据集中的每一条记录再分别到被驱动表中查找匹配,所以驱动表只需要访问一次,被驱动表要访问多次
20162014
2017- 多表查询格式:(笛卡儿积)
2015+ MySQL 将查询驱动表后得到的记录成为驱动表的扇出,连接查询的成本:单次访问驱动表的成本 + 扇出值 * 单次访问被驱动表的成本,优化器会选择成本最小的表连接顺序(确定谁是驱动表,谁是被驱动表)生成执行计划,进行连接查询,优化方式:
20182016
2019- ` ` ` mysql
2020- SELECT
2021- 列名列表
2022- FROM
2023- 表名列表
2024- WHERE
2025- 条件...
2026- ` ` `
2017+ * 减少驱动表的扇出
2018+ * 降低访问被驱动表的成本
2019+
2020+ MySQL 提出了一种空间换时间的优化方式,基于块的循环连接,执行连接查询前申请一块固定大小的内存作为连接缓冲区 Join Buffer,先把若干条驱动表中的扇出暂存在缓冲区,每一条被驱动表中的记录一次性的与 Buffer 中多条记录进行匹配(可能是一对多),因为是在内存中完成,所以速度快,并且降低了 I/ O 成本。
2021+
2022+ Join Buffer 可以通过参数 ` join_buffer_size` 进行配置,默认大小是 256 KB
2023+
2024+ 在成本分析时,对于很多张表的连接查询,连接顺序有非常多,MySQL 如果挨着进行遍历计算成本,会消耗很多资源
2025+
2026+ * 提前结束某种连接顺序的成本评估:维护一个全局变量记录当前成本最小的连接方式,如果一种顺序只计算了一部分就已经超过了最小成本,可以提前结束计算
2027+ * 系统变量 optimizer_search_depth:如果连接表的个数小于该变量,就继续穷举分析每一种连接数量,反之只对数量与 depth 值相同的表进行分析,该值越大成本分析的越精确
2028+
2029+ * 系统变量 optimizer_prune_level:控制启发式规则的启用,这些规则就是根据以往经验指定的,不满足规则的连接顺序不分析成本
20272030
20282031
20292032
20302033***
20312034
20322035
20332036
2034- # ### 内连接
2037+ # ### 内外连接
2038+
2039+ # #### 内连接
20352040
2036- 查询原理:内连接查询的是两张表有交集的部分数据,分为驱动表和被驱动表,首先查询驱动表得到结果集,然后根据结果集中的每一条记录都分别到被驱动表中查找匹配
2041+ 内连接查询,若驱动表中的记录在被驱动表中找不到匹配的记录时,则该记录不会加到最后的结果集
20372042
20382043* 显式内连接
20392044
@@ -2054,15 +2059,19 @@ WHERE
20542059
20552060
20562061
2057- # ### 外连接
2062+ # #### 外连接
20582063
2059- * 左外连接:查询左表的全部数据,和左右两张表有交集部分的数据
2064+ 外连接查询,若驱动表中的记录在被驱动表中找不到匹配的记录时,则该记录也会加到最后的结果集,只是对于被驱动表中** 不匹配过滤条件** 的记录,各个字段使用 NULL 填充
2065+
2066+ 应用实例:差学生成绩,也想查出缺考的人的成绩
2067+
2068+ * 左外连接:选择左侧的表为驱动表,查询左表的全部数据,和左右两张表有交集部分的数据
20602069
20612070 ` ` ` mysql
20622071 SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 条件;
20632072 ` ` `
20642073
2065- * 右外连接:查询右表的全部数据,和左右两张表有交集部分的数据
2074+ * 右外连接:选择右侧的表为驱动表, 查询右表的全部数据,和左右两张表有交集部分的数据
20662075
20672076 ` ` ` mysql
20682077 SELECT 列名 FROM 表名1 RIGHT [OUTER] JOIN 表名2 ON 条件;
@@ -2077,45 +2086,9 @@ WHERE
20772086
20782087
20792088
2080- # ### 子查询
2081-
2082- 子查询概念:查询语句中嵌套了查询语句,** 将嵌套查询称为子查询**
2083-
2084- * 结果是单行单列:可以将查询的结果作为另一条语句的查询条件,使用运算符判断
2085-
2086- ` ` ` mysql
2087- SELECT 列名 FROM 表名 WHERE 列名=(SELECT 列名/聚合函数(列名) FROM 表名 [WHERE 条件]);
2088- ` ` `
2089-
2090- * 结果是多行单列:可以作为条件,使用运算符in 或not in 进行判断
2091-
2092- ` ` ` mysql
2093- SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 条件]);
2094- ` ` `
2095-
2096- * 结果是多行多列:查询的结果可以作为一张虚拟表参与查询
2097-
2098- ` ` ` mysql
2099- SELECT 列名 FROM 表名 [别名],(SELECT 列名 FROM 表名 [WHERE 条件]) [别名] [WHERE 条件];
2100-
2101- -- 查询订单表orderlist中id大于4的订单信息和所属用户USER信息
2102- SELECT
2103- *
2104- FROM
2105- USER u,
2106- (SELECT * FROM orderlist WHERE id>4) o
2107- WHERE
2108- u.id=o.uid;
2109- ` ` `
2110-
2111-
2112-
2113-
2114- ***
2115-
21162089
21172090
2118- # ### 自关联
2091+ # ### 关联查询
21192092
21202093自关联查询:同一张表中有数据关联,可以多次查询这同一个表
21212094
@@ -2182,15 +2155,53 @@ WHERE
21822155 1009 宋江 NULL NULL NULL
21832156 ```
21842157
2158+
2159+
2160+
2161+ ***
2162+
2163+
2164+
2165+ ### 嵌套查询
2166+
2167+ 子查询概念:查询语句中嵌套了查询语句,**将嵌套查询称为子查询**
2168+
2169+ * 结果是单行单列:可以将查询的结果作为另一条语句的查询条件,使用运算符判断
2170+
2171+ ```mysql
2172+ SELECT 列名 FROM 表名 WHERE 列名=(SELECT 列名/聚合函数(列名) FROM 表名 [WHERE 条件]);
2173+ ```
2174+
2175+ * 结果是多行单列:可以作为条件,使用运算符in或not in进行判断
2176+
2177+ ``` mysql
2178+ SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 条件]);
2179+ ```
2180+
2181+ * 结果是多行多列:查询的结果可以作为一张虚拟表参与查询
2182+
2183+ ``` mysql
2184+ SELECT 列名 FROM 表名 [别名],(SELECT 列名 FROM 表名 [WHERE 条件]) [别名] [WHERE 条件];
21852185
2186+ -- 查询订单表orderlist中id大于4的订单信息和所属用户USER信息
2187+ SELECT
2188+ *
2189+ FROM
2190+ USER u,
2191+ (SELECT * FROM orderlist WHERE id> 4 ) o
2192+ WHERE
2193+ u .id = o .uid ;
2194+ ```
2195+
2196+
21862197
21872198***
21882199
21892200
21902201
2191- ### 多表练习
2202+ ### 查询练习
21922203
2193- #### 数据准备
2204+ 数据准备:
21942205
21952206``` mysql
21962207-- 创建db4数据库
@@ -2241,11 +2252,11 @@ CREATE TABLE us_pro(
22412252
22422253
22432254
2244- #### 数据查询
2255+ ** 数据查询: **
22452256
224622571 . 查询用户的编号、姓名、年龄、订单编号。
22472258 分析:
2248- 数据:用户的编号、姓名、年龄在user表,订单编号在orderlist表
2259+ 数据:用户的编号、姓名、年龄在 user 表,订单编号在 orderlist 表
22492260 条件:user.id = orderlist.uid
22502261
22512262 ``` mysql
0 commit comments