KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

Prisma 数据访问层 — keel 龙骨

Prisma 数据访问层 的参考信息:Prisma 数据访问层

课程导读 · 每条结论都要能拿出查询日志和 EXPLAIN

这门课解决的是一类"代码看起来没问题、跑起来也没报错"的问题:接口为什么偶发唯一键冲突、列表页翻到后面为什么慢、本地能跑上线就 500、一个"加个字段"的改动为什么在生产上变成"要不要清空数据库"。

你现在的起点

如果你符合上面这几条,这门课就是为你写的。会写 SQL 是前提——这门课不教 SQL,它教的是"这些 SQL 是被谁、以什么形状发出去的"。不懂前者,后面任何一条结论你都无法验证。

一条能走通的学习路径

先学会看(01 一次 findMany 编译成了什么)
  → 编译器把你的调用变成了什么;多出来的那些字各自解决什么问题
  → 谁在做编译:Prisma 7 的管线与产物

再看这份"能被编译的东西"从哪来(02 schema 是一份两向的契约)
  → 逆向只描述结构、不描述意图;它丢掉的比它给的多
  → 两个方向只能选一个当真相

然后是这门课最实用的一章(03 include 到底发几条 SQL)
  → N+1 的真身、两种策略、以及"一条 SQL"的账单

写的那一侧(04 写路径:从 upsert 到嵌套写)
  → 原子性来自哪、为什么一次 create 是五条、事务的开始为什么看不见

值的旅程(05 值穿过边界时变成了什么)
  → 静默变形 vs 直接报错、精度在哪一层丢、原生 SQL 的边界

改结构的三种处境(06 迁移:从空库、从现成库、从被人改过的库)
  → baseline、drift、以及那个"数据会全丢"的提示

收口(07 管不到的那部分)
  → 连接池、深翻分页、方言、装机体积

你会拿到什么

章节 一句话 关键动作
01 一次 findMany 编译成了什么 你写的对象到数据库那边变成了什么 查询日志 + 三份时序记录 + 枚举 CAST 的三种位置对照
02 schema 是一份两向的契约 逆向出结构,逆向不出意图 一次真 db pull 的告警清单 + "保住 / 丢掉"对照表
03 include 到底发几条 SQL "一条 SQL"不等于"一次工作" N+1 计数 + 两种策略的 SQL 原文 + 两份 EXPLAIN
04 写路径:从 upsert 到嵌套写 一次嵌套 create 是五条语句 ON CONFLICT 原文 + 分块公式 + 事务日志里缺了什么
05 值穿过边界时变成了什么 同一个问题分裂成"静默变形"和"直接报错" 类型对照表 + BigInt 序列化失败 + P2010
06 迁移:从空库、从现成库、从被人改过的库 status 说没事的时候可能正有事 不连库生成 DDL + P3005 + baseline 台账
07 管不到的那部分 池、深翻、方言与体积 池容量实测 + 两组 EXPLAIN 的 rows= 对照

每章结构统一:现场 → 形态 → 原因 → 本章脉络 → 生产边界 → 动手:可观察结果 → 故障注入 → 自测题 → 现在能解释什么。

三个必须先纠偏的认知

  1. include 不是"没有 N+1",是"把 N 次子查询合并成 1 次批量查询"。 代价被挪到了那条 IN ($1,...,$N) 上——占位符个数等于主表返回的行数。真有一条路能把它变成一条 SQL(join 策略),但那条路在关联是"一对多"时会把"N 次往返"换成"一次往返里的 N 次循环",实测在 3000 篇时慢一倍。没有免费的改写,只有代价搬家。
  2. migrate status 说 "up to date" 不等于库和 schema 一致。 它比对的是迁移历史,不是数据库的真实结构。库被人手工改过之后它会照说 up to date,而 migrate dev 给的补救手段是"清空数据、全部重来"。要验证真实一致性,只能用 migrate diff。
  3. 类型问题几乎不出在数据库那一侧。 BigInt 让接口 500、Decimal 静默变成字符串、时间精度在穿过 JS 时丢掉、连原生 SQL 的返回类型都可能被适配器拒绝。这些都不是你的业务逻辑,是类型系统的接缝。

学完这门课你能做什么

前置要求

替身边界

实验以 Prisma 7.10.0 + @prisma/adapter-pg + pg 8.23 + PostgreSQL 16.15 为准。这一行的版本演进比大多数框架都快——本课程记下的多处默认值、CLI 参数、生成器行为都是被某一版改过的(datasource.url 移出 schema、prisma-client 生成器、--to-schema 改名、migrate dev 移除 --skip-generate、连接池默认值变更)。结论的形状("转换在参数侧还是列侧"、"批量查询的占位符随 N 增长"、"基线登记只写台账")跨版本成立,具体数字和参数名请在你自己的版本上复核。

实验数据是一张小表(5000 行 / 20000 行),全部在单机缓存里。凡涉及绝对毫秒数的地方,请只看比值。

进入 keel 阅读