范式
- 第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
- 第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。
- 第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如 果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系:关键字段 → 非关键字段 x → 非关键字段y
MySQL索引
- InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
- InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
- InnoDB 是聚簇索引,MyISAM 是非聚簇索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是二级索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和二级索引是独立的。
- InnoDB 不保存表的具体行数,执行select count(*) from table 时需要全表扫描。而 MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
- InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。MyISAM一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
MySQL层次
由图可以看出,MySQL的架构可以分为连接层、服务层、引擎层和存储层。
MySQL查询流程
(一)SELECT语句的执行过程
(1)客户端与mysql的连接器建立连接。
连接器可以把它理解为是一个连接池,存储和管理着多个连接。除此之外还负责校验权限,比如root用户是所有权限都有,而有些用户可能只有读的权限没有写的权限。
(2)查询缓存。
首先要注意到Mysql8.0之后查询缓存模块被拿掉了。查询缓存仅对于select语句,当查询缓存开启的时候,比如对表A的select * from A;该语句和查询结果会以HashMap的形式,将查询语句(select * from A)作为key,结果作为value存储起来,当你下一次进行查询的select查询的时候,如果是一模一样的查询语句,则会命中,且Mysql不往下执行,直接返回结果。
(3)对sql语句进行词法、语法分析。
分析器做两个事:一是词义分析,也就是说根据你这个SQL字符和空格组成的字符串,对关键字进行分析,比如发现有“select”,Mysql就知道这是一个查询语句,发现from后面的“food”,就知道food是表名;第二件事,语义分析,这就是我们熟悉的语法检查,一旦发现错误就报出:You have an error in your sql syntax。
(4)生成sql语句的执行计划
优化器会在连表查询的时候确定怎样的查询顺序比较好,或是有多个索引的时候决定用哪一个索引,不用哪一个索引等,会根据执行的效率进行判断。
(5)调用存储引擎的API进行操作
根据优化器的分析如果是全表扫描的话就会调用InnoDB执行引擎调取第一行,记录之后调取“下一行”接口……直至找到;或者是通过索引查找,最后执行器将所有结果的集合返回给用户。
(二)UPDATE语句执行过程
update语句与select语句不通的是在执行的过程中,会写三个日志:
一是事务开始(任何一个操作都是事务),写undo log,记录记录上一个版本数据,并更新记录的回滚指针和事务ID;
二是事务开始后,引擎将这行新数据更新到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态;
三是执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
然后还有事务的两阶段提交:prepare+commit。gsmtoday.github.io/2019/02/08/…