ORM、Schema 与数据库迁移
ORM 把代码对象映射到数据库操作,迁移则记录表结构怎样一步步变化。两者都不能取代对实际 SQL 和数据风险的理解。
- 为任务模型生成一次可审查迁移,在练习库应用并回查结构与数据。
- Prisma / JPA 等 ORM 与 SQL 的关系
- 观察ORM、Schema 与数据库迁移后,应当为任务模型生成一次可审查迁移,在练习库应用并回查结构与数据,并保留查询结果、影响行数、迁移记录和缓存命中情况作为可重复检查的依据。
- 完成 6.2「SQL 与关系型数据库直觉」
FOUNDATION
必须理解
ORM(Object-Relational Mapping,对象关系映射)把代码中的模型与数据库操作连接起来;迁移则记录数据库结构怎样从旧版本演进到新版本。便利不能替代对 SQL 和数据风险的理解。
本课依次讲清Prisma / JPA 等 ORM 与 SQL 的关系、Schema、客户端、查询和关系加载和迁移文件、开发数据库与生产数据库,最后通过“用 Prisma Client 完成创建、查询、更新并核对数据库”检查学习结果。
ORM 像翻译员,把 TypeScript 对象翻成 SQL;迁移像建筑改造图纸,按顺序记录加门、改管线。翻译员和图纸都可能出错,所以施工前要审查。
Prisma schema 定义 User 与 Task,迁移创建表和外键,服务端通过 Prisma Client 查询当前用户任务;新增 dueAt 字段要生成并检查迁移。
Prisma / JPA 等 ORM 与 SQL 的关系
Prisma Schema 写清模型、字段、关系和约束,Prisma Client 再根据它生成带类型的查询方法。最后确实执行工作的仍然是数据库和 SQL。
基础概念
ORM(Object-Relational Mapping,对象关系映射)把程序中的类型或对象操作映射为数据库查询。Prisma、JPA 等减少重复代码,但底层仍由 SQL 与数据库执行。
进一步理解
ORM 模型描述字段、关系和约束,客户端提供类型化查询。它能防止部分拼接错误,却不会自动设计正确业务模型或高效查询。
复杂查询、事务和性能问题仍需理解生成的 SQL、索引与数据库行为。不同 ORM 的加载策略也可能造成大量隐形请求。
代码通过 `task.findMany({where:{ownerId}})` 查询任务,ORM 生成参数化 SQL;开发者仍要确认只返回当前用户且没有 N+1 查询。
ORM 不是数据库,也不是 SQL 替代物;它是应用与关系型数据库之间的一层映射和工具。
这一小节记住:使用 ORM 提高表达和类型安全,同时保留检查数据库行为的能力。
Schema、客户端、查询和关系加载
迁移文件记录数据库结构每一步怎么变化,像 Git 记录代码历史。开发时可以反复试,到了生产环境就得考虑旧数据、锁表时间和失败后怎么处理。
基础概念
Schema 是数据结构与约束的声明,生成客户端把声明转换为可调用 API,关系加载决定查询时是否以及怎样取得关联记录。
进一步理解
一对多关系通常由“多”方保存外键。是否一起加载关联数据应由当前用例决定,默认全部加载会增加查询和传输。
Schema 改变只是代码层意图,真实数据库还需迁移。生成客户端也需与新 Schema 同步,否则类型和数据库会处于不同版本。
Task 的 ownerId 保存外键,owner 描述 ORM 关系;列表页只选择任务字段,详情页需要时再加载所有者公开信息。
类型中的可选字段与数据库可空约束相关但不完全相同;应用没传值、数据库默认值与实际 NULL 要分别理解。
这一小节记住:Schema 描述数据契约,查询应只加载当前行为需要的字段与关系。
迁移文件、开发数据库与生产数据库
如果旧表里已经有一万行数据,突然加一个必填字段,这一万行都没有值。更稳的做法通常是先允许为空、完成回填,再把约束收紧。
基础概念
迁移文件记录数据库结构从一个版本变到下一个版本的具体步骤。开发库用于试验,生产库含真实数据,执行策略必须考虑兼容、锁表、回填和失败恢复。
进一步理解
新增非空字段时,旧行没有值。安全过程常分为增加可空字段、部署兼容代码、回填旧数据、再收紧约束。
迁移应进入版本控制并先在含真实规模副本上演练。直接手改生产表会让源码、迁移历史和实际结构失去一致。
为任务增加 priority:先允许为空并让新代码兼容,批量回填默认值,验证无 NULL 后再添加非空约束。
代码回滚不自动回滚数据库。某些结构删除和数据转换不可逆,必须单独设计向前修复或恢复方案。
这一小节记住:数据库结构变化要被记录、审查、演练,并与应用版本保持兼容。
- Prisma Schema 中已经存在 User 模型及其 tasks 反向关系。
- 生成迁移前确认目标数据库与现有数据,不直接对生产执行开发重置。
model Task {
id String @id @default(cuid())
title String
done Boolean @default(false)
ownerId String
owner User @relation(fields: [ownerId], references: [id])
createdAt DateTime @default(now())
}阅读ORM、Schema 与数据库迁移示例时,ownerId 是外键值,owner 描述 Prisma 层关系;数据库迁移会建立相应约束。
- id 使用 cuid 生成主键,done 与 createdAt 由数据库/客户端提供默认值。
- ownerId 保存真实外键值,owner 声明该字段引用 User.id。
- 修改模型后需生成并审查迁移 SQL,再更新客户端类型。
迁移创建任务表、外键和默认值;无效 ownerId 被约束拒绝,查询时可以按需加载 owner,而不是复制用户数据。
AI COLLABORATION
AI 如何参与
在ORM、Schema 与数据库迁移这一课,AI 负责根据真实材料解释Prisma / JPA 等 ORM 与 SQL 的关系并指出遗漏,学习者负责控制范围、执行修改和核对查询结果、影响行数、迁移记录和缓存命中情况。
推荐协作顺序
- 1
把当前 schema、目标变化和已有数据情况发给 AI。
- 2
让它先说明旧数据会遇到什么,再给分阶段迁移方案。
- 3
生成迁移后请它解释 SQL,但最终以测试数据库的真实结果为准。
这是当前模型、数据库结构和生成迁移。请逐项比较差异,指出会创建、修改或丢失什么。不要直接操作生产库,不自动接受删除列。给出应用前备份、练习库验证和回退检查。
模型有清晰主键、外键和时间字段;迁移方案考虑旧数据,不只给 prisma migrate 命令;ORM、Schema 与数据库迁移的人工验收必须回到真实页面、请求、终端、测试或数据结果,不能用 AI 的文字说明代替。
人工检查清单
- 确认没有保存明文密码,级联删除符合产品意图,生成的迁移 SQL 会被人工检查。
- 让 AI 展示迁移实际 SQL、旧数据处理和新旧应用并存时的兼容路径。
- 在含旧数据的测试副本执行迁移、回退或恢复演练,并核对行数与约束。
COMMON TRAPS
常见误区
下面三类问题会让任务看似完成,却经不起刷新、错误输入或真实环境检查。先看现象,再找原因和修正方法。
盲信自动生成迁移
- 你会看到
- 工具建议删除或重建含数据的列
- 为什么发生
- 工具只比较结构差异,不了解现有数据能否安全转换或丢弃。
- 怎样纠正
- 逐行审查并在副本演练
多人修改后重写历史
- 你会看到
- 不同环境拥有不一致迁移顺序
- 为什么发生
- 其他环境可能已经执行旧迁移,改写文件会让同一编号代表不同操作。
- 怎样纠正
- 已共享迁移通过新增文件修正
上线时直接试迁移
- 你会看到
- 锁表或数据转换失败影响用户
- 为什么发生
- 生产数据量和并发与本地不同,锁表及转换耗时必须提前验证。
- 怎样纠正
- 先备份、演练并准备恢复步骤
HANDS-ON
动手任务
为任务模型生成一次可审查迁移,在练习库应用并回查结构与数据。
- 完成 6.2「SQL 与关系型数据库直觉」
跟着做
- 01
安装并初始化 Prisma,连接本地 PostgreSQL。
- 02
定义 User、Task 及一对多关系。
- 03
生成第一份迁移并阅读 SQL。
- 04
写 seed 或脚本创建一名用户与任务。
- 05
用 Prisma Client 完成创建、查询、更新并核对数据库。
为任务模型生成一次可审查迁移,在练习库应用并回查结构与数据。
新增 dueAt 可选字段,写出从可选到必填的两阶段迁移计划。
离开本课前,自问四件事
- ORM、Schema、生成客户端与数据库分别承担什么?
- 关系加载为什么要按用例选择而不是默认全部取得?
- 给有旧数据的表新增必填字段应怎样分阶段?
- 为什么应用代码回滚并不保证数据库也能回到原状态?
确认完成后,会同步更新学习中心的课程学习进度。