iOS数据库框架WCDB总结
1. 背景:
- 项目使用FMDB来操作数据库非常繁琐,开发中添加表和字段容易出错,需要操作很多SQL语句
2. 概述:
- WCDB是一个高效,完整,易用的数据库框架,基于SQLCipher,适用于iOS、MacOS和安卓 ##3. 功能:
- 支持灵活易用的ORM(Object Relational Mapping),开发者可以快捷的定义表、索引、约束,并进行增删改查
- WINQ(WCDB语言集成查询): 通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码。
- 多线程高并发:支持多线程读与读,读与写并发执行,写与写串行操作
- 损坏修复:内建了Repair Kit用于修复损坏的数据库
- 防注入:内建了对SQL注入的保护
4. 目的:
- 减少开发中的胶水代码,提高开发效率,避免SQL注入的安全问题,解决数据库操作的卡顿,方便数据库的备份和修复
5. 原理概述:
- 减少开发中的胶水代码(SQL语句),防止SQL注入:
- 使用WINQ(WCDB语言集成查询),操作数据库以传参的形式进行, 解脱字符串语法。按照原来SQL的语法封装,保留了其组合的能力,不会错过任何接口,例如:
- 使用WINQ(WCDB语言集成查询),操作数据库以传参的形式进行, 解脱字符串语法。按照原来SQL的语法封装,保留了其组合的能力,不会错过任何接口,例如:
- 解决数据库的卡顿
- 多线程并发优化
- 背景:FMDB操作数据库是串行执行的,FMDatabaseQueue内部是GCD创建一个串行队列执行任务,保证线程安全,容易出现阻塞线程的情况
- 针对SQLite做优化
- 打开支持多线程并发
- 打开支持WAL模式
- iOS定制化优化:
- 因为没有多进程并发需求,忽略文件锁,只加线程锁(互斥锁pthread_mutex_lock),添加到队列,把等待休眠的线程加到队列中,当主线程被其他线程阻塞时,可以将主线程的操作“插队”到Queue的头部
- I/O性能优化
- 保留WAL文件的大小,约3.9M
- WAL文件写入数据库文件的过程称为checkpoint,原来checkpoint之后都会清空文件
- mmap优化
- 开启SQLite的mmap,对DB文件有直接作用,但SQLite没有实现对WAL文件的mmap,因为原来WAL文件是会被删除回收的,在并发情况下会崩溃
- 手动调用unixMapfile把不会缩短的WAL文件映射到内存中
- 其他优化:
- 禁用文件锁
- 文件锁导致一些只需要从cache读取的操作,不得不进行至少一次I/O操作
- 禁用内存统计锁
- 操作不耗时,但是很频繁,多线程并发时,容易相互阻塞
- 禁用文件锁
- 多线程并发优化
- 解决单表过大,多表过多所带来的性能问题
- 多表过多:数据库初始化很慢
- SQLite 在初始化的时候,会将 sqlite_master 表中的元信息加载进一个 Hash 表中,而这个表的默认容量是 1KB,对于大小为 32 字节的节点,只需超过 32 个表,就会将其填满。超载的 Hash 表会退化成线性表,并通过比较字符串的方式将元素插入到正确的位置。于是,每新增一个表,都会产生大量的字符串比较的操作,拖慢效率。因此,在调整 Hash 表的容量之后,卡顿问题迎刃而解
- 单表过大:查询慢
- 解决:改为使用整型作为索引,因为使用字符串作索引,占用空间太大,需要遍历的节点过多,从而造成大量 I/O
- 多表过多:数据库初始化很慢
- 加密
- SQLCipher 使用 AES-256 进行全数据库加密
备注:
mmap是一种系统调用,用于在内存中映射文件或设备。它允许将文件的一部分或整个文件映射到进程的地址空间,从而使得文件的内容可以直接通过内存访问,而不需要通过传统的文件读写操作。对映射区域的修改会直接反映在原始文件中,因为映射区域和文件在内存中是共享的
WCDB与FMDB的对比:
- 语言和封装度:
- FMDB是用OC写的,WCDB使用C++编写,并提供OC接口
- WCDB是更高级的封装,隐藏了更多的底层实现逻辑,并且提供了面向对象的方式操作数据库
- 线程安全
- FMDB不是线程安全的,需要我们自己管理数据库操作的线程安全
- WCDB是线程安全的,我们只需要调用框架提供的方式直接操作数据库即可,不用担心线程安全问题
- ORM(Object Relational Mapping)支持
- FMDB不支持ORM,开发者需要写SQL语句来操作数据库
- WCDB内置ORM支持,可以使用模型映射到数据库的表中,大大地简化了数据库的操作
- 性能:
- WCDB针对iOS做了定制化优化,处理大量数据的时候,性能好很多
- 加密:
- WCDB基于SQLCipher,提供了数据库加密的便捷方法
- FMDB本身不提供加密功能
- 数据备份和修复
- WCDB提供数据备份和恢复的方法
- FMDB需要自己处理