SQL必知必会-极客时间

第三讲:学会用数据库的方式思考SQL是如何执行的

  • 在RDBMS中执行方式是有区别的
  • 什么是硬解析和软解析
  • SQL在MySql中是如何执行的?

SQL必知必会-极客时间_第1张图片

  • 共享池:数据字典缓冲区。
  • 绑定变量会优化Oracle的解析过程
  • Mysql流程:查询缓存,解析器,优化器,执行器

SQL必知必会-极客时间_第2张图片

  • innidb:事务,行级锁,外键

  • 不同的数据库SQL的执行原理是一样的


  • 其实数据库内部的原理很复杂

SQL必知必会-极客时间_第3张图片

  • 在Mysql中对SQL执行的时间进行分析
  • 查看profiling是否开启
select @@profiling;
```因此在DDL中使用PRIMARY KEY进行规

- 需要开启profiling设置为1

```java
set profiling=1;
  • 执行SQL后查看时间(全部时间)
show profiles
  • 查看上一次的时间
show profile;

SQL必知必会-极客时间_第4张图片

  • 可以查询指定的Query ID
show profile for query 2;

在8.0之后mysql不再支持缓存查询。数据表有更新,缓存都将清空,只有数据表是静态的时候,缓存查询才有价值,如果数据表经常更新,反而增加了SQL查询时间

  • 查看mysql的版本信息
select version();

SQL必知必会-极客时间_第5张图片

总结

  • 相同的地方在于Oracle和MySQL都是通过解析器→优化器→执行器这样的流程来执行SQL的。
  • Oracle提出了共享池的概念,通过共享池来判断是软解析还是硬解析
  • mysql在8.0中放弃了缓存查询,而是直接。解析器→优化器→执行器的流程
  • mysql的一大特色就是存储引擎可插拔,可以针对每张表选择适合的存储引擎。

SQL必知必会-极客时间_第6张图片

  • 课后题
  1. 绑定变量概念:sql语句中使用变量,通过不同的变量值来改变sql的执行结果
    优点:减少硬解析,减少Oracle的工作量
    缺点:参数不同导致执行效率不同,优化比较难做。
  2. MyISAM的使用场景为读写分离的读库, 而InnoDB为写库
  3. C共享池,看图中有个Shared SQL Area。

第四讲:使用DDL创建数据库&数据表时需要注意什么?

  • 常见的约束:主键约束、外键约束、唯一性约束
  • 设计数据表的原则:数据表的个数越少越好,数据表中的字段个数越少越好,数据表中联合主键的字段个数越少越好,使用主键和外键越多越好
  • 数据定义语言
  • 转储SQL文件----仅结构
  • utf8_general_ci代表大小写不敏感
  • 如果没设置为为utf8_bin,代表对大小写敏感
  • UNIQUE INDEX(唯一索引)唯一索引可以用BTree或者HASH方式
  • 我们将字符编码设置为utf8mb4,排序规则为utf8_general_ci,行格式为Dynamic
  • 可以通过DDL命令完成表结构的修改
  1. 添加字段,比如我在数据表中添加一个age字段,类型为int(11)
ALTER TABLE player ADD (age int(11));
  1. 修改字段名,将age字段改成player_age
ALTER TABLE player RENAME COLUMN age to player_age
  1. 修改字段的数据类型,将player_age的数据类型设置为float(3,1)
ALTER TABLE player MODIFY (player_age float(3,1));
  1. 删除字段, 删除刚才添加的player_age字段
ALTER TABLE player DROP COLUMN player_age;
  • 数据表常见的约束,约束的目的在于保证RDBMS里面数据的准确性和一致性

  • 主键约束:起唯一标识的作用,不能重复,不能为空UNIQUE+NOT NULL,一个数据表中的主键只能有一个,主键可以是一个字段,也可以是由多个字段复合而成

  • 外键约束:外键确保了表与表之间引用的完整性。一个表中的主键对应另一张表中的外键。外键可以重复也可以为空

  • 还可以对字段进行约束:唯一性约束、NOT NULL约束、DEFAULT,表明了字段的默认值。如果在插入数据的时候,这个字段没有取值,就设置为默认值。

  • CHECK约束,用来检查特定字段取值范围的有效性,CHECK约束的结果不能为FALSE,比如我们可以对身高height的数值进行CHECK约束,必须≥0,且<3,即CHECK(height>=0 AND height<3)。

  • 数据表越少越好、数据表的字段个数越少越好、联合主键的字段数越少越好(空间大,不好理解)、使用主键和外键越多越好。键设计的越多证明利用率越高

