枚举与自定义 JSON 类型
枚举(enum)
Prisma Schema 里的 enum 是独立的顶层声明,字段可以引用它来约束取值范围:
enum Role {
USER
ADMIN
MODERATOR
}
model User {
id Int @id
role Role @default(USER)
}
Prisma Client 生成的 TypeScript 类型里,role 字段会被推断为字面量联合类型 'USER' | 'ADMIN' | 'MODERATOR',TypeScript 编译器会帮你检查赋值。
数据库层面的表现
- PostgreSQL:Prisma Migrate 会创建原生 PostgreSQL enum 类型,字段类型就是这个 enum
- MySQL:MySQL 有原生 ENUM 类型,直接映射
- SQLite:SQLite 没有原生枚举,Prisma 在客户端层做校验,数据库里存字符串
- MongoDB:作为字符串存
自定义枚举值
默认 Prisma 直接用枚举名作为数据库值。如果需要不同的字符串:
enum Role {
@map("customer")
USER
@map("admin_user")
ADMIN
}
数据库里存的是 customer 和 admin_user,但 Prisma Client 里用 USER 和 ADMIN。
Json 字段
Json 类型可以存储任意 JSON 数据:
model Settings {
id Int @id
preferences Json
}
Prisma Client 里你可以直接赋值和读取 JavaScript 对象:
await prisma.settings.create({
data: {
preferences: { theme: 'dark', notifications: { email: true, sms: false } },
},
})
const settings = await prisma.settings.findFirst()
console.log(settings?.preferences.theme) // 'dark'
数据库支持情况
| 数据库 | JSON 支持 | 备注 |
|---|---|---|
| PostgreSQL | ✅ 完整 | JSONB 类型,支持索引查询 |
| MySQL | ✅ 完整 | JSON 类型 |
| MongoDB | ✅ 完整 | 天然文档型 |
| SQLite | ❌ 不支持 |
查询 JSON 字段
PostgreSQL 的 JSONB 支持对 JSON 内部进行筛选:
// Schema
model Log {
id Int @id
payload Json
}
// 查询 payload 对象里 level = "error" 的记录
const errors = await prisma.log.findMany({
where: {
payload: {
path: ['level'],
equals: 'error',
},
},
})
注意:对 JSON 内部结构的查询支持因数据库而异,PostgreSQL 支持最完整。MySQL 的 JSON 查询需要用 raw 回退。
什么时候用 Json 字段
- 灵活的配置数据:用户偏好、Feature Flags、动态表单数据等
- 审计日志 / 事件存储:字段结构不固定、经常变化
- 避免频繁迁移:某些数据结构经常变,但不想每次改 Schema 就跑一次迁移
不要把本来应该是结构化关系数据的东西塞进 Json 字段——那会丧失类型安全和关系查询能力。