- 1 存储引擎
1.1)MYISAM:不支持事务、外键,表锁,写锁优先级大于读锁,MyISAM表不太适合于有大量更新操作和查询操作
1.2)InnoDB:支持事务和外键,行锁,带来了脏读,不可重复读,幻读
- 2 数据类型
- 3 索引(InnoDB使用的是聚簇索引,MyISM使用的是非聚簇索引)
索引
3.1)聚簇索引:顺序结构存储,索引和数据在一起,找到了索引,就找到了数据
3.2)非聚簇索引
3.3)二级索引:
3.3.1)唯一索引:索引值唯一,不能为空,查找到一条就停止
3.3.2)普通索引:一直查找直到没有满足的
3.3.3)前缀索引:给BLOB,TEXT,或者长varchar建立索引,具体长度创建的时候指定
3.4)B+树索引
3.4.1)B+树,B树的区别
B树每个节点都存储数据,而B+树只有叶子节点才存储数据,同样数据量下,B树高度高,在大数据下IO次数比较多
B树三层可以存放两千万条数据
3.4.2)最左前缀原则
3.5)哈希索引
3.5.1)Hash索引底层是哈希表,适合等值查询,
3.5.2)相对于B+树来说不适合范围查询
3.5.3)不支持多列联合索引的最左匹配规则
3.5.4)如果有大量重复Key,会出现hash冲突
3.5.5)应用场景:
3.5.5.1)哈希索引只包含hash值和行指针,不能作为覆盖索引,不能排序,不支持最左前缀原则。
3.5.5.2)只支持等值查询(=,in),不支持范围查询
3.5.5.3)如果出现hash冲突,需要遍历链表中的所有行指针进行一一比较
3.5.5.4)hash冲突越高,维护索引的代价越高
- 4 事务
4.1)隔离级别(ACID):
4.1.1)读取未提交:脏读,不可重复读,幻读
4.1.2)读取已提交:不可重复读,幻读
4.1.3)可重复读(默认):幻读
4.1.4)可串行化
- 5 锁
5.1)粒度锁
5.1.1)行锁:InnoDB是通过给索引上的索引项加锁来实现的,如果没有通过索引条件加锁,InnoDb使用表锁
5.1.2)表锁
5.1.2.1)如果当前事务更新大部分或者全部数据,使用行锁性能差,考虑使用表锁
5.1.2.2)事务涉及多张表,可能造成死锁,引起大量回滚,考虑一次性锁住所有表
5.1.3)页锁: 引擎 BDB
5.2)行锁分类
5.2.1)记录锁:为某行的记录加锁,id为1的记录行会被锁住,id列必须为唯一索引或者主键索引,否则下面语句加的锁会变成临键锁
5.2.2)间隙锁:基于非唯一索引,它锁住的是一段范围内的索引记录。范围条件查询,而不是等值查询,innodb会给已有的数据记录索引项加锁,对于在这个范围内但不存在的记录叫做间隙
给这部分 间隙 加锁 叫做间隙锁。锁定一个范围,但不包括记录本身 RR隔离界别下
间隙锁条件:
1.普通索引锁定
2.使用多列唯一索引
3.使用唯一索引锁住多行数据
5.2.3)临键锁:记录锁+间隙锁,左开右闭合,特殊的间隙锁,通过临键锁可以解决幻读的问题,每个数据行的非唯一索引,都会存一把临键锁,在唯一索引上不存在临键锁 锁定一个范围,并且锁定记录本身
当innodb扫描索引记录时,首先对选中的索引记录加上记录锁,然后对索引记录两遍间隙加上间隙锁
临键锁在以下两个条件时会降级成为间隙锁或者记录锁:
当查询未命中任务记录时,会降级为间隙锁。
当使用主键或者唯一索引命中了一条记录时,会降级为记录锁。
test表中有5条记录,主键值分别为:1,5,8,10,20。那么就会有如下六个间隙:(-∞,1),(1,5),(5,8),(8,10),(10,20),(20,+∞)
select * from test where id>=2 and id<6 for update;
临键锁中锁住的是最后一个命中记录的 key 和其下一个左开右闭的区间那么上面的例子中其实锁住了(1,5]和(5,8]这两个区间。
如果我们执行的查询刚好是id>=2且id<&