sqlite是一种用C编写的、轻量级的、遵循ACID(atomicity、consistency、isolation、durability)的关系型数据库。
1、不支持外键,支持事务。
2、没有独立进程。
sqlite有4种锁
1、SHARED,共享锁
2、RESERVED,保留锁
3、PENDING,未决锁
4、EXCLUSIVE,排他锁
锁逐级上升机制
1、读操作用的是共享锁,因此可以并发读。
2、写操作会先获得保留锁,把需要更新的数据写到缓存。这时,已有的读操作可以继续,也接受新的读操作申请。一个DB一个时间点只能有一个保留锁。
3、接着,写操作会获得未决锁。这时,已有的读操作还是可以继续,但是不再接受新的读操作申请了。
4、等到所有读操作结束。写操作会获得排他锁,把缓存中的数据刷到磁盘上。
锁实现
1、sqlite的所有锁都是基于文件锁。文件锁可以锁整个文件,也可以锁文件的一部分(即记录锁),具体实现由fcntl接口给出。可想而知,sqlite的并发性能要差一些,不过移动端本就不是高并发场景。
2、保留锁可以提高并发性能,因为直到要刷数据到磁盘时,才获得排他锁。
3、未决锁可以防止写操作饿死,因为一旦获得未决锁,就不会再接受新的读操作申请了。
sqlite的表和索引都是用B+树进行存储。B+树的非叶子节点不存数据,只存key,这样一个节点可以存储尽可能多的key,从而降低树的深度,减少磁盘I/O次数。
1、表B+树节点的key是rowid(sqlite默认分配的唯一键),数据是对应的一行记录。
2、索引B+树节点的key是索引列,数据是rowid。
SCAN
SEARCH
使用sqlcipher对sqlite数据库加密时,是按页(例如一页4K)进行的。
sqlcipher默认会对用户传进去的key做预处理,形成新的key,再用来加密数据库。
1、一个db中不能有同名索引,即使是两个不同的表
2、sqlite默认syncchronous = full
3、sqlite trace profile
sqlite监控:
https://stackoverflow.com/questions/48164123/how-can-i-trace-sqlite3-execute-time-in-ios