1.什么是MySQL
MySQL是一种关系型数据库,在Java企业级开发中非常常用,开源免费并且方便扩展。
2.存储引擎
MyISAM和InnoDB(事务性数据库引擎)
MyISAM是MySQL的默认数据库引擎(5.5版之前)。虽然性能极佳,而且提供了大量的特性,包括全文索引、压缩、空间函数等,但MyISAM不支持事务和行级锁,而且最大的缺陷就是崩溃后无法安全修复。5.5之后,引入了InnoDB(事务性数据库引擎)
两者的对比:
- 是否支持行级锁:MyISAM只有表级锁,而InnoDB支持行级锁和表级锁,默认为行级锁
- 是否支持事务和崩溃后的安全恢复:MyISAM强调的是性能,每次查询都具有原子性,其执行速度比InnoDB类型更快,但是不提供事务支持。InnoDB提供事务支持事务,外部键等高级数据库功能。具有事务、回滚、和崩溃修复能力的事务安全型表。
- 是否支持MVCC:仅InnoDB支持,应对高并发事务,MVCC比加锁更高效。
3.索引
索引是一只数据结构。排序和查找快
MySQL索引使用的数据结构主要有BTree索引和哈希索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。
聚集索引和非聚集索引
- 聚集索引:主键索引,物理上持续的一段时间,插入慢,更新代价高,适合排序
- 非聚集索引:主键之外的索引,逻辑上的连续,单表最大249个
使用聚集索引为什么查询速度快
物理空间上持续,确保后续的索引值在物理上相邻
索引的建立
需要建索引:
- 主键
- 频繁访问的字段
- 外键
- 查询后用来Order By的字段
- 查询中分组的字段
不需要建索引:
- 表记录太少
- 频繁更新的字段
- where条件用不到的字段
- 重复的数据
索引失效:
- 索引能间断
- 索引列作任何操作,导致全表扫描
- 字符串不加单引号
- 使用OR
- 范围后全失效
- !=索引失效
- is null 、is not null
- group by / order by顺序不对
4.事务
事务是逻辑上的一组操作,要么都执行,要么都不执行。
4.1.事务的四大特性(ACID)
- 原子性(Atomicity):事务最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
- 一致性(Consistency):执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
- 隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。
- 持久性(Durablity):一个事务被提交之后。它对数据库的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
4.2.数据库范式
- 一范式:保证每一列的原子性 (不存在合并单元格)
- 二范式:非主键列不存在对主键的部分依赖(每张表只说一件事)
- 三范式:消除传递依赖
4.3.并发事务处理的问题
- 更新丢失(一致性):多个事务修改同一行数据,导致先更新的结果,被后更新的结果覆盖
- 脏读:读到了修改但是没有提交的数据
- 不可重复读:在一个事务中,读到了修改后的事务
- 幻读:在一个事务中,读到了刚刚新增的数据。
4.4.事务的隔离级别
- READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
- READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
- REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改的,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- SERIALIZABLE(可串行化):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务间就完全不可能产生干扰。也就是说可以防止脏读、不可重复读、以及幻读。
MySQL InnoDB存储引擎的默认支持的隔离级别是REPEATABLE-READ(可重复读)
4.5.事务的传播行为
5.InnoDB 锁
5.1行级锁
- 开销大,加锁慢;并发高,支持事务
- A线程没有提交之前B阻塞
- 可重复读
- AB线程修改不同行时,互不干扰
- 建立索引但是索引失效会导致行锁变表锁
5.2 间隙锁
当使用范围查询,而不是精准查询的时候,InnoDB会给符合索引的已有数据和不存在数据加锁,如果此时添加符合该索引的锁时,该线程也会被阻塞。
5.3 查看锁状态
show status like ' innodb_row_lock%'
5.4 死锁的必要条件
- 互斥:一个资源在一个时间只能被一个占有。
- 占有且等待:一个线程占有一个资源时,等待另一个资源。
- 不可抢占:当一个资源被占用的时候,其他线程不能占用
- 循环等待:线程1持有A等待B,线程2持有B等待A
5.5 InnoDB存储引擎的锁的算法有三种
- Record lock: 单个行记录上的锁
- Gap lock :间隙锁,锁定一个范围,不包括记录本身
- Next-key lock : record+gap 锁定一个范围,包含记录本身。
6.主从复制
6.1 原理
- 主机的数据库更新时间被写到binlog文件中
- 从机拷贝主机的二进制文件
- 重新执行二进制文件
6.2 复制分类
(1)异步复制(默认)
主机只管写,不管从机是否读; 如果主机宕机,可能出现数据丢失
(2)半同步复制
主机写后,等待从机反馈写入成功;如果等待超时,转为异步复制,当从机反馈写入成功后,重新转为同步写入。