mysql 索引分为三类:B+树、hash索引、全文索引
相同点
不同点
会创建!分为两种种情况
没有创建索引,但有主键。
没有创建索引,也没有主键。
树最底层的就是 叶子节点
,而上层的就是 非叶字节点
页中大致有以下几个部分
三层聚簇索引来举例
根节点 只存 主键 + 页数 + 其他信息 约等于 10字节,一页是16k 也就是说存储了1600条
那么也就是说第二层有 1600 页,每一页也同样是存储了16000条
也就是说叶子节点有 1600 * 1600 页
叶子节点要存储真实数据,就按照1k来计算,一页 16 条记录 那就是 16 * 1600 * 1600 条记录 大约四千万条。
连接池 - 缓存 - 解析 - 优化 - 引擎
对比项 | MyISAM | InnDB |
---|---|---|
外键 | 不支持 | 支持 |
事务 | 不支持 | 支持 |
行表锁 | 表锁,及时操作一条记录也会锁住整个表,不适合高并发操作 | 行锁,操作时之锁某一行,不影响其他行,适合高并发操作 |
关注点 | 并发查询,节省资源,消耗少,简单业务 | 并发写、事务、多表关系、更大资源 |
符号 | 英文 | 中文 | 解释 |
---|---|---|---|
A | atomicity | 原子性 | 要么全成功要么全失败 |
C | consistency | 一致性 | 从一个合法状态、到另一个合法状态,如果被迫中断的操作将一些中间操作已经写入数据库这就是非法的,不一致的。 |
I | isolation | 隔离性 | 事务和事务之间不能互相干扰 |
D | durability | 持久性 | 一个事务一旦成功提交,它对数据库中的数据的改变就应该是永久的 |
原子性、隔离性、持久性都服务于一致性
以下例子中 age 都是 18
A 事务的任务是 修改 age=20 修改 name=张三,当A事务没有完整完成事务,只完成了 age=20的修改时。
B 事务读取 age获取到了20,这是A事务失败了数据回滚 age 返回到 18 那么B事务就拿到了脏数据,这就是 脏读
A 事务修改 age= age + 5
B 事务修改 age= age + 3
我们期望得到的是 age + 5 + 3 = 26
但如果隔离性不够B事务就可能覆盖A事务的操作
A 事务 读到数据 18 进行计算前 B事务也读到了数据18 也开始计算,这时 A数据计算结束 age = 23 但B事务的age还是18,计算结束
age= 21这就是 修改丢失,也可以叫做 脏写
A 事务 一直读取age时
B 事务 修改了age=20,这时A事务读取的age变成了20,这就是不可重复读
。
A事务在一次事务中,多次读取age时age被其他事物修改,导致同一次事务中age值不同。
类似于不可重复读,幻读是记录级别,返回的结果集不一致。
A 事务 第一次获取表行数时为5行,这时B事务新增了一行数据,A事务在同一次事务中再次查询行数变成了6行,这就是 幻读
隔离级别越高 性能越差,隔离级别越低 性能越高
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | ❎ | ❎ | ❎ |
读已提交 | ✅ | ❎ | ❎ |
可重复读(默认) | ✅ | ✅ | ❎ |
串行化 | ✅ | ✅ | ✅ |
串行化,基于读写锁实现,会对表进行加锁。
读已提交,可重复度基于MVCC多版并发本控制实现。因为加的是行锁,所以无法完全解决幻读。
锁定读使用到了读写锁,
非锁定读 MVCC多版本并发控制
实现依赖于 隐藏字段、Read View、undo log
隐藏字段
Read View
帮助我们在并发事务中,通过版本来判断哪个事务的数据是可见的。
undo log
除了用来回滚数据,还可以读取可见的版本数据。以此实现非锁定读。
undo log,成功一起成功,否则一起回滚
不同的隔离级别通过,通过锁和MVCC来保证一致性
redo log,提交成功必然redo log就写入了,如果写入失败那么数据就回滚了。
数据的原子性、隔离性、持久性一起保证数据的一致性。
简单的select 查询不会上锁,其他的事务可能将它扣成 0 了 再-1就不对了。
查询库存 = 100
减库存 = -1
记录日志 = log
提交 commit
可以 加一个 for update 加一个排他锁
select * from table_name for update
如何出现,两个事务互相依赖对方未释放的资源时会出现,如下。
事务 A
表 t id = 100 更新 加行锁
表 t id = 200 更新 加行锁
事务 B
表 t id = 200 更新 加行锁
表 t id = 100 更新 加行锁
将age=18 改为 20 日志记录顺序
bin log 刷盘三种机制,修改sync_binlog参数就可
redo log 和 undo log刷盘机制
如果直接同步表结构的二进制数据那么会有未知同步到哪里的问题,如果发生中断。
可以,使用BLOB(binary large object)来存储。
存
不存
使用 utf8mb4
join效率高,子查询效率低
子查询会创建临时表,会多一个创表和删表的操作,而join不需要,并且可以使用索引。
开启慢查询日志,收集sql(一般不开启,会带来一些性能上的问题)
查询到后使用 mysql dump slow (记得关闭慢查询日志)
rows表示返回多少行 filtered 有用的是多少。
rows 100 filtered 1.00说明影响到 100行,只有百分之1有用
count(列名)不统计null行数
count(*)统计
分成两个sql,第一个正常查询,但只查询id字段,快速定位id,通过第二个sql来查询具体值。子查询和join都可以。