概论:
利用JDBC driver和MySQL数据库建立TCP连接之后的连接对象放在池中,当需要操作数据库的时候从池中取出一个连接,发送SQL到MySQL,MySQL经过SQL语法解析、查询优化、生成实际物理计划及执行、连接处理与类型处理等一系列的过程之后返回要查询的数据给JDBC driver的resultset。把连接对象重新放到池子中
tcp建立连接的过程
握手 挥手 ┏(^0^)┛- tcp udp(网络协议)
7层协议(实际用到4层)
线程池相关(线程池以及各种池化好处)
常用的数据库连接池
参数min、max、active
数据库ACID
A:原子性(Atomicity)
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
就像你买东西要么交钱收货一起都执行,要么要是发不出货,就退钱。
C:一致性(Consistency)
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
I:隔离性(Isolation)
指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
redolog undolog( InnoDB )
InnoDB是mysql的一个存储引擎,大部分人对mysql都比较熟悉,这里简单介绍一下数据库事务实现的一些基本原理,在本地事务中,服务和资源在事务的包裹下可以看做是一体的:
我们的本地事务由资源管理器进行管理:
而事务的ACID是通过InnoDB日志和锁来保证。事务的隔离性是通过数据库锁的机制实现的,持久性通过redo log(重做日志)来实现,原子性和一致性通过Undo log来实现。UndoLog的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为UndoLog)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。 和Undo Log相反,RedoLog记录的是新数据的备份。在事务提交前,只要将RedoLog持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是RedoLog已经持久化。系统可以根据RedoLog的内容,将所有数据恢复到最新的状态。
事务隔离级别 悲观、乐观、间隙锁(见上一篇)
分布式事务(强一致or最终一致)
ACID和CAP的 CA是一样的吗?
分布式事务常用的解决方案的优缺点是什么?适用于什么场景?
分布式事务出现的原因?用来解决什么痛点?
C一致性,A可用性,p分区容错性
CP( 一致+分区容错性 ) : zookeeper追求强一致。
TCC(Try-Confirm-Cancel)
本地消息表(ebay通过消息日志异步执行任务)最终一致模型
MQ( 在RocketMQ中实现了分布式事务,实际上其实是对本地消息表的一个封装,将本地消息表移动到了MQ内部 )
索引
数据结构( B-TREE、2-3树、红黑树、 AVL树)
数据库的索引可以使用哈希基础的算法和树状结构的算法等。B树是一种数据库常用的算法,它是为磁盘而设计的一种平衡搜索树。和二叉树相比B树是个多叉树,每个结点包含多个子结点。本文主要讨论B树和其变体B+树。
为什么使用B树
磁盘的读写速度比主存慢得多,读写时寻道和预旋转时间占用较多,顺序读效率较高。所以磁盘会每次存取多个连续数据项而不是一个。数据被分为多个页来存取。
一个B树的结点存储在一个磁盘页中,页的大小限制了B树的孩子数量。B树每个结点通常有50到2000个子结点,这大大降低了树的高度,从而减少了每次查询所需的磁盘IO次数。
B+树还有一个好处是数据是排序的,能支持区间查询。排序的数据在查询连接时也很有用(多路归并)。
即使在SSD流行的今天,B树仍然是最合适的数据库索引。
B树
B树的每个结点存储n个关键字x.key1,..x.keyn,它们是排序的。关键字对存储在子树中的关键字范围加以分割。每个结点包含的关键字数量有上界和下界,从t到2t-1。
B+树
B+树是B树的变体。B树的数据项可能存储在中间结点上,B+树的数据项只能存储在叶结点上。虽然B树在某些查询上能更快,但是B+树的结点存储的分支更多,树的高度更小,平均性能更好。
B+树将叶子结点串联起来,这样方便对数据进行顺序扫描。
我们代码中实际使用的是B+树,以下将不区分B+树和B树。
B树的搜索
B树结点中每个key是排序的,搜索时用二分查找来找到对应区间,获取到对应子结点的指针。
平衡调整
插入数据的时侯,如果当前结点满,则调整到兄弟结点,或者分裂出新兄弟结点。可以用单程向下的方式插入数据,来避免递归。不同于AVL树,B树新层的产生都发生在根结点上。
分裂、合并之类的套路和AVL树有些不同,不需要旋转之类的操作,非常简单。
B树调整平衡之所以简单高效,是因为它不像AVL那样要求完全平衡,而是有t到2t-1的容忍度。
B树详细的插入、删除操作过程不再多说,任何一本数据结构和算法的书中都会有。
代码结构
BTree类负责提供B树的搜索和插入。
RBNode表示B树的只读结点。
WBNode表示B树的读写结点。
BTreeIterator用来扫描B树叶结点中存储的数据项。
每个结点的指针即是页的ID。为了能支持变长字符串Key,结点存储在页的前半部分,key的字符串集中存放在后半部分,key的位置只保存字符串的偏移地址。
数据库表存储
一个数据库可以建多张表,我们把数据文件第0页留出来,专门存放数据库表的元信息。元信息包括但不限于表名称、表各字段和类型、表拥有的索引、BTree的root结点ID等。
有些数据会单独把记录数据存储在其他地方,BTree中只存储记录的地址。我们这里直接把每行记录组成的记录数据(这里暂时用JSON格式存储)保存在BTree的叶结点中
引用资料链接:
https://zhuanlan.zhihu.com/p/30132610
https://blog.csdn.net/panweiwei1994/article/details/78969238
https://zhuanlan.zhihu.com/p/41891052
网友评论