数据库底层工作原理学习笔记
连接有三种方式
(假设外表N比内表M数据多)
循环连接:外表取一个或一块数据,分别和内表的一个或一块数据进行匹配。次数为:外+外*内或 外快数+外块数*内块数。
hash连接:内表字段建hash表,每bucket桶尽量平均分配,外表每个字段会进入一个桶,查询桶中是否有匹配。次数为:外+ 每次桶内查找次数[0-内/桶量]的累加 +内表字段建立哈希表的时间+外*每个外元素在内表hash找到桶的时间。如果hash足够有效即桶数足够多,复杂度是o(外+内)。解释:hash是hash的两表的这份关联,不是单一某个表,hash之后桶区间大小均匀分布。桶足够小时,就有外N个桶,有的桶有元素有的桶是空,总取次数为外+内。
归并连接:先进行排序,然后归并。如果没排序,归并排序需要用o(外*log(外)+内*log(内)),底数是2。归并连接用时o(外+内)
事务处理:
Wal Write-Ahead Logging protocol 1必须先日志再执行;2日志保持顺序;3commit先日志再执行。
隔离等级:
序列化:每个事务在单独世界里。
可重读 每个事务在单独世界里,除了增加数据会被所有事务看到。其它操作不会。
读提交 每个事务提交的数据都会被所有事务看到。
读未提交/脏读 每个事务未提交的数据可以被所有事务看到。
所有操作保存在事务log里。先写事务log 缓存,再写数据缓存,外部函数返回,log缓存写盘,数据缓存写盘。
特别的,log里边记录了本次操作的撤销方式,这种方式是reverse operation to goback to the privious stata(logical UNDO)。还有一种是保存原来的数据,操作复杂不被采用。所以主流数据库(ARIES)会有机制使数据撤销时回到之前的状态。
FOCE commit之前数据必须写好。NO-FOCE数据可以在commit之后写。
STEAL 在commit之前数据就开始一点一点地写盘。NO-STREAL 等到commit的时候一次写完。
一般数据库用NO-FOCE/STEAL
缓存里保存着当前事务表和脏数据页组成的表格,并且时不时把这些表格写进磁盘。
事务发生一般错误,或者网络错误,就会参照这些表格进行回滚。
如果发生宕机,根据log磁盘记录恢复 当前事务表和脏数据页表 没备份到磁盘的部分。备份到磁盘的部分直接读取恢复两个表的缓存。
学习链接:(英文版用的句子和单词都很简单,除了那几个经常见到的专用词没别的,所以很容易读懂。也可以对照着读,读英文的含义地道一点。)
英文原版:http://coding-geek.com/how-databases-work/#Query_optimizer
中文翻译:https://www.kancloud.cn/devbean/how-databases-work/145502
mysql是可重读,通过多版本控制(mmvc)实现。多版本控制设有系统版本号,表里的每一行数据都有创建和失效时的版本号,没有失效的是未定义。事务开始时获取版本号,只能操作创建版本号<=本事务版本号<失效版本号。
事务开始后,另一个事务提交的:
insert创建版本号大,不会不看到,于是没有幻读;update会让旧数据失效,从新增加一行数据和一个新的创建版本号,不会被看到;delete的创建版本号小的话,加上本来失效版本号大,会被看到。(参考园友的MMVC讲解)

浙公网安备 33010602011771号