SQLite 简介
常见的关系型数据库有 SQLite,MySQL,SQL Server 等,通常学习关系型数据库时不会使用 SQLite,但是 SQLite 是世界上使用最广泛的数据库引擎。SQLite 内置于所有手机和大多数计算机中,并捆绑在人们每天使用的无数其他应用程序中。SQLite 是一个由 C 语音开发的嵌入式库,具有小型、 快速、 自包含、 高可靠、 功能齐全等特点。
文章以3.32.2
版本为例讲述 SQLite 的一些基本知识
SQLite 常用命令和示例
在命令行中使用 SQLite 命令,需要先执行sqlite3
命令,进入SQLite提示符
。
创建或打开数据库
有两种方法可以创建或打开数据库,一个是在sqlite3
命令后面加上数据库路径,另一个是使用点命令.open
sqlite3 /.../xxx.db 法
通过执行这个命令进入SQLite提示符
时,如果数据库文件已经存在,则直接打开对应数据库,否则不会立即在对应路径创建 xxx.db 文件。要等到执行了添加数据表,视图等数据库对象的命令之后。
示例
先执行如下命令,此时没有创建出
comms_ease.db
文件
再执行如下命令创建一张表,在当前目录出现comms_ease.db
文件
.open /.../xxx.db 法
使用.open
是一个点命令,使用它需要先执行sqlite3
命令进入SQLite提示符
。.open
命令的使用方式也是在命令后面追加数据库路径,不过和sqlite3 /.../xxx.db法
不同的是,执行.open
命令后,数据库文件会被直接创建出来,不需要再创建数据库对象。
创建表
SQLite 的创建语句为CREATE TABLE,完整的创建表语句内容丰富,除了创建普通表外,还能具备判断表是否已经存在,创建临时表等能力。常见的创建普通表的句式为。
默认情况下,一张表的最大列数为 2000,每一行能存下的最大字节数为十亿,能满足绝大多数的需求,创建普通表的示例如下
例子中,创建了一个名为table_comms_ease
的数据表,包含两列,第一列是id
,类型是整形,不能为空,而且是表的主键,并可以自动生成; 第二列是value
,类型为字符串
在表名已经存在的情况下,调用CREATE TABLE 表名
语句会报错,要避免,可以使用CREATE TABLE IF NOT EXISTS 表名
语句。如果不存在,则创建表,如果存在,则什么都不做。示例如下
如果希望临时存储一些数据,而且只对当前连接有效,可以试试临时表。临时表的创建语句为CREATE TEMP TABLE
。临时表只对当前数据库连接有效,重新建立连接或者同时存在的其他连接都无法访问到。示例如下
其它常用点命令
点命令是SQLite
数据库独特的命令形式,它们通常比较简单,而且不需要以分号结尾,常见的点命令如下表所示
增
向表内添加一行,即为每一列构建一个值,并填入新的一行中。添加行的命令是INSERT,添加方式有三种,一种是指定值添加;二是添加 Select 语句的结果;三是默认添加。
指定值添加就是指定部分或者所有列的值,剩下列使用默认值的方式,对于没有通过
DEFAULTE
,AUTOINCREMENT
等方式声明默认值的列,如果没有指定NOT NULL
则填入NULL
,否则报错。至少需要指定一列的值,如需全部填写默认值,可以使用默认添加
方式。需要注意的是,值的顺序要和列的顺序保持一致。示例如下:
通过添加加 Select 语句的结果添加一行的格式为
INSERT INTO 表名 SELECT ...
通过此方法添加一行时,默认值不会被自动填充,SELECT 语句查出的数据量必须和表的列数一致。假设已经存在表operator
包含列key
和description
而且某一行的key
为'.backup',description
为备份数据库到文件
,给出示例如下:
默认添加的格式为
INSERT INTO 表名 DEFAULT VALUES;
为每一列都填入默认值,如果没有特别声明默认值,则填入 NULL。示例如下:
通过创建表章节的示例语句创建出数据表,再依次调用上述示例语句,则数据表内会出现 5 行数据,如下
删
删除表内的一行,命令是DELETE,常用格式为
删除命令本身比较简单,指定表名和删除条件即可删除一列,如下示例表示如果value
列中的值有value of
开头,则删除。
如上命令操作后,table_comms_ease
表还剩的数据为
改
修改表内数据的命令为UPDATE,其常用格式为
修改多列内容时可以采用先写出列名,再按顺序赋值的方式,也可以采用一列一列修改的方式。如果要更新 id 为 4 的所在行的值,设置id
为123
,value
为new value
,两种修改方式分别如下
或者
修改后,table_comms_ease
表中的数据为
修改单列的方法和修改多列的方法相似,比如将id
为 5 这一行的value
也修改为new value
,可以如下操作
或者
修改后,table_comms_ease
表中的数据为
查
查询语句的命令是SELECT,它不会修改数据库,结果的行数在自然数范围内,每一行代表一个查询结果。SELECT
命令的常用格式为
查询语句中可用的配置比较多,但是大都不是必须的。查询table_comms_ease
表的所有内容只需要如下命令即可
上面命令中的*
表示所有列,命令相当于
结果为
另外,可以通过VALUES
语句构建一个查询结果,结果的列名为column1
, column2
, column3
等等。比如
的结果为
去重策略
去重策略有两种,一种是默认策略ALL
,代表不去重;另一种是DISTINCT
,代表去重。table_comms_ease
表中value
列的值相同,使用ALL
和DISTINCT
分别查询 value 列时,命令和结果如下:
ALL 命令
结果为
DISTINCT 命令
结果为
可以看出在有重复结果时,ALL 策略会保留所有结果,而 DISTINCT 策略只保留其中一个
表名或者子查询语句
查询语句的FROM
关键字后面可以跟表名或者子查询语句,用于限制查询范围。当填写表名时,可以填写多个表名,用逗号或者连接运算符分隔。当填写查询语句时,可以视为先查询出一张表,再从此表中查询出数据。
假设还有一张表table_comms_ease_1
,列信息和table_comms_ease
表相同,值为
则此字段填写table_comms_ease,table_comms_ease_1
时得到如下命令
结果为
当此字段填写两个子查询语句,如一个是 id 为 5,另一个是 id 为 123 时,则得到如下命令
结果为
将子查询语句的结果视为一张表,则可以统一对两种填写格式的理解。另外查询命令也支持混合填写表名和查询语句。
排序条件
排序条件决定了结果的排列顺序,常用格式如下
比较方式有三种,分别为BINARY
, NOCASE
和 RTRIM
BINARY:使用标准 C 库中的 memcmp()函数逐字节比较
NOCASE:先把 ASC II 码中的大写字母转为小写字母,再按照 BINARY 方式比较
RTRIM:去掉末尾空格后按照 BINARY 方式比较
通过下面命令为表table_comms_ease
添加几条数据,
则表中的数据变为
注意:id 为 7 的一行对应的 value 的末尾有一个空格
如下示例展示了三种不同比较方式的区别
BINARY 命令
结果:
NOCASE 命令
结果:
RTRIM 命令
结果:
数量限制
数量限制语句可以限制查询结果的行数,常用格式如下
设数量为 n,偏移量为 o,则上面格式的意义是从第o+1
条开始,取最多n
条数据,如果没有符合条件的数据,则结果为空。
限制数量为 3,得到如下表达式
结果为
由于表的总行数是 5,所以如果限制数量≥5,则会查出整张表。
如果限制数量为 3,同时指定偏移量为 1,得到如下表达式
结果过滤掉第一条数据(5, newvalue)
,并向后取 3 条,得到
如果限制数量为 3,同时指定偏移量为 3,得到如下表达式
结果过滤掉前三条数据,并向后取 3 条,但是后面只有 2 条,所以得到
如果偏移量≥5,则什么都查不到
SQLite常见限制
数据库中的B树
B 树与 B+树简介
B 树是一种平衡多路查找树,每个结点包含三个部分:键,值,指向子结点的指针。假设一个 B 树结点中有n
个键,则它同时有n
个值。如果这是一个叶子结点,则它没有指向子结点的指针,否则有n+1
个指向子结点的指针。下图为n==2
时的结点情况。
图中键1
和键2
两个值需要满足键1<键2
。 值1
和值2
分别与键1
和键2
对应;三个指向子结点的指针
,分别指向具有不同范围的键
的子结点。子结点1
中的键
都小于键1
;子结点2
中的键
都大于键1
,且小于键2
;子结点3
中的键
都大于键2
。如下图提供了一个 3 路 B 树的示例。
上图中每个结点有三排,第一排是键
;第二排是值
;第三排是指向子结点的指针
。根节点有50
和100
两个键
,因此它的左子树中结点的键
都小于50
;中子树中结点的键
都大于50
且小于100
;右子树中结点的键
都大于100
。
B+树和 B 树类似,但是 B+树的内部结点中只有键
和指向子结点的指针
,而叶子结点具有键
、值
和指向下一组值的指针
,即只在叶子结点上存储数据。因此父结点中的键还会再出现在子结点上。而且 B+树的叶子结点的指向下一组值的指针
,将所有值
都串成了一个链表。由于内部结点不需要存储值
,B+树可以存储更多的键
。下图用 5 路 B+树存储了上面 3 路 B 树的内容。
B树页
数据库文件由一页或多页组成。同一个数据库中,每页的大小相同,都是 在 512 和 65536 之间,并且为 2 的整数次幂。数据库的页分为锁定字节(lock-byte)页、freelist 页、B 树页、负载溢出页和指针映射页。
B 树算法为 SQLite 提供了键值存储模式,而且保证了键的有序性和唯一性。SQLite 数据库中 B 树的结点就是一个页面,所以指向的子结点的指针实际上是对应页面的页码。SQLite 数据库使用了两种 B 树变体,在叶子节点存储数据的表B树
和不存储数据的索引B树
。一颗完整的树只能是完全的表B树
或者完全的索引B树
。
表 B 树和索引 B 树
表 B 树类似 B+树,只将值存放在叶子结点中;索引 B 树是一颗没有值的树,键就是数据本身,因此索引 B 树其实类似于 B 树。下表列出了它们之间的一些差异。
版权声明: 本文为 InfoQ 作者【网易云信】的原创文章。
原文链接:【http://xie.infoq.cn/article/d5eaf59e629e536c87843b788】。文章转载请联系作者。
评论