- 1.数据库三大范式
- 2.MySQL基础架构分析
- 2.1 MySQL总体架构
2.2 MySQL中的一条查询SQL是如何执行的">
2.2 MySQL中的一条查询SQL是如何执行的- 2.3 更新语句的执行流程
- 3.InnoDB与MyISAM的区别
- 4.drop、delete、truncate的区别
- 5.内连接、外连接(8大SQL)
- 6.varchar和char的区别
- 7.视图
1.数据库三大范式
第一范式(列不可分): 每一列都是不可拆分的原子项 每一列只包含一个实例含义,不可拆分
第二范式(主键约束):要求数据库表中的每个实例或行必须可以被惟一的区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。要求实体的属性完全依赖于主关键字。一张表存在组合主键时,其他非主键字段不能部分依赖。
比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键 这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。
而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。
第三范式(外键约束): 确保数据表中的每一列数据都和主键直接相关,而不能间接相关。(非主键列相互独立)
比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。
反范式:
适用场景:当冗余信息有价值或者能大幅度提高查询效率的时候,我们才会采取反范式的优化。
增加冗余字段的建议:
- 这个冗余字段不需要经常修改
- 这个冗余字段查询的时候不可或缺
反范式的问题:
- 存储空间变大了
- 一个表中字段做了修改,另一个表中冗余的字段也需要做同步修改,否则数据不一致
- 在数据量小的情况下,反范式不能体现性能的优势,可能还会让数据库的设计更加复杂
2.MySQL基础架构分析
2.1 MySQL总体架构

连接层:最上层是一些客户端和连接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于tcp/ip的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。
服务层:
- Management Serveices & Utilities: 系统管理和控制工具
- SQL Interface: SQL接口 接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface
- Parser: 解析器
- Optimizer: 查询优化器。
Cache和Buffer: 查询缓存。
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。<br /> 这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等
引擎层:(表级层面)
存储引擎层,存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。
存储层:
数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。 主要负责数据的存储和读取 。
2.2 MySQL中的一条查询SQL是如何执行的

1)连接器
主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。
2)查询缓存
连接建立后,执行查询语句的时候,会先查询缓存,MySQL 会先校验这个 sql 是否执行过,以 Key-Value 的形式缓存在内存中,Key 是查询预计,Value 是结果集。如果缓存 key 被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用。
3)分析器
MySQL 没有命中缓存,那么就会进入分析器,分析器主要是用来分析 SQL 语句是来干嘛的,分析器也会分为几步:
第一步,词法分析,一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。
第二步,语法分析,主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。
4)优化器
优化器的作用就是它认为的最优的执行方案去执行,比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。
5)执行器
当选择了执行方案后,MySQL 就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。
总结:查询语句的执行流程如下:权限校验(如果命中缓存)—->查询缓存—->分析器—->优化器—->权限校验—->执行器—->引擎
2.3 更新语句的执行流程
更新语句的执行流程与查询差不多,不过涉及到数据的修改,需要用到日志。
先说结论,更新语句的执行流程为:
分析器——>权限校验——>执行器—->引擎—-redo log(prepare 状态)—->binlog—->redo log(commit状态)
为什么redo log需要有prepare 状态呢?
先看一下两种情况:
- 先写 redo log 直接提交,然后写 binlog,假设写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 bingog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。
- 先写 binlog,然后写 redo log,假设写完了 binlog,机器异常重启了,由于没有 redo log,本机是无法恢复这一条记录的,但是 binlog 又有记录,那么和上面同样的道理,就会产生数据不一致的情况。
如果采用 redo log 两阶段提交的方式就不一样了,写完 binglog 后,然后再提交 redo log 就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设 redo log 处于预提交状态,binglog 也已经写完了,这个时候发生了异常重启会怎么样呢? 这个就要依赖于 MySQL 的处理机制了,MySQL 的处理过程如下:
- 判断 redo log 是否完整,如果判断是完整的,就立即提交。
- 如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。
3.InnoDB与MyISAM的区别
1.InnoDB支持事务,MyISAM不支持
2.InnoDB支持外键,而MyISAM不支持
3.InnoDB主键是聚集索引,数据文件是和索引绑在一起的,而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。
4.InnoDB不保存表的具体行数,执行select count() from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快。
5. MyISAM 只有表级锁(table-level locking),而 InnoDB 支持*行级锁(row-level locking)和表级锁,默认为行级锁。
4.drop、delete、truncate的区别
- drop table 表名 ,直接将表都删除掉,在删除表的时候使用。
- truncate table 表名 ,只删除表中的数据,再插入数据的时候自增长 id 又从 1 开始,在清空表中数据的时候使用。
- delete from 表名 where 列名=值,删除某一列的数据,如果不加 where 子句和truncate table 表名作用类似。
- delete有返回值,truncate无返回值
5.内连接、外连接(8大SQL)

6.varchar和char的区别
varchar 与 char 的区别,char 是一种固定长度的类型,varchar 则是一种可变长度的类型。
7.视图
视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。 视图具有表结构文件,但不存在数据文件。
视图作用
1. 简化业务逻辑
2. 对客户端隐藏真实的表结构
