在此先感谢开源社区的伙计们为我提供非常优秀的理论文档,但在此深表感谢,
正是有你们的无私和博学,人类才能在科学美丽的道路上不断前进。
Eric Niebler, Kevlin Henney,Chris Kohlhoff,John Maddock, Howard Hinnant ,Jeff Garland
First of all,thanks to the open source community guys
to provide the excellent documentation of the database theory for me,
For your selfless and erudite, human can promote himself persistently in the beautiful
road of science.
Eric Niebler, Kevlin Henney,Chris Kohlhoff,John Maddock, Howard Hinnant ,
Jeff Garland
说明:以下文档非专业文档,也非严谨学术论文,只是我在解读数据库技术资料时的自身理解,可能有不少的错误,希望各位高手大侠指正,
首先,我们先明确下VDBE的概念,其实我们在执行sql的过程中,比如Insert的语句时,是由VDBE将命令分拆成数据操作的原子指令(instruction),VDBE将其解析,拆分,排序,才执行出我们最后的结果。而VDBE可以理解为解析这些虚拟机器指令,并执行机器操作的虚拟机。VDBE可以说是数据库技术中最核心的技术,我们完善了一个数据库的VDBE,那么我的征途就胜利了一半了。
但令我惊奇的是VDBE没什么难以理解的高深知识,先人将一个复杂的系统用简单的方法巧妙的实现了。
在这个数据库虚拟机中,每一种指令(instruction)都虚拟机中都是固化的,就是说每一种一执行都是按照固定的逻辑去操作,而每一种指令(instruction)都有五种或数种数据操作(operand)作为操作的参数(我的理解)。而这数种数据操作都是跟虚拟机中的注册机(register)*注1*相关联的。
以下是sqlite文档中提供的数据库指令操作的实例
比如 delete from tbl1 where two<20;
我们执行以上这条简单的语句。
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- --------- -- -------
1 Goto 0 20 0 00
2 OpenRead 0 2 0 00 tbl
3 SetNumColumns 0 2 0 00
4 Rewind 0 11 0 00
5 Column 0 1 2 00 tbl.two
6 Integer 20 3 0 00
7 Ge 3 10 2 cs(BINARY) 6a
8 Rowid 0 1 0 00
9 FifoWrite 1 0 0 00
10 Next 0 5 0 00
11 Close 0 0 0 00
12 OpenWrite 0 2 0 00 tbl
13 SetNumColumns 0 2 0 00
14 FifoRead 1 18 0 00
15 NotExists 0 17 1 00
16 Delete 0 1 0 tbl 00
17 Goto 0 14 0 00
18 Close 0 0 0 00
19 Halt 0 0 0 00
20 Transaction 0 1 0 00
21 VerifyCookie 0 1 0 00
22 TableLock -1 2 0 tbl 00
23 Goto 0 2 0 00
数据库中执行以上机器指令列表
其中的opcode就是如上说的机器指令,而 p1,p2,p3,p4,p5 就是数据操作,我将其理解为我们程序中函数的参数。
我先逐个介绍下指令的功能
Goto:跳转至p2所指的指令地址(Addr)
Transaction:这个我们很眼熟,开启一个事务,P1是数据库的Id,0为主数据库,1,2为附加关联的数据库,如果
P2为非0值,代表一个写事务开始执行,这时操作会提交一个(RESERVED lock)乐观锁,没有一个进程可以执行写
事务。如果P2大于等于2,那么事务会提交一个(EXCLUSIVE lock)悲观锁,即其他进程不能读也不能写。
OpenRead:为一个数据表打开一个只读的数据库游标,根数据叶(root page)是数据操作P2。
Rewind:读取数据表或索引的第P1个实体,如数据表或索引为空,且P2大于0,指令地址跳转至p2,如果P2为0并数据表
或索引为空跳转至下一个地址的指令。
SetNumColumns:根据P2设定游标的列数
等等,指令的意思就不一一解释了,有兴趣的同学可以参看sqlite文档,
该内容也相当重要,也许在后面的版本我会将指令的内容补全
VDBE正是将一个个简单的数据操作,执行出delete from tbl1 where two<20;的动作。
那么我们可以知道了VDBE究竟做了什么东西
从图上我们可以看到,我们数据库的内核是由三部分构成,
1,实现我们熟悉嵌入sql语句的c\c++接口。
2,将sql语句解析成各个虚拟机指令(instruction),多亏了SQLite我们有一个优秀的解析器可以借鉴。
3,由VDBE去实现各个机器指令的算法。说白了就是一个又一个的C函数。
注1:又一个重要的机制,我稍后补充文档。