第2章 持久化技术全景图
本地持久化技术并非孤立选择,而是构成自底向上的技术栈。本章围绕文件系统、SQLite、Core Data、Realm、Room、SharedPreferences、DataStore七类主流方案,从方案边界、分层结构、组件职责、数据流/控制流、选型权衡、风险点、落地步骤及验收标准进行全景式梳理,为后续各章节的深入剖析建立统一坐标系。
2.1 方案边界
每种技术适用不同数据类型、操作规模和平台约束:
| 技术 | 数据类型 | 典型数据量 | 平台核心约束 |
|---|---|---|---|
| 文件系统(File/NSData) | 二进制大文件、文本、JSON/XML | MB~GB | 需自行管理解析、并发、脏写 |
| SQLite | 结构化关系数据 | KB~GB | 嵌入式C库,跨平台但需C API或封装 |
| Core Data | 对象图托管对象 | KB~百MB | 仅Apple平台,深度集成Cocoa |
| Realm | 对象(零拷贝) | KB~百MB | 移动优先,跨平台(Java/Kotlin/Swift/JS) |
| Room | 关系型对象映射 | KB~GB | 仅Android,基于SQLite的ORM |
| SharedPreferences | 键值对(基本类型、String、Set) | KB~数MB | 仅Android,异步加载,不推荐大体积 |
| DataStore | 键值对或Protocol Buffers | KB~百MB | 仅Android,协程/Flow驱动,替换SP |
2.2 分层结构与组件职责
从操作系统到应用层,持久化方案处于不同抽象层级:
- OS内核层:提供块设备驱动、文件系统(ext4/APFS/F2FS)及页缓存。
- 文件系统层:直接读写文件、目录;上层可构建索引或日志结构存储。
- 数据库引擎层:SQLite、Realm核心引擎,处理B树、WAL、事务。
- ORM/对象封装层:Core Data(NSManagedObjectModel)、Room(DAO+Entity)、Realm(RLMObject)提供对象映射、懒加载、缓存。
- 应用API层:SharedPreferences/DataStore提供极简KV接口;NSUserDefaults(iOS)同样为KV但依赖plist文件。
关键分界:文件系统和数据库引擎属于“底层存储组件”,而ORM/封装层属于“应用数据管理组件”。选型时需明确团队控制力落在哪一层。
2.3 数据流/控制流
以一次写操作为例,不同技术路径差异显著:
- 文件系统:应用→序列化→write()→page cache→磁盘。无事务,需自己加锁。
- SQLite裸用:应用→SQL→sqlite3_exec→VDBE→B-tree→pager→page cache→磁盘。支持ACID事务。
- Room:应用→Repository→DAO→SQLite(自动生成SQL)→同上。生命周期感知,配合LiveData/Flow。
- Core Data:应用→NSManagedObject→NSManagedObjectContext→NSPersistentStoreCoordinator→SQLite/XML/二进制。合并策略、逆序依赖。
- Realm:应用→RLMObject→Realm事务块→共享group→mmap文件→磁盘。零拷贝,主线程直接读最新版本。
- SharedPreferences:应用→Editor→apply()/commit()→XML文件写入。异步刷新,无事务。
- DataStore:应用→DataStore<Preferences>→Transform/Serialize→文件。协程保证顺序写,使用Flow订阅变化。
2.4 选型权衡
| 维度 | 文件系统 | SQLite | Core Data | Realm | Room | SharedPref. | DataStore |
|---|---|---|---|---|---|---|---|
| 查询能力 | 无 | 强(SQL) | 中等(谓词) | 强(类SQL/谓词) | 强(SQL+DAO) | 无 | 无 |
| 自动迁移 | 无 | 需手写 | 轻量+重量级 | 自动(有风险) | 自动+手写 | 丢弃 | 丢弃 |
| 线程安全 | 手动 | 单写多读 | Context隔离 | 多版本无锁 | 官方LiveData/Flow | 非线程安全 | 协程保证 |
| 离线/回退 | 自然 | 自然 | 自然 | 自然 | 自然 | 自然 | 自然 |
| 平台生态绑定 | 低 | 低(C库) | 仅Apple | 跨平台 | 仅Android | 仅Android | 仅Android |
| 学习曲线 | 低 | 中 | 高 | 中 | 中 | 极低 | 低 |
2.5 风险点
- 技术锁定:Core Data/Realm 的序列化格式不透明,跨语言或跨平台迁移困难。
- 性能边界:SharedPreferences 在大量写入时会阻塞UI;文件系统在大数据量下无索引导致全量扫描。
- 数据迁移:SQLite 版本变更需谨慎 ALTER TABLE;Realm schema 变更可能导致所有客户端强制升级。
- 版本兼容:DataStore 尚不成熟(API不稳定),Realm 曾有大版本不兼容。
- 团队熟悉度:选择 Room 需团队理解 SQL/DAO;选择 Core Data 需掌握 NSManagedObjectContext 的多线程规则。
2.6 落地步骤
- 盘点数据特征:结构化 vs 非结构化;读写比例;并发模型;离线需求。
- 映射平台约束:纯 Android → Room/DataStore;纯 iOS → Core Data/NSFileStorage;跨平台 → Realm/自定义SQLite封装。
- 构建 PoC 原型:对候选技术各实现一个简单 CRUD 用例,记录初始化延迟、读写耗时、内存占用。
- 评估复杂度:团队学习成本、现有架构兼容性、测试工具链(FTS、iCloud同步等是否内置)。
- 决策并定义抽象层:建议通过 Repository 或 DAO 接口封装,使底层替换成本最小化。
2.7 验收标准
- 选型结果覆盖所有业务数据持久化场景(缓存、离线、大文件、配置)。
- 单次基础读写延迟不超过业务容忍阈值(例如配置读取<10ms,数据库查询<100ms)。
- 数据迁移方案已明确:版本升级时无需用户手动清除数据。
- 并发场景下不会出现脏读、丢失更新或 ANR。
- 单元测试和集成测试覆盖率≥85%(持久化层)且可 Mock。
决策检查点:当团队从原生开发转向跨平台时,优先考虑Realm或SQLite封装;当需要极致性能且愿意承担迁移成本时,文件系统+自定义索引方案不可忽略。