SQLite 与轻量数据库
问题
iOS 中使用 SQLite 有哪些方式?与 Core Data 相比如何选择?
答案
SQLite 使用方式
| 方案 | 说明 | 推荐 |
|---|---|---|
| C API | libsqlite3,最底层 | ⭐ |
| FMDB | ObjC 封装 | ⭐⭐⭐ |
| GRDB.swift | Swift 封装,类型安全 | ⭐⭐⭐⭐⭐ |
| SQLite.swift | DSL 风格查询 | ⭐⭐⭐⭐ |
GRDB.swift 示例
import GRDB
struct User: Codable, FetchableRecord, PersistableRecord {
var id: Int64?
var name: String
var age: Int
}
// 创建数据库
let dbQueue = try DatabaseQueue(path: dbPath)
// 建表
try dbQueue.write { db in
try db.create(table: "user") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
t.column("age", .integer).notNull()
}
}
// 插入
try dbQueue.write { db in
var user = User(id: nil, name: "Alice", age: 25)
try user.insert(db)
}
// 查询
let users = try dbQueue.read { db in
try User.filter(Column("age") > 18).order(Column("name")).fetchAll(db)
}
SQLite vs Core Data 选型
| 场景 | 推荐 |
|---|---|
| 简单 CRUD + SwiftUI | SwiftData |
| 复杂对象关系 + 变更追踪 | Core Data |
| 复杂 SQL 查询 + 性能要求高 | SQLite(GRDB) |
| 跨平台共享数据库 | SQLite |
常见面试问题
Q1: SQLite 是否线程安全?
答案:SQLite 支持多种线程模式:
- serialized(默认):线程安全,内部加锁
- multi-thread:不同连接可并发,同一连接不可
- single-thread:非线程安全
GRDB 的 DatabaseQueue 为串行访问,DatabasePool 为读写分离(一写多读),都是线程安全的。