属性
说明
Atomitity
一个事务的所有操作,要么全部完成,要么全部不完成,不会结束在中间的某个环节。
Consistency
一致性属性确保任何事务将数据库从一个有效状态带到另一个有效状态。写入数据库的任何数据必须根据所有定义的规则(包括约束,级联,触发器及其任何组合)有效。这不保证程序员可能想要的所有方式的事务的正确性(那是应用程序代码的责任),但只是任何编程错误不能违背定义好的规则
Islation
数据库允许多个并发事务同时对数据进行读写和修改,隔离性可以防止多个并发事务执行时由于交叉执行而导致的数据不一致。事务的隔离级别下文会讲到
Durability
事务树立结束后,对数据的修改是永久的,即便系统故障也不会丢失
问题
说明
Dirty read
指一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问使用了这个数据
Non-repeatable reads
指在一个事务内,多次读同一个数据。在这个事务还没有结束时,另外一个事务也访问该同一个数据并作出提交。那么第一个事务中两次读数据可能是不一样的。他与脏读的区别是,脏读读取到了其他事务还未提交的数据,而这里读取的是另一个事务提交的数据
Phantom reads
第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部行。同时,第二个事务向表中插入一行新数据。那么,操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。他和不可重复读的区别是,不可重复读查询的都是同一项数据,而幻读针对的是一批数据的整体
隔离级别
解释
Serializable
所有的事务串行化执行,每次读都需要获得表级共享锁,读写相互都会阻塞,这是最强的隔离级别,不会出现上述的三种问题
Repeatable Read
在同一个事务中内的多次查询和事务开始时刻都是一致的,该隔离级别消除了不可重复读,但是可能还会出现幻读(可以理解为,可重复读只是保证了针对这一条数据的update事务会被当前可重复读的事务阻塞,而对insert操作的事务则不会被阻塞)
Read Committed
只能读取已经提交的数据。即如果两个事务并发,允许读事务过程中发生写事务的提交。这不能保证可重复读
Read Uncommitted
允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
1.4 Isolation levels & Read phenomenon
Isolation levels
Dirty reads
Non-repeatable reads
Phantoms
Read Uncommitted
may occur
may occur
may occur
Read Committed
don't occur
may occur
may occur
Repeatable Read
don't occur
don't occur
may occur
Serializable
don't occur
don't occur
don't occur
我们常见的数据库系统,其索引使用的数据结构多是B-Tree(此处的横线不是减,只是连接符而已)或者B+Tree。MySql使用的是B+Tree,Oracle使用的是B-Tree。
B-Tree的结构是是一个多叉树,树中的每一个节点的内容是具体的数据(或者指向数据的指针)
B+Tree的结构也是一个多叉树,不同的是树中非叶子节点中存储的是一个范围,而不是具体的数据或指针,树的叶子节点存储真实的数据,并且叶子节点构成一个链表,以方便范围类型的查找
这与磁盘的读写有关,由于磁盘特殊的机械结构,在进行读写的时候都是直接读取一个扇区,数据是以块为单位,这就导致如果我们一个节点中的数据量很少,那就会读取到许多不需要的数据。而如果节点数据很少,每个节点都需要进行磁盘读取将会耗费大量的磁盘IO时间。我们知道磁盘IO是性能的瓶颈所在,所以我们为了减少磁盘读取操作,使用多叉树存储数据,每次读取都是读取树中的一个节点的数据(通常是1K到4K)。这样每次的读取不会出现冗余的数据,而且读取次数也大大减少。
类别
解释
聚集索引
表数据按照索引的顺序来存储,叶子节点即存储了真实的数据行
非聚集索引
表数据存储与索引顺序无关,叶子节点包含索引字段值及指向数据页数据行的逻辑指针
类别
解释
普通索引
基本的数据库索引
唯一索引
数据库索引列的值必须唯一,如果是组合索引,列值的组合必须唯一
主键索引
一种特殊的唯一索引,不允许为空值,一般在建表的时候同时创建主键索引
组合索引
多列组合在一起构成的索引,查询时,只有顺序条件才会生效,如对于A,B, C构成的索引,只有A,AB,ABC这样的顺序条件才会起作用
索引是在Mysql的存储引擎层实现的,而不是在服务层实现的。所以每种存储引擎的索引并不完全相同
类别
解释
B-Tree索引
最常见的索引类型,大部分引擎都支持B-Tree索引
Hash索引
即使用列的Hash值作为索引查找,只用Memory引擎支持,使用场景简单
R-Tree索引
MyISAM的一种特殊索引,主要用于地理空间数据类型
Full-text
全文索引,MyISAM 和 InnoDB 支持
只介绍乐观与悲观锁
对数据被外界修改持保守态度,因此,在整个数据处理过程中,数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制,在对任意记录进行修改前,先尝试为该记录加上排它锁,如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。如果成功则执行修改,完成后解锁。在效率方面,处理枷锁的机制会让数据库产生额外的开销,尤其在几乎没有锁竞争的情况下加锁是在做无用功。
乐观锁假定数据一般情况下不会发生锁冲突,所以在数据进行提交更新时,使用CAS操作监测是否有冲突发生,如果发生了冲突则返回错误信息,让用户决定如何去做(如回滚等)。实现乐观锁的一般有两种方式,一个使用版本号,一个是使用时间戳。乐观锁并发控制相信事务之间的竞争比较少,因此尽可能直接做下去,直到提交的时候才去检查。所以不会产生任何锁和死锁。但是这样对于存在并发的情况下会出现问题。
范式
内容
第一范式
数据库表中的字段都是单一属性的,不可再分
第二范式
数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖,也即所有非关键字段都完全以阿里与任一组候选关键字。比如对于(学号,姓名,年龄,课程名称,成绩,学分)的关系,存在如下决定关系(学号,课程名称)->(姓名,年龄,成绩,学分),还存在如下决定关系(学号)->(姓名,年龄)。这就不符合第二范式
第三范式
每个非关键字都不传递依赖于关系中的候选主键