第6章:Schema 和版本迁移
Schema 定义与管理
什么是 Schema?
在 SwiftData 中,Schema(模式)是对数据模型的正式描述,它定义了:
- 实体(Entities)及其属性
- 实体间的关系
- 约束条件和索引
- 版本信息
Schema 是 SwiftData 管理底层数据库结构的核心依据,也是版本迁移的基础。
自动生成的 Schema
当使用 @Model 宏标记数据模型时,SwiftData 会自动生成对应的 Schema:
@Model
final class Book {
var title: String
var author: String
var publishDate: Date
init(title: String, author: String, publishDate: Date) {
self.title = title
self.author = author
self.publishDate = publishDate
}
}
SwiftData 会自动为这个 Book 类创建包含三个属性的 Schema。
显式定义 Schema
虽然自动生成很方便,但有时需要更精细的控制。可以通过 Schema 类型显式定义:
import SwiftData
let bookSchema = Schema([
Book.self
])
// 或者更详细的配置
let detailedSchema = Schema(
version: Schema.Version(1, 0, 0),
entities: [
Schema.Entity(
name: "Book",
properties: [
Schema.Property(name: "title", type: .string),
Schema.Property(name: "author", type: .string),
Schema.Property(name: "publishDate", type: .date)
]
)
]
)
Schema 配置选项
创建 ModelContainer 时可以指定 Schema 配置:
// 基本配置
let container = try ModelContainer(for: Book.self)
// 高级配置
let config = ModelConfiguration(
schema: detailedSchema,
isStoredInMemoryOnly: false,
allowsSave: true,
cloudKitContainerIdentifier: nil
)
let customContainer = try ModelContainer(
for: detailedSchema,
configurations: config
)
Schema 版本管理
良好的版本管理策略包括:
- 版本号:使用语义化版本(主版本.次版本.修订号)
- 变更日志:记录每个版本的模型变更
- 测试计划:为每个迁移路径编写测试
// 检查当前 Schema 版本
if let currentVersion = container.schema.currentVersion {
print("Current schema version: \(currentVersion)")
}
最佳实践
- 单一职责:每个模型类应该只负责一件事
- 命名一致:属性名使用小驼峰,实体名使用大驼峰
- 文档注释:为每个模型和重要属性添加文档
- 版本兼容:考虑向后兼容性,避免破坏性变更
调试 Schema
当遇到 Schema 相关问题时,可以:
- 启用 Core Data 调试日志(SwiftData 基于 Core Data)
launchArguments.append("-com.apple.CoreData.SQLDebug 3") - 检查生成的 SQL 语句
- 使用
ModelContainer的schema属性检查当前 Schema
常见问题解决
问题1:属性类型变更导致崩溃
解决方案:必须通过版本迁移来修改属性类型
问题2:实体名冲突
解决方案:使用 @Model(name: "CustomName") 指定唯一名称
问题3:多模块中的模型定义
解决方案:确保所有相关模块都能访问模型定义,或使用显式 Schema 注册
通过合理管理 Schema,你可以确保数据模型的稳定性和可维护性,为后续的版本迁移打下坚实基础。
