一、为什么需要SQLite替代方案

在iOS开发中,CoreData一直是官方推荐的本地数据存储方案。它提供了对象关系映射(ORM)功能,让开发者可以用面向对象的方式操作数据库。但CoreData的学习曲线较陡,配置复杂,性能优化也需要额外处理。

相比之下,SQLite更轻量、更直接。它是一个嵌入式数据库,不需要额外服务支持,适合移动端的高效数据存储。如果你的项目需要更灵活的数据操作,或者希望减少框架依赖,SQLite会是一个不错的选择。

二、SQLite在iOS中的基本使用

在iOS中,我们可以通过原生的SQLite3 C API或者封装库(如FMDB)来操作SQLite。这里以FMDB为例,因为它更符合Swift/OC的编码习惯。

技术栈:iOS + Swift + FMDB

import FMDB

// 1. 创建或打开数据库
let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/test.db"
let db = FMDatabase(path: dbPath)

guard db.open() else {
    print("数据库打开失败")
    return
}

// 2. 创建表
do {
    try db.executeUpdate("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)", values: nil)
} catch {
    print("创建表失败: \(error)")
}

// 3. 插入数据
do {
    try db.executeUpdate("INSERT INTO users (name, age) VALUES (?, ?)", values: ["张三", 25])
    try db.executeUpdate("INSERT INTO users (name, age) VALUES (?, ?)", values: ["李四", 30])
} catch {
    print("插入数据失败: \(error)")
}

// 4. 查询数据
do {
    let result = try db.executeQuery("SELECT * FROM users", values: nil)
    while result.next() {
        let name = result.string(forColumn: "name") ?? ""
        let age = result.int(forColumn: "age")
        print("姓名: \(name), 年龄: \(age)")
    }
} catch {
    print("查询失败: \(error)")
}

// 5. 关闭数据库
db.close()

这个示例涵盖了数据库的基本操作:创建/打开、建表、增删改查。FMDB的API设计非常直观,比直接使用SQLite3 C API方便很多。

三、SQLite与CoreData的对比

1. 性能

  • SQLite:直接操作数据库文件,读写性能较高,适合大量数据的快速存取。
  • CoreData:虽然是基于SQLite的封装,但ORM层会带来额外开销,复杂查询时性能可能不如直接使用SQLite。

2. 灵活性

  • SQLite:可以执行任意SQL语句,适合复杂查询或需要直接控制数据库的场景。
  • CoreData:只能通过NSFetchRequest操作数据,灵活性较低,但提供了数据模型版本迁移等高级功能。

3. 学习成本

  • SQLite:需要熟悉SQL语法,但概念简单,适合有数据库基础的开发者。
  • CoreData:需要理解NSManagedObjectContextNSPersistentStoreCoordinator等概念,学习曲线较陡。

四、SQLite的高级用法

1. 事务处理

SQLite支持事务,可以保证批量操作的原子性。

// 开启事务
db.beginTransaction()

do {
    try db.executeUpdate("UPDATE users SET age = ? WHERE name = ?", values: [26, "张三"])
    try db.executeUpdate("DELETE FROM users WHERE name = ?", values: ["李四"])
    db.commit() // 提交事务
} catch {
    db.rollback() // 回滚事务
    print("事务执行失败: \(error)")
}

2. 数据库迁移

如果表结构需要修改,可以通过版本管理实现迁移。

// 检查当前版本
let version = db.userVersion
if version < 2 {
    do {
        try db.executeUpdate("ALTER TABLE users ADD COLUMN email TEXT", values: nil)
        db.userVersion = 2 // 更新版本号
    } catch {
        print("迁移失败: \(error)")
    }
}

五、应用场景与注意事项

1. 适合场景

  • 需要高性能读写的应用(如日志记录、缓存)。
  • 需要复杂SQL查询的场景(如报表统计)。
  • 希望减少框架依赖的轻量级应用。

2. 注意事项

  • 线程安全:SQLite的写操作是串行的,多线程环境下需要使用FMDatabaseQueue
  • 数据备份:SQLite文件可以包含在iCloud备份中,但敏感数据建议加密。
  • 性能优化:合理使用索引、避免频繁打开关闭数据库。

六、总结

SQLite在iOS开发中是一个高效、灵活的数据库选择。虽然它没有CoreData的高级功能(如数据模型迁移、关系管理),但在性能和可控性上更胜一筹。如果你的项目需要轻量级存储或复杂查询,不妨试试SQLite。