目录
MySQL数据库学习笔记分享,持续更新~敬请关注~
希望对正在学习MySQL数据库的小伙伴有帮助,如有不当之处,请予指正~
多表查询
多表关系
概述:表结构之间存在的各种联系
分类:
一对多(多对一)
实现:在多的一方建立外键,指向一的一方的主键;
多对多
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方外键;
一对一
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE);
多表查询概述
概述:指从多张表中查询数据;
笛卡尔积:笛卡尔积是指在数学中,两个集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)
分类:
连接查询:
内连接:相当于查询A、B交集部分数据;
外连接:左外连接:查询左表所有数据,以及两张表交集部分数据;
右外连接:查询右表所有数据,以及两张表交集部分数据;
自链接:当前表与自身的连接查询,自链接必须使用表别名。
子查询:
标量子查询(子查询结果为单个值);
列子查询(子查询结果为一列);
行子查询(子查询结果为一行);
表子查询(子查询结果为多行多列)。
连接查询
内连接
内连接查询语法
--查询学生表和成绩表中的每个学生对应的信息内容
--隐式内连接
--SELECT 字段列表 FROM 表1,表2 WHERE 条件...;
SELECT * FROM stu,scores WHERE stu.scores_id = scores.id;
--当表名较长时可使用别名
SELECT a.name,b.scores FROM stu a , scores b WHERE a.scores_id = b.id;
--显式内连接
--SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件...;
SELECT a.name,b.scores FROM stu a INNER JOIN scores b ON a.scores_id = b.id;
SELECT a.name,b.scores FROM stu a JOIN scores b ON a.scores_id = b.id;
注意:
1.隐式内连接和显式内连接的区别在于表的连接形式和连接条件的表示形式;
2.当给表取了别名之后,就不能再通过表名限制字段;
3.如果某条数据查询字段的内容为null,不属于交集内容,不会被查询到;
外连接
外连接查询语法
--查询stu表中所有学生信息以及对应的分组
--左外连接:相当于查询表1(左表)的所有数据 包含 表1和表2交集部分的数据
--SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...;
SELECT * FROM stu a LEFT OUTER JOIN term b ON a.term_id = b.id;
SELECT a.*,b.name FROM stu a LEFT JOIN term b ON a.term_id = b.id;
--查询term表中的分组以及组内成员信息
--右外连接:相当于查询表2(右表)的所有数据 包含 表1和表2交集部分的数据
--SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件...;
SELECT * FROM stu a RIGHT OUTER JOIN term b ON a.term_id = b.id;
SELECT b.*,a.name FROM stu a RIGHT JOIN term b ON a.term_id = b.id;
--右外连接改为左外连接
SELECT b.*,a.name FROM term b LEFT JOIN stu a ON a.term_id = b.id;
注意:
1.右外连接通常可以改写为左外连接
2.左外连接和右外连接都会分别查询到左表和右表中的所有数据,查询字段数据为null时也会被查到
自连接
自连接查询语法
--查询学生的以及同桌的姓名
--SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件...;
--内连接查询
SELECT a.name,b.name FROM stu a,stu b WHERE a.partnerid = b.id;
--外连接查询
SELECT a.name,b.name FROM stu a LEFT JOIN stu b ON a.partnerid = b.id;
注意:自链接查询可以是内连接查询,也可以是外连接查询
联合查询-union,union all
定义:对于union查询,就是把多次查询的结果并起来,形成一个新的查询结果集
语法:
--查询所有学生中成绩大于90,年龄小于18的学生信息
--SELECT 字段列表 FROM 表A...
--UNION [ALL]
--SELECT 字段列表 FROM 表B...;
--UNION ALL 对查询到的所有元素进行合并
SELECT * FROM stu WHERE score > 90
UNION ALL
SELECT * FROM stu WHERE age < 18;
--UNION 对查询到的元素进行去重复然后合并
SELECT * FROM stu WHERE score > 90
UNION
SELECT * FROM stu WHERE age < 18;
注意:
1.联合查询的多张表的列数必须保持一致,字段类型也需要保持一致;
2.UNION ALL 会将全部的数据进行合并,UNION会对合并后的数据去重。
子查询
定义:SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询。
--例如
SELECT * FROM stu WHERE column1 = (SELECT column1 FROM stu2);
--子查询外部的语句可以是INSERT/UPDATE/DELETE/SELSCT的任何一个
根据子查询结果不同可以分为:
标量子查询(子查询结果为单个值);
列子查询(子查询结果为一列);
行子查询(子查询结果为一行);
表子查询(子查询结果为多行多列)。
子查询可以出现的位置:
WHERE之后;
FROM之后;
SELECT之后。
标量子查询
定义:子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
常用操作符:=、<>、>、>=、<、<=
--查询apple小组内学生信息
--查询小组id
SELECT id FROM term WHERE name = 'apple';
--查询小组内成员信息
SELECT * FROM stu WHERE term_id = 1;--假设1为上一语句查询结果
--合并为一条语句
SELECT * FROM stu WHERE term_id = (SELECT id FROM term WHERE name = 'apple');
列子查询
定义:子查询返回的结果是一列(可以是多行),这种子查询称为列子查询;
常用的操作符:IN、NOT IN、ANY、SOME、ALL
操作符 | 作用 |
IN | 在指定的范围之内多选一 |
NOT IN | 不在指定的集合范围之内 |
ANY | 子查询返回列表中,任意一个满足即可 |
SOME | 与ANY相同,使用SOME 的地方都可以使用ANY |
ALL | 子查询返回列表的所有值都必须满足 |
--查询qpple和orange小组内学生信息
--查询小组id
SELECT id FROM term WHERE name = 'apple' OR name = 'orange';
--查询小组内成员信息
SELECT id FROM stu WHERE term_id IN (1,2);--假设1、2为上一语句查询结果
--合并为一条语句
SELECT id FROM stu WHERE term_id IN (SELECT id FROM term WHERE name = 'apple' OR name = 'orange');
--查询比小组apple成员成绩都高的学生信息
SELECT id FROM stu WHERE term_id = (SELECT id FROM term WHERE name = 'apple');
SELECT * FROM stu WHERE score > ALL (SELECT id FROM stu WHERE term_id = (SELECT id FROM term WHERE name = 'apple'));
--查询比小组apple成员成绩任意一个人高的的学生信息
SELECT id FROM stu WHERE term_id = (SELECT id FROM term WHERE name = 'apple');
SELECT * FROM stu WHERE score > ANY (SELECT id FROM stu WHERE term_id = (SELECT id FROM term WHERE name = 'apple'));
SELECT * FROM stu WHERE score > SOME (SELECT id FROM stu WHERE term_id = (SELECT id FROM term WHERE name = 'apple'));
行子查询
定义:子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
常用的操作符:=、<>、IN、NOT IN
--查询与小明的成绩相同以及任课老师相同的信息
SELECT score,teacherid FROM stu WHERE name = '小明';
SELECT * FROM stu WHERE (score,teacherid) = (SELECT score,teacherid FROM stu WHERE name = '小明');
表子查询
定义:子查询返回的结果是多行多列,这种子查询称为表子查询。
常用的操作符:IN
--查询与小明和小红的老师和成绩相同的学生信息
SELECT score,teacherid FROM stu WHERE name = '小明' OR name = '小红';
SELECT * FROM stu WHERE (score,teacherid) IN (SELECT score,teacherid FROM stu WHERE name = '小明' OR name = '小红');
事务
事务简介
事务是一组操作的集合,他是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。(在执行一个事务的时候,首先开启事务,事务内的操作全部执行成功后提交事务,如果其中一个操作异常,将回滚事务,从而保证数据的完整性和一致性)。
默认MySQL的事务是自动提交的,当执行一条DML语言,执行完之后,MySQL会立即隐式的提交事务。
事务操作
方式一:修改事务提交方式
--查看/设置事务提交方式
SELECT @@autocommit;
SET @@autocommit = 0;
--提交事务
COMMIT;
--回滚事务
ROLLBACK;
注意:事务提交方式1为自动,0为手动; 如果操作抛出异常不再提交,进行回滚事务。
方式二:开启事务,不修改事务提交方式
--开启事务
START TRANSACTION;
--或
BEGIN;
--提交事务
COMMIT;
--回滚事务
ROLLBACK;
注意:先开启事务,执行操作,如果无异常提交事务;有异常抛出则回滚事务。
事务四大特性
原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
并发事问题
问题 | 描述 |
脏读 | 一个事务读到另一个事务还没有提交的数据。 |
不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。 |
幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但在插入数据时,又发现这行数据已经存在,好像出现了”幻影“。 |
事务隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
Read uncommitted(读未提交) | √ | √ | √ |
Read committed(读已提交) | × | √ | √ |
Repeatable Read(默认)(可重复读) | × | × | √ |
Serializable(串形化) | × | × | × |
--查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;
--设置事务隔离级别
--SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE};
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
注意:事务的隔离级别越高,数据越安全,但是性能越低。
MySQL数据库基础篇(下)到这里就结束了,制作不易,全文手敲,希望看到的小伙伴,你们能够喜欢~
下期预告:MySQL数据库进阶知识