总结

SQL必知必会-极客时间_第7张图片

  • 主键、外键、索引三者的作用和区别?
  • 主键就是为了设置唯一字段,不能重复,不能为空
  • 外键用于表关系的建立、可以重复可以为空,防止误删
  • 索引用于优化查询
  • 外键的存在确实会造成额外的开销,因为每次更新数据都需要检查另一张表的数据,也容易造成死锁
  • 在SQL之初还是建议使用外键对数据表建立约束建立强一致性,也不需要在业务层在实现过多的检查。在互联网项目的后期可以取消外键的约束转移到业务层进行实现。
  • 在分库分表的情况下也会降低外键的使用,通过减少外键的使用,来降低死锁发生的概率提高并发处理的性能
  • 使用limit关键字 order by关键字
  • 不要使用select *
  • 关键字顺序
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
  • select语句的执行顺序
FROM > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT
  • 写了一个SQL语句,那么它的关键字顺序和执行顺序是下面这样的:
SELECT DISTINCT player_id, player_name, count(*) as num #顺序5
FROM player JOIN team ON player.team_id = team.team_id #顺序1
WHERE height > 1.80 #顺序2
GROUP BY player.team_id #顺序3
HAVING num > 2 #顺序4
ORDER BY num DESC #顺序6
LIMIT 2 #顺序7
  • and比or执行的优先级会更高
  • 通配符的匹配’%太%’_只代表一个字符 %代表0个或多个
  • 尽量不要使用通配符,太消耗性能通常会全表扫描
  • 实际工作中不同人写的SQL语句的查询效率差别很大,保持高效率的一个很重要的原因,就是要避免全表扫描,所以我们会考虑在WHERE及ORDER BY涉及到的列上增加索引。

总结

  • 以heros数据表为例,请你编写SQL语句,对英雄名称、主要定位、次要定位、最大生命和最大法力进行查询,筛选条件为:主要定位是坦克或者战士,并且次要定位不为空,同时满足最大生命值大于8000或者最大法力小于1500的英雄,并且按照最大生命和最大法力之和从高到底的顺序进行排序。
SELECT name, role_main,role_assist,hp_max,mp_max FROM heros WHERE role_main in ('坦克' ,'战士') and role_assist is not null and
 (hp_max >8000 or mp_max < 1500) ORDER BY (hp_max+mp_max) DESC;

SQL必知必会-极客时间_第8张图片

05丨检索数据:你还在SELECT * 么?

  • SQL语句的执行顺序:FROM > WHERE > GROUP BY > HAVING > SELECT 的字段 > DISTINCT > ORDER BY > LIMIT

06丨数据过滤:SQL数据过滤都有哪些方法?

  • 避免全表扫描,所以我们会考虑在 WHERE 及 ORDER BY 涉及到的列上增加索引。

07-什么是SQL函数?为什么使用SQL函数可能会带来问题?

08-什么是SQL的聚集函数,如何利用它们汇总表的数据?

SQL必知必会-极客时间_第9张图片

  • SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY …
  • where对条件过滤,having对分组过滤

09-子查询:子查询的种类都有哪些,如何提高子查询的性能?

  • SQL支持子查询,从查询的结果中再次查询

12丨视图在SQL中的作用是什么,它是怎样工作的?

  • 视图是虚拟表,本身是不具有数据的

SQL必知必会-极客时间_第10张图片

  • 可以针对不同的用户指定不同的查询视图
  • 视图封装了底层与数据表的接口,相当于是一张或多张表的数据结果集
  • 可以简化复杂的SQL查询
  • 小型数据库是不需要使用视图的,大型项目中视图的价值就凸显出来了。可以经常查询的结果集放在虚拟表中提升使用效率
  • create view创建视图
  • 查询比平均身高高的人的名字:CREATE VIEW player_above_avg_height AS SELECT player_id, height FROM player WHERE height > (SELECT AVG(height) from player)
  • 修改视图:ALTER VIEW
  • 删除视图:DROP VIEW
  • 可以基于视图进行查询:SELECT * FROM player_height_grades WHERE height >= 1.90 AND height <= 2.08
  • 视图是对SQL的封装,提高代码的复用率
  • 视图是虚拟表,本身不存储数据,如果想要通过视图对底层数据表的数据进行修改也会受到很多限制,通常我们是把视图用于查询,也就是对 SQL 查询的一种封装。

1、FROM子句组装数据
2、WHERE子句进行条件筛选
3、GROUP BY分组
4、使用聚集函数进行计算;
5、HAVING筛选分组;
6、计算所有的表达式;
7、SELECT 的字段;
8、ORDER BY排序
9、LIMIT筛选

13丨什么是存储过程,在实际项目中用得多么?

  • 存储过程和视图有同样的优点:清晰、安全、减少网络流量传输
  • 存储过程是SQL语句和流程控制语句的集合,可以接受输入参数也可以返回输出参数给调用者
  • CREATE PROCEDURE 创建一个存储过程
  • DROP PROCEDURE删除存储过程
  • ALTER PROCEDURE 修改
  • 存储过程只需要在创造时编译,之后都不用重新编译
  • 减少网络传输,只需要一次连接
  • 但是有缺点:版本更新很麻烦、高并发会采用分库分表不太适用

SQL必知必会-极客时间_第11张图片

  • 作者回复: 对的,在MySQL中,如果是连续BEGIN,开启了第一个事务,还没有进行COMMIT提交,而直接进行第二个事务的BEGIN,数据库会隐式的帮助COMMIT第一个事务,然后进入到第二个事务
  • 不可重复读是同一条记录的内容被修改了,重点在于UPDATE或DELETE
  • 幻读是查询某一个范围的数据行变多了或者少了,重点在于INSERT
  • 在 MySQL InnoDB 存储引擎中,COUNT(*)和COUNT(1)都是对所有结果进行COUNT。如果有 WHERE 子句,则是对所有符合筛选条件的数据行进行统计;如果没有 WHERE 子句,则是对数据表的数据行数进行统计。
  • 因此COUNT(*)和COUNT(1)本质上并没有区别,执行的复杂度都是O(N),也就是采用全表扫描,进行循环 + 计数的方式进行统计。
  • 在 InnoDB 引擎中,如果采用COUNT()和COUNT(1)来统计数据行数,要尽量采用二级索引。因为主键采用的索引是聚簇索引,聚簇索引包含的信息多,明显会大于二级索引(非聚簇索引)。对于COUNT()和COUNT(1)来说,它们不需要查找具体的行,只是统计行数,系统会自动采用占用空间更小的二级索引来进行统计。

SQL必知必会-极客时间_第12张图片

事务

  • 幻度和不可重复读的区别:不可重复读强调在于更新和删除,幻度是强调插入

30丨锁:悲观锁和乐观锁是什么?

MVCC

  • 通过 MVCC 我们可以解决以下几个问题:
  1. 读写之间阻塞的问题,通过 MVCC 可以让读写互相不阻塞,即读不阻塞写,写不阻塞读,这样就可以提升事务并发处理能力。
  2. 降低了死锁的概率。这是因为 MVCC 采用了乐观锁的方式,读取数据时并不需要加锁,对于写操作,也只锁定必要的行。
  3. 解决一致性读的问题。一致性读也被称为快照读,当我们查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务提交的更新结果。
  • 什么是快照读,什么是当前读:

  • 不加锁简单的读取都是快照读 ,而当前读包括了加锁的读取和 DML 操作

  • 这些数据包括事务版本号、行记录中的隐藏列和 Undo Log。

  • 每开启一个事务,我们都会从数据库中获得一个事务 ID(也就是事务版本号),这个事务 ID 是自增长的,通过 ID 大小,我们就可以判断事务的时间顺序。

  • db_row_id:隐藏的行 ID,用来生成默认聚集索引。如果我们创建数据表的时候没有指定聚集索引,这时 InnoDB 就会用这个隐藏 ID 来创建聚集索引。采用聚集索引的方式可以提升数据的查找效率。

  • db_trx_id:操作这个数据的事务 ID,也就是最后一个对该数据进行插入或更新的事务 ID。

  • db_roll_ptr:回滚指针,也就是指向这个记录的 Undo Log 信息。

  • InnoDB 将行记录快照保存在了 Undo Log 里,我们可以在回滚段中找到它们

  • 在可重复读的情况下,InnoDB 可以通过 Next-Key 锁 +MVCC 来解决幻读问题。

  • 我们需要记住,MVCC 的核心就是 Undo Log+ Read View,“MV”就是通过 Undo Log 来保存数据的历史版本,实现多版本的管理,“CC”是通过 Read View 来实现管理,通过 Read View 原则来决定数据是否显示。同时针对不同的隔离级别,Read View 的生成策略不同,也就实现了不同的隔离级别。

SQL必知必会-极客时间_第13张图片

你可能感兴趣的:(SQL必知必会-极客时间)