数据库
数据库⭐MySQL 默认存储引擎InnoDB(事务性存储引擎)一、事务 数据库事务? 数据库事务有什么作用? 数据事务的实现原理: ⭐关系型数据库支持事务的四大特性(ACID)并发事务带来的问题:事务隔离级别:⭐MyISAM和InnoDB区别数据库索引索引优缺点索引底层数据结构Hash索引存在问题(MySQL没有使用Hash索引)B树 多路平衡查找树B+树(ISAM和InnoDB引擎使用)聚集索引非聚集索引覆盖索引MVCC(Multi-Version Concurrency Control)多版本并发控制
⭐MySQL 默认存储引擎InnoDB(事务性存储引擎)
一、事务
逻辑上的一组操作,要么都执行,要么都不执行。
数据库事务?
如果没有特指分布式事务,往往指的就是数据库事务。
数据库事务有什么作用?
保证多个对数据库的操作(也就是 SQL 语句)构成一个逻辑上的整体。构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行 。
数据事务的实现原理:
MySQL InnoDB引擎使用redo log(重做日志)保证事务的持久性,用undo log(回滚日志)保证事务的原子性,通过锁机制、MVCC保证事务的隔离性(默认支持的隔离性是重复读)。保证了事务的持久性、原子性、隔离性之后一致性才能得到保障。
⭐关系型数据库支持事务的四大特性(ACID)
-
原子性(Atomicity): 事务是最小的执行单位,不允许分割。
-
一致性(Consistency): 执行事务前后,数据保持一致。
-
隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其它事务所干扰,各并发事务之间数据库独立。
-
持久性(Durability):一个事务被提交后,它对数据库中数据的改变是持久的,即使数据库发生故障也不该对其有任何影响。
并发事务带来的问题:
❓ 都没提到隔离级别与丢失修改的关系。
-
脏读(Dirty read):一事务访问数据并修改,但还未提交数据库。另一事务也访问并使用这个数据,则读到这个未提交到数据库的 "脏数据"。
-
丢失修改(Lost to modify): 一事务读取一数据,另一事务也读取该数据。第一个事务中修改了这个数据后,第二个数据也修改了这个数据。这样第一个事务内的修改结果就被丢失。
-
不可重复读(Unrepeatable read): 指在一个事务内多次读同一数据,在这个事务还没结束时。另一个事务也范围更改数据。那么第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。
-
幻读(Phantom read):一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入(删除)了一些数据。随后查询中,T1发现多了一些原本不存在的记录。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ-UNCOMMITTED | √ | √ | √ |
READ-COMMITTED | × | √ | √ |
REPEATABLE-READ | × | × | √ |
SERIALIZABLE | × | × | × |
事务隔离级别:
-
读取未提交:最低隔离级别,允许读取尚未提交的数据。
-
读取已提交:允许读取并发事务已经提交的数据,可阻止脏读,但幻读和不可重复读会发生。
-
(默认级别)可重复读:对同一字段多次读取结果一致。除非数据是被本身事务自己所修改。可阻止脏读和不可重复读,但会出现幻读。
-
可串行化:最高隔离级别,完全服从ACID。所有事务一次逐个执行。可阻止脏读、不可重复读、幻读。
MySQL InnoDB 的 REPEATABLE-READ(可重读)并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是 Next-Key Locks。
因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 READ-COMMITTED(读取提交内容) ,但是你要知道的是 InnoDB 存储引擎默认使用 REPEAaTABLE-READ(可重读) 并不会有任何性能损失。
InnoDB 存储引擎在 分布式事务 的情况下一般会用到 SERIALIZABLE(可串行化) 隔离级别。
InnoDB 存储引擎提供了对 XA 事务的支持,并通过 XA 事务来支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源(transactional resources)参与到一个全局的事务中。事务资源通常是关系型数据库系统,但也可以是其他类型的资源。全局事务要求在其中的所有参与的事务要么都提交,要么都回滚,这对于事务原有的 ACID 要求又有了提高。另外,在使用分布式事务时,InnoDB 存储引擎的事务隔离级别必须设置为 SERIALIZABLE。
⭐MyISAM和InnoDB区别
MYISAM | INNODB |
---|---|
只支持表级锁 | 支持行级锁(默认)和表级锁 |
不提供事务支持 | ①提供事务支持,②具有提交(commit)和回滚事务(roll back)的能力 |
不支持外键 | 支持 |
不支持数据库异常崩溃后的安全恢复 | 依赖redo log,在数据库异常崩溃后,数据库重新启动的时候会保证数据库恢复到崩溃前的状态 |
不支持MVCC | 支持 |
一般我们也是不建议在数据库层面使用外键的,应用层面可以解决。
不过,这样会对数据的一致性造成威胁。具体要不要使用外键还是要根据你的项目来决定。
InnoDB 存储引擎的锁的算法有三种:
- Record lock:单个行记录上的锁
- Gap lock:间隙锁,锁定一个范围,不包括记录本身
- Next-key lock:record+gap 锁定一个范围,包含记录本身 ❓记录本身是什么
数据库索引
索引优缺点
优点:1.加快数据检索速度。2.通过创建唯一索引,保证数据库表中每一行数据唯一性。
缺点:1.创建和维护索引耗费时间,增删改时,索引需要动态修改。2.索引需要物理文件存储,会耗费空间。
索引一定能提高查询性能吗? 大多数情况下,索引查询都是比全表查询要快的。但是如果数据库数量不大,那么使用索引也不一定能够带来很大提升。
索引底层数据结构
Hash、B树、B+树
Hash索引存在问题(MySQL没有使用Hash索引)
-
Hash冲突
-
Hash不支持顺序和范围查询⭐
B树 多路平衡查找树
所有节点既存放外键(key),也存放数据(Data)。叶子节点独立。检索相当于对关键字做二分查找,可能未到叶子节点,检索结束。
B+树(ISAM和InnoDB引擎使用)
只有叶子节点key+data,内节点只有key。叶子节点有一条引用链指向它相邻的叶子节点,检索效率稳定,任何查询都是根到叶,叶子节点顺序检索明显。
MyISAM引擎: B+ Tree叶节点的data域存放数据记录的地址,非聚簇索引
InnoDB引擎:数据本身就是索引文件,叶节点data保存完整数据记录。表数据文件就是主索引。聚簇索引
辅助索引的data域存储主键的值
∴主索引搜索时,直接找到key所在节点即可取出数据
辅助索引搜索(二级索引),要先取主键的值,再走一遍主索引
- 唯一索引、普通索引、前缀索引、全文索引
聚集索引
聚集索引:索引结构和数据一起存放的索引
主键索引属于聚集索引
优点 | 缺点 |
---|---|
查询速度快,整个B+树本身时一棵多路平衡树叶子节点有序,定位到索引的节点就定位到了数据 | 1.依赖有序数据 2.更新代价大 |
非聚集索引
索引结构和数据分开存放的索引,叶子节点存放主键,根据主键再回表查数据
优点 | 缺点 |
---|---|
更新代价小 | 1.依赖有序数据 2.可能❓会二次查询(回表) |
覆盖索引
一个索引包含/覆盖所要查询的字段的值,即需要查询的字段正好是索引的字段,可直接根据索引查到数据。
MVCC(Multi-Version Concurrency Control)多版本并发控制
实现读——写冲突不加锁
提高数据库并发性能,处理读——写冲突,即使有读写冲突时,也能做到不加锁,非阻塞并发读
MVCC 可以看作是行级锁的一个升级,可以有效减少加锁操作,提供性能。
①当前读 (悲观锁的实现)
②快照读
网友评论