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

SQLite学习(九) - 虚拟机指令2,第1张

概述本文介绍SQLite虚拟机指令的版本是2.8.0. SQLite3 以及以后版本的虚拟机概念上是一样的。 但是一些 *** 作码, *** 作数用法,个数有所改变,算法也有所不同。VDBE虚拟机语言,类似汇编语言,VDBE的每天指令由一个opcode 和3个operand组成(SQLite3以后有5个)。 下面看个例子来学习。 1 INSERT SQL CREATE TABLE examp(one text, t

本文介绍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个元素d出,转换成二进制(用于写入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
//从栈中d出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

总结

以上是内存溢出为你收集整理的SQLite学习(九) - 虚拟机指令2全部内容,希望文章能够帮你解决SQLite学习(九) - 虚拟机指令2所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1173913.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存