数据库索引
索引的原理
为什么用索引:
- 1.加快检索速度
- 2.唯一索引可以保证数据的唯一性
索引有缺陷吗?
-
1.索引也占空间
-
2.对数据进行增删改时,还要维护索引
-
3.创建索引和维护索引费时间
索引怎么提高查询速度?
将无序的数据变为有序的数据。就像给数据加了目录
使用索引的注意事项:
- 经常搜索的列上加索引
- 将长需要进行where判断的列上加索引
- 经常需要排序的列上加索引,
- 经常需要连接的列上加索引,加快连接速度
索引使用的主要数据结构
哈希索引
B+树索引
覆盖索引
如果一个索引,包含了所有需要查询的字段,就称为覆盖索引。
最左前缀原则
如果索引是联合索引,如User表的name和city加联合索引就是 (name,city), 如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以 被用到。
事务隔离级别: 隔离级别是通过加锁来实现的。
对数据库的访问通常是很多的,因此数据库一定做了很多支持并发的功能。
READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻 读或不可重复读
READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读 仍有可能发生
REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修 改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务 之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)
Mysql锁
数据库遵循两阶段锁协议,将事务分为两个阶段,加锁阶段和解锁阶段。
- 加锁阶段:对数据进行读之前加共享锁,写之前加排他锁。加锁不成功则进入等待状态。知道枷锁成功才继续执行。
- 解锁阶段:事务释放了一个锁以后,事务进入解锁阶段。该阶段只能进行解锁不能进行加锁操作。 事务 | 加锁/解锁处理 | | -------------------- | ---------------------------------- | | begin; | | | insert into test ….. | 加insert对应的锁 | | update test set… | 加update对应的锁 | | delete from test …. | 加delete对应的锁 | | commit; | 事务提交时,同时释放insert、update、delete对应的锁
如果不显示的用begin开启事务,执行语句时,会自动上锁。 用bigin显示开启事务,就会加锁,需要等commit后才会释放锁。不然就会不满足事务的隔离性,数据会在中途被其他事务修改。
意向锁:
假如有一个事务在执行,锁了某一行,这时候又执行了DDL语句,给表加一个字段,需要锁表,但是由于表里有一行记录被锁住了,锁表就会阻塞。 那么mysql在锁表时又是怎么知道有行锁呢? 如果是遍历每一行看是否有锁,性能就太差了。 mysql是怎么做的? 其实在获取行锁前,会先获取一个意向锁,表示将要加行锁。这样mysql判断行锁就不需要遍历了,只需要判读以下是否有意向锁就行了。