SQLite数据库使用和问题处理

世界上使用最多的数据库是什么?并不是Oracle也不是MySQLPostgreSQL,而是SQLite
这个小巧的嵌入式数据库引擎,手机,浏览器等无数的应用程序都内置了 SQLite 数据库。

SQLite 简介

SQLite是遵守ACID的关系数据库管理系统,它包含在一个相对小的C程序库中。与许多其它数据库管理系统不同,SQLite不是一个客户端/服务器结构的数据库引擎,而是被集成在用户程序中。 SQLite遵守ACID,实现了大多数SQL标准。它使用动态的、弱类型的SQL语法。
目前使用的版本主要都是SQLite3

SQLite 特点

嵌入式

不需要单独的线程,可以直接嵌入程序中。连部署都不用考虑了。

关系型数据库

  1. 遵守ACID,自带事务。
  2. 支持SQL,简单易用。

SQLite 使用场景

服务端程序的辅助存储

服务端程序里,用于保存节点的元数据信息。用于本地缓存等场景。

手机等终端应用程序的数据库

终端应用程序通常也需要保存些数据,类似钉钉,微信等。这肯定比存文件方便可靠多了。

工具类程序

最典型的就是YUM了。类似的应用肯定也还有。

单元测试

通常,服务端程序开发都会使用MySQL等关系型数据库,用于支持并发。但在写单元测试时,如果使用SQLMock会非常麻烦。此时,可以使用SQLite来替代SQLMock实现单测。

SQLite 使用方法

这里使用Golang来举例,SQLite支持各种语言,用法基本一样。

常规用法

Golang中,需要传入两个参数,第一个是指定数据库类型,第二个则是数据库路径。

db, err := sql.Open("sqlite3", "./foo.db")
if err != nil {
    log.Fatal(err)
}

defer db.Close()

内存模式

SQLite的内存模式(Memory Mode)就是一种在内存中创建数据库的方式,即将数据库文件保存在内存中,而不是保存在磁盘上。在程序结束后,SQLite的数据就会消失,非常适合用作单元测试,避免数据干扰。但在每次运行时都需要重新创建表格、插入数据等操作。
Golang中,将SQLite的路径配置成:memory:就使用了内存模式。

db, err := sql.Open("sqlite3", ":memory:")

共享缓存的内存模式

如果是使用Golang开发,有可能遇到一个情况。
有的SQL报错,找不到表,但实际上表一开始已经初始化了

OperationalError:no such table

这并不是因为SQLite出现数据损坏,或者是MVCC的问题,而是多线程造成的。Golang属于多线程模式,链接数据库时可能会有多个会话。但按照上述的用法,每个会话都会有一个自己的SQLite实例,当程序用了另一个会话时,访问的是另一个SQLite实例,自然就会报错找不到表了。
如果使用文件的方式,则能正常运行。当然,SQLite也有有共享缓存的内存模式。

db, err := sql.Open("sqlite3", "file::memory:?cache=shared")

这样,同一个进程中的不同会话,都会使用同一块内存。就能解决上述问题了。

注意

SQLiteMySQL在一些SQL的处理上存在一些不同。建议使用ORM来屏蔽差异。
此外,SQLite中,不同表如果用一个索引名字,是会冲突的,需要注意。

database is locked处理

SQLite可以多个会话读,但同时只能有一个写会话,否则会产生锁库的报错。所以,我们在代码实现时需要注意避免同时存在多个会话的写操作。

限制会话数

db.SetMaxOpenConns(1);

设置后,会话数会被限制成1,但如果需要多个会话操作数据库时,程序会直接卡死。
比如某个事务中,有读取另一个表的请求,第二个数据库操作会因为拿不到会话而卡死。

配置参数

db, err := sql.Open("sqlite3", "file::memory:?cache=shared&_journal=WAL&_busy_timeout=10000")
启用WAL

启用SQLite3WAL(Write-Ahead Logging)模式可以显著降低锁库的概率。在WAL模式下,读写操作不相互阻塞,可以实现高并发的读写操作。

设置忙碌超时时间

设置忙碌时间可以让SQLite在发现锁定时,等待一会。这也可以降低报错的情况。

注意

上述两个参数也可以在会话中设置,但由于database/sql通常会创建多个连接,如下操作只会影响其中的一个链接。在其它链接访问时,依然会报错。

db.Exec("PRAGMA busy_timeout = 10000;")

参考资料

  1. In-Memory Databases
  2. PRAGMA Statements
© 版权声明
THE END
广告
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容