SQLite学习(九) - 虚拟机指令2

前端之家收集整理的这篇文章主要介绍了SQLite学习(九) - 虚拟机指令2前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文介绍sqlite虚拟机指令的版本是2.8.0. sqlite3以及以后版本的虚拟机概念上是一样的。但是一些操作码,操作数用法,个数有所改变,算法也有所不同。VDBE虚拟机语言,类似汇编语言,VDBE的每天指令由一个opcode3operand组成(sqlite3以后有5)下面看个例子来学习。

1 INSERT sql

CREATE TABLE examp(one text,two int);

INSERT INTO examp VALUES('Hello,World!',99);
通过
explain指令,我们可以得到这条INSERT sqlVDBE指令

$sqlitetest_database_1
sqlite>CREATETABLEexamp(onetext,twoint);
sqlite>.explain
sqlite>EXPLAININSERTINTOexampVALUES('Hello,99);
addropcodep1p2p3
-------------------------------------------------------------
0Transaction00
1VerifyCookie081
2Transaction10
3Integer00
4OpenWrite03examp
5NewRecno00
6String00Hello,World!
7Integer99099
8MakeRecord20
9PutIntKey01
10Close00
11Commit00
12Halt00

这个INSERT12条指令完成,头3条指令和最后2条指令时标准指令,每个sql都会有这几个指令。实际完成INSERT操作的是中间的7条指令。下面我们来逐条分析。

(1)开始执行
0Transaction00
1VerifyCookie081
2Transaction10


Transaction
开始一个事务。P1数作用的数据库id0表述main database.databases指令可以查看数据库的情况。第二个Transaction指令在rollback journal上创建一个事务。

sqlite> .databases
seqnamefile
----------------------------------------------------------------------------
0main

VerifyCookie指令验证下P1数据的cookie值与P2值相同,保证修改之前这个数据库没有被其他线程修改过。以免读脏数据或覆盖已更新数据。

(2)打开游标
3Integer00
4OpenWrite03examp

Integer指令将P1=database id pushVDB Stack中。如果P3不为NULL,它的值就是database名字的string
OpenWrite
指令打开一个read/write的游标。P1=0 table idP2=3 table所在页page id

(3)写入db文件
5NewRecno00//创建一个新的record id,并压入栈
6String00Hello,World!//P3值压入栈
7Integer99099//将值99压入栈
8MakeRecord20//将栈中的top P1=2个元素弹出,转换成二进制(用于写入db文件),压入栈。
9PutIntKey01
//pop栈中的2个元素,写入db文件P2=1表示改变的元素个数。

(4)
结束
10Close00
//关闭游标
11Commit00
//提交所有update,deletes the journal file and releases the write lock on the database. A read lock continues to be held if there are still cursors open.
12Halt00
//VDB engine exit

2SELECT查询

sqlite>EXPLAINSELECT*FROMexamp;
addropcodep1p2p3
-------------------------------------------------------------
0ColumnName00one
1ColumnName10two
2Integer00
3OpenRead03examp
4VerifyCookie081
5Rewind010
6Column00
7Column01
8Callback20
9Next06
10Close00
11Halt00

如果熟悉sqlite API就知道有一个callback函数
int Callback(void *pUserData,int nColumn,char *azData[],char *azColumnName[]);

VDBE的任务就是传入后三个参数
int nColumn返回的column个数
char *azData[]返回data
char*
azColumnName[] column名数组

(
1)开始执行准备要返回的column
0ColumnName00one
1ColumnName10two


ColumnName指令将column名字传入azColumnName字符串数组,然后后面会有相应的column指令将值传入

(2) 打开游标


2Integer00
3OpenRead03examp
//打开一个只读的游标
4VerifyCookie081


(3)
循环

5Rewind010初始化一个循环,将游标移到P1指向的数据库的第一个entery然后Column and Next指令会用这个游标来轮询整个table。如果是空表,就直接跳转P2=10指向的地址。

6Column00P2=0th column压入栈
7Column01
P2=1th column压入栈
8Callback20
//从栈中弹出P1=2个元素,传入azData
9Next06//
循环跳转到第p2=6条指令,继续执行

3. sqlite3版本的生成的指令
指令稍有改动,基于上面的分析还是可以看懂的,具体每个指令用法可以看指令参考http://www.sqlite.org/opcode.html

sqlite> EXPLAIN INSERT INTO examp VALUES('Hello,99);

addropcodep1p2p3p4p5comment
---------------------------------------------------------
0Trace00000
1Goto010000
2OpenWrite020200
3NewRowid01000
4String8020Hello,World!00
5Integer993000
6MakeRecord224ad00
7Insert041examp1b
8Close00000
9Halt00000
10Transaction01000
11VerifyCookie01000
12TableLock021examp00
13Goto02000

sqlite> EXPLAIN SELECT * FROM examp; addropcodep1p2p3p4p5comment --------------------------------------------------------- 0Trace00000 1Goto010000 2OpenRead020200 3Rewind08000 4Column00100 5Column01200 6ResultRow12000 7Next04001 8Close00000 9Halt00000 10Transaction00000 11VerifyCookie01000 12TableLock020examp00 13Goto02000

原文链接:https://www.f2er.com/sqlite/201220.html

猜你在找的Sqlite相关文章