首页 / Prisma ORM 入门教程 / 引用操作:级联删除与约束行为

Prisma ORM 入门教程

引用操作:级联删除与约束行为

本教程共 54 篇 · 第 14 篇 · 更新于 2026-08-11 · 约 4 分钟阅读

Prisma引用操作级联删除onDeleterelationMode外键约束

本节目标:掌握 onDelete/onUpdate 五种动作与默认值,避开循环引用陷阱,理解 relationMode 的两种模式。

删掉一个用户,他的文章怎么办?一起删、保留但置空作者、还是干脆拒绝删除?答案由引用操作(referential actions)决定。

引用操作写在 @relation 属性里,最终映射为数据库的外键约束:

model Post {
  id       Int    @id @default(autoincrement())
  title    String
  author   User   @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId Int
}

model User {
  id    Int    @id @default(autoincrement())
  posts Post[]
}

onDelete 管删除父记录,onUpdate 管父记录主键值变化。Prisma 提供五种动作。

五种动作

动作删除父记录时适用场景
Cascade子记录一并删除文章与评论
Restrict有子记录就拒绝删除保护历史数据
NoAction基本同 Restrict,PG 可延迟到事务末尾检查SQL Server 兼容
SetNull外键置空作者注销但保留文章
SetDefault外键恢复默认值匿名作者

写法就是在 @relation 里加参数:

// 作者注销后,文章保留,authorId 置空
author   User?  @relation(fields: [authorId], references: [id], onDelete: SetNull)
authorId Int?

SetNull 要求外键可选;SetDefault 要求外键有 @default。组合用错,迁移或运行时会报错。

Note

隐式多对多不支持引用操作。想级联清理连接记录,必须转成显式多对多,把动作写在连接表模型上。

默认值:不写也有行为

什么都不写时,Prisma 按关系是否必填套默认值:

  • onDelete:必填关系用 Restrict,可选关系用 SetNull
  • onUpdate:一律 Cascade

口诀:删必填要拦,删可选可空,改主键跟着走。

各家数据库还有自己的脾气:

  • MySQL/MariaDB 不支持 SetDefault(8.0+ 把它当 NoAction 别名)
  • PostgreSQL 允许对非空字段声明 SetNull,但触发时会报错,Prisma 会警告你改成可选
  • SQL Server 没有 Restrict,用 NoAction 代替

循环引用陷阱

默认的 onUpdate: Cascade 在自关系里会形成循环。员工与经理的关系就是这样:

model Employee {
  id        Int        @id @default(autoincrement())
  manager   Employee?  @relation("management", fields: [managerId], references: [id], onUpdate: NoAction, onDelete: NoAction)
  managees  Employee[] @relation("management")
  managerId Int?
}

在 SQL Server 和 MongoDB 上,自关系、三表循环、多条级联路径都会触发校验错误,提示你把其中一侧的 onDelete/onUpdate 改成 NoAction 来断环。Prisma 在生成 SQL 前就会检查出来,不用等数据库报错。

Tip

环路的本质是「级联追着自己跑」。任选一条边改成 NoAction,环就断了。

relationMode:外键还是模拟

关系模式由 datasource 块里的 relationMode 控制:

datasource db {
  provider     = "mysql"
  relationMode = "prisma"
}

两种模式:

  • foreignKeys(默认):外键约束和引用操作都在数据库执行,Prisma Migrate 会生成对应的 ADD CONSTRAINT SQL
  • prisma:Prisma Client 用额外查询模拟引用完整性,给不支持外键的数据库用,比如 PlanetScale 和 MongoDB

模拟模式有代价:

  1. 每个相关操作多跑几条查询,性能有损耗
  2. 不自动创建外键索引,要在关系标量字段上手动加 @@index,否则查关联会全表扫描
  3. NoAction(PG/SQLite)、SetDefault 在模拟模式下不支持

错误消息也不一样:foreignKeys 报「外键约束失败」,prisma 模式报「违反必填关系」。

Tip

只要数据库支持外键,就用默认的 foreignKeys。模拟模式是给 PlanetScale 这类特殊场景准备的。

MongoDB 只有 prisma 模式可用,但 v7 不支持 MongoDB,相关讨论留到 v6.19 教程。

参考来源

  • Prisma 官方文档:Referential actions
  • Prisma 官方文档:Relation mode
  • Mapagam:Understanding Referential Actions