一、事务
1. 数据库事务:是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
2. 数据库事务特性
① 原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
② 一致性:事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义时数据库中的数据应满足完整性约束
③ 隔离性:多个事务并发执行时,一个事务的执行不应影响其他事务的执行
④ 持久性:已被提交的事务对数据库的修改应该永久保存在数据库中
3. 脏读、幻读、不可重复读
① 脏读:读到其他事务未提交的数据
② 幻读:在一个事务中前后读取的数据总量不一样,例如前后行数不同
③ 不可重复读:在一个事务中前后读取数据不一样,即读到其他事务已提交的数据
4. 封锁类型
① 排它锁(X锁、写锁):事务T对数据对象加上X锁,则只允许T读取和修改A,其他任何事务都不能在对A加任何类型的锁,直到T释放A上的X锁
② 共享锁(S锁、读锁):事务T对数据对象加上S锁,则T可以读取但不能修改A,其他事务只能再对A加S锁,不能加X锁,直到T释放A上的S锁
其他:③ 多版本并发控制 MVCC :用来解决读-写冲突的无锁并发控制。为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联。读操作只读该事务开始前的数据库快照。这样读操作不会阻塞写操作,写操作不会阻塞读操作的同时,避免了脏读和不可重复读。
④ 乐观并发控制 OCC:用来决解写-写冲突的无锁并发控制。认为事务间的争用没有那么多,所以先进行修改,在提交事务前,检查一下事务开始后有没有新提交,如果没有则提交;如果有则放弃并重试。默认读数据时不会修改,所以不会上锁;适用于多读写比较少的情况,省去锁的开销,加大体系吞吐量
⑤ 悲观锁:是真正的锁。在获取资源前对资源加锁,确保同一时刻只有有限进程能够访问该资源,其他想要获取资源的操作都会进入等待状态,直到该线程完成了对资源的操作并释放锁后,其他线程才能重新操作资源
5. 事务的隔离级别和四级封锁协议
事务是定义和维护一致性的单位,封锁就是要保证这种一致性。如果对封锁的要求高会增加开销、降低并发性和效率;有的事务并不严格要求结果的质量,如果加上严格的封锁则是不必要和不经济的。因此有必要进行进一步的分析,考察不同级别的一致性对数据库数据的质量及并行能力的影响
隔离级别:
① READ UNCOMMITTED(未提交读):在读数据时不检查或使用任何锁,无法解决脏读、不可重复读、幻读
② READ COMMITTED(已提交读):只读取提交的数据并等待其他事务释放排它锁。读数据的共享锁在读操作完成后立即释放
③ REPEATABLE READ(可重复读):与已提交读那样读数据,但会保持共享锁直到事务结束
④ SERIALIZABLE(可序列化):类似于可重复读,但不仅会锁定受影响的数据,还会锁定这个范围,防止其他用户在事务完成之前更新数据集或将行插入进数据集内
四级封锁协议:
① 一级:事务在对需要修改的数据上面对其加共享锁(S),直到事务结束才释放
② 二级:事务在对需要更新的数据上加排它锁(X),防止其他事务读取未提交的数据。事务对当前被读取数据加共享锁(S),一旦读完立即释放该行的共享锁。(避免脏读)
③ 三级:二级+事务在读数据时必须先加共享锁(S),直到事务结束再释放(保证可重复读)
④ 四级:事务读取/更改的数据所在表加表锁,其他事务不能读写该表中的任何数据
6. 死锁
死锁:多个进程因竞争共享资源而造成的一种僵局,若无外力作用,这些进程将永远不能向前推进
① 原因:a. 竞争系统资源 b. 进程推进顺序不当
② 产生死锁必要条件(破坏必要条件):
a. 互斥条件:一个资源每次只能被一个进程使用
b. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放(破坏:采用资源预先分配策略,进程运行前申请全部资源,满足则运行,否则等待)
c. 不剥夺条件:进程已获得的资源,在未使用完之前不能强行剥夺(破坏:进程申请不到一个资源,则释放所占有全部资源 )
d. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系(破坏:实现资源有序分配,进程只能采用按序号递增形式申请资源)
③ 避免死锁 vs. 预防死锁
避免死锁:不严格限制死锁产生的必要条件,是在系统运行过程中注意避免死锁的最终发生。
预防死锁:破坏产生死锁的必要条件,严格防止死锁出现
二、索引
1. 什么是数据库索引?索引优缺点?
是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。在没有索引的情况下,数据库会遍历数据后选择符合条件的;有索引后,数据库会直接现在索引中查找符合条件的选项。(一般数据库默认都会为主键生成索引)。
优点:可以加快搜索速度
缺点:索引文件越大,占用空间越多。由于底层索引大多是B+树等平衡多叉树,为了维护平衡,增删的时间效率很差
2. 索引的底层数据结构及各自特点
B树和B+树都是平衡多叉树。B树的节点保存索引和关键字;B+树的非叶子节点保存索引,叶子节点保存关键字的有序链表。
① B树的特性:关键字集合分布在整棵树中;任何一个关键字出现且只出现在一个节点中;搜索可能在非叶子节点结束;搜索性能等价于在关键字全集内做一次二分查找;自动层次控制
② B+树特性:所有关键字都出现在叶子节点的链表中,且链表的关键字恰好时有序的;不可能在非叶子节点命中;非叶子节点相当于叶子结点的索引,叶子节点相当于存储数据的数据层;更适合文件索引系统
③ 红黑树:红黑树每个节点只有两个子节点,树的深度过大,造成IO读写频繁,效率低下
为什么B+树比B树更适合数据库索引?
① B+树空间利用率更高:B+树内部节点值作为索引使用,而不像B树每个节点都需要存储硬盘指针。
② 增删文件(节点)时B+树效率更高:因为叶子节点包含所有关键字,且有序链表存储
③ B+树查询效率稳定:任何关键字的查找都必须走一条从根节点到叶子结点的路
④ B+树更便于范围查询:B树在提高了IO性能的同时并没有解决元素遍历的效率低下的问题,正是为了解决这个问题B+树应运而生。B+树只需要遍历叶子节点就可以实现整棵树的遍历。而且数据中基本范围的查询是非常频繁的。
3. Mysql中的索引类型和区别
① 普通索引:最基本的索引,没有任何限制
② 唯一索引:索引列的值必须唯一,允许空值
③ 主键索引:特殊的唯一索引,不允许有空值
④ 全文索引:仅可用于MyISAM表,用于在一篇文章中检索文本信息,针对较大的数据生成全文所很耗时耗空间
⑤ 组合索引:为了更多的提高MySQL效率可建立组合索引,遵循“最左前缀”原则
4. 聚簇索引 vs 非聚簇索引
① 聚簇索引一个表只有一个;非聚簇索引一个表可以存在多个
② 聚簇索引的顺序是数据的物理存储顺序;非聚簇索引是逻辑上连续,物理存储上不连续。
本质区别:B+树的叶子节点储存的是行数据还是索引(聚簇索引的key值)
(MyIASM只有非聚簇索引;Innodb既有聚簇索引又有非聚簇索引)
例如:user表中有 id、name、age 三列。id是自增主键,name是普通索引
a. 执行 select * from user where id = 1 时,会在主键索引对应的B+树的叶子节点上搜索id = 1的整行数据
b. 执行 select * from user where name = 'tom' 时,会先在name索引对应的B+树节点上搜索name = 'tom'的节点,并获取对应的主键id值。再根据id使用主键索引读取到整行数据(回表查询)
c. 执行 select id, name from user where name = 'tom' 时,只需要扫描name索引树,因为id也存在树里
5. 索引的最左前缀原则
建立联合索引时要选择索引的顺序。例如索引 index1:(a,b,c),只会走a、ab、abc三类查询
特殊情况: ① ac查询会走index1索引,但只走a字段索引,不走c
② select * from table where a = '1' and b > ‘2’ and c='3' 只走a、b索引,不走c。因为索引时有序的,index1索引回先根据a排序,再根据b,最后根据c排序。但走完a、b索引后,c肯定无序了,数据库会觉得还不如全表扫描c字段快
6. 数据库索引实现原理 (5条消息) 数据库索引实现原理_pocher的博客-CSDN博客_数据库索引原理
三、Other
1. 数据库范式
① 第一范式:数据库表中的所有字段值都是不可分解的原子值
② 第二范式:确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关。
③ 第三范式:确保每列都和主键列直接相关,而不是间接相关
2. 数据库引擎
① Innodb:提供了对数据库事务、行级锁和外键的支持,并实现了四种隔离级别。MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引(不支持全文索引)。没有保存表的行数,count(*) 需要扫描全表。当需要使用数据库事务时,Innodb是首选。由于锁的粒度更小,写操作不会锁定全表,所以并发较高时,可以提升效率。但如果执行sql时不能确定要扫描的范围,Innodb同样会锁全表。
② MyIASM(MySQL默认引擎):不支持事务、行级锁和外键,要锁整个表,效率第一点。存储了表的行数,count(*)只需要读取已经存好的值,不需要全表扫描。
Innodb适合插入删除操作多的场景;MyIASM适合查询操作多的场景。
3. sql语句的执行过程
数据库引擎检查语法、语义;对查询对象加锁;访问权限核对;确定最佳执行计划
关键字执行顺序:① 首先Where将原始记录中不满足条件的记录删除(所以应该在where中尽量将不满足条件的记录筛掉,这样可以减少分组)
② 通过Group By关键字后面指定的分组条件将筛选得到的试图进行分组
③ 接着系统根据Having关键字后面指定的筛选条件,将分组视图后不满足条件的记录筛掉
④ 然后按照Order By语句对试图进行排序
4. 海量数据数据库分库分表
分表能解决单表数据量过大带来的查询效率下降问题,但无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,要对数据库进行拆分,从而提高数据库写入能力。分库/分表可以财通通过一个关键字取模的方式,来对数据访问进行路由。
① 垂直切分:原表A B C;分表 A C;A B
② 水平切分:原表A B C(1-100);分表A B C(1-50);A B C(51-100)
5. 关系型数据库 vs. 非关系型数据库(nosql)
① 关系型数据库:采用了关系模型(表)来组织数据。
优点:易于维护;使用方便;支持sql可实现复杂操作。
缺点:读写能力差;灵活度不高;高并发读写需求是瓶颈
② 非关系型数据库:优点:格式灵活:可以是key-value、文档、图片等,应用场景广泛;速度快:nosql可以用硬盘或者内存作为载体,关系型数据库只能用硬盘;高扩展性;成本低
缺点:不支持sql;无事务处理;数据结构相对复杂
6. Mysql vs. Redis
① Mysql:是关系型数据库,数据存放在磁盘
② Redis:非关系型数据库,数据存放在内存,提高了访问速度
一般写数据直接用mysql,读取用redis。mysql - > redis同步用的比较多。Mysql作为数据持久化和管理,Redis用来做数据读取缓存、队列、锁等。
7. 数据库连接池
在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接的获取和返回方式
① 资源重用:连接池里的连接可以重复使用,避免频繁创建、释放连接引起的大量性能开销
② 更快的系统响应速度:避免数据库连接初始化和释放过程的时间开销,缩短系统整体响应时间
8. 主从架构
当客户端发起读写请求时,从mysql服务进行读写数据。假设有三台mysql服务,一台作为主master服务,另外两台作为从salve。master拥有读写的权限,主要承担了写的工作;salve只有读的权限,主要承担了读的操作。当客户端发起请求时,会将请求分流,实现读写分离
优点:读写分离,分担了单台数据库或单台服务器的压力
缺点:主从延时,可能会导致数据的不一致性
9. drop vs. delete vs. truncate
① 执行速度:drop > delete > truncate
② delete语句执行删除过程是从表中删除一行,同时将该删除操作作为事务记录在日志中保存以便进行回滚操作
truncate table 一次性从表中删除所有数据,不走事务,不会激活与表有关的删除触发器,执行速度快
③ truncate 和 delete 只删除数据,不删除表结构;drop删除整个表(结构 和 数据)
④ delete是数据库操作语言(dml),走事务;truncate 和 drop 是数据库定义语言(ddl)操作立即生效
10. 数据库-行存储及列存储区别 (5条消息) 数据库-行存储及列存储区别_^果然好^的博客-CSDN博客_列式数据库的优缺点