SQLite对于客户端开发的同学来讲,应该不陌生。那么SQLite到底适合什么场景,出现数据加载慢或查不出的问题时如何排查解决,SQLite损坏时如何去定位并修复,对于基础架构师来说,如何对源码为C语言的SQLite进行封装供应用层调用?作者在深入浅出SQLite系列文章尝试一一和大家进行交流探讨。 今天是深入浅出SQLite系列的第一篇文章,本篇主要是针对Sqlite做一个整体介绍。
什么是SQLite
本质
它是一个轻量级(只有250~400K)的开源ANSI-C库。
解决的问题
主要是用来解决结构化数据在客户端的持久化存储问题。
SQLite的主要特点
优点:
- 兼容性:数据库文件格式稳定,向后兼容,跨平台,可移植性强.安全兼容ACID,允许从多个线程或进程安全访问
- 单一性:只支持本地存储,并不支持网络访问
- 低依赖性:在最小配置下,只使用了 memcmp、strcmp 等少数几个标准库 API
- 多样性:支持内存,磁盘数据库
缺点:
- 安全性:
- 无权限管理机制
- 不支持加密(但可用开源的加密库代替系统内置的动态库实现加密,譬如 SQLCipher)
- SQL标准支持不全:
- 不支持删除,修改数据表的列
- 视图为可读的,不支持操作视图
- 不支持右外和全外连接
- 触发器支持 FOR EACH ROW触发器,不支持FOR EACH STATEMENT触发器
- 锁的粒度过粗:只有数据库文件锁,没有表锁,视图锁这些。
- 不支持并发写操作
- 性能:
- 在100w数据量下访问尚可
- 为已有表添加索引较慢
SQLite的整体组成
SQLite主要由7个模块构成,这些模块被分割成两个部分:前端解析系统和后端引擎。
前端:
前端预处理应用程序传递过来的SQL语句和SQLite命令。对获取的编码分析,优化,并转换为后端能够执行的SQLite内部字节编码。前端可分为三个模块:
- 标示分析(Tokenizer) 将输入的SQL语句分成标识符;
- 语法分析(Parser) 解析器分析通过标识器产生的标识分析语句的结构,并且得到一棵语法树。解析器同时也包含了重构语法树的优化器,因此能够找到一棵产生一个高效的字节编码程序的语法树。
- 代码生成器(Code Generator) 代码生成器遍历语法树,并且生成一个等价的字节编码程序 前端实现了sqlite3_prepare API函数。
后端:
后端是用来解释字节编码程序的引擎。该引擎做的才是真正的数据库处理工作。后端部分由四个模块组成:
- 虚拟机(VM) VM模块是一个内部字节编码语言的解释器。它通过执行字节编码语句来实现SQL语句的工作。它是数据库中数据的最终的操作者。它把数据库看成表和索引的集合,而表和索引则是一系列的元组或者记录。
- B/B+-树 B/B+树模块把每一个元组集组织进一个依次排好序的树状数据结构中,表和索引被分别置于单独的B+和B树中。该模块帮助VM进行搜索,插入和删除树中的元组。它也帮助VM创建新的树和删除旧的树
- 页面调度程序(pager) 页面调度程序模块在原始文件的上层实现了一个面向页面的数据库文件抽象。它管理B/B+树使用的内存内缓存(数据库页的),另外,他也管理文件的锁定,并用日志来实现事务的ACID属性。
- 操作系统交界面(system interface) 操作系统交界面模块提供了对应于不同本地操作系统的统一的交界面 后端实现了slqite3bind,sqlite3_step,sqlite3_column_,sqlite3_reset和sqlite3_finalize API函数。
客户端对SQLite的支持
主流的移动操作系统(iOS & Android)均已内置
SQLite的适用场景
- 硬件设备:移动手机,嵌入式,可穿戴设备等
- 软件场景:数量较多,关系较复杂的有本地持久化需求的结构化数据的增删改查