4.4.3 模型定义:字段类型与关系映射
一句话破题
模型定义是 Prisma 的核心——它决定了你的数据结构、关系和约束如何映射到数据库。
完整的模型示例
prisma
model User {
// 标识字段
id String @id @default(cuid())
// 业务字段
email String @unique
name String?
role Role @default(USER)
// 审计字段
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
// 关系字段
posts Post[]
profile Profile?
// 表级约束
@@index([email])
@@map("users") // 映射到数据库表名
}字段类型详解
标量类型:
| Prisma 类型 | TypeScript | PostgreSQL | 说明 |
|---|---|---|---|
String | string | TEXT | 字符串 |
Int | number | INTEGER | 整数 |
BigInt | bigint | BIGINT | 大整数 |
Float | number | DOUBLE PRECISION | 浮点数 |
Decimal | Decimal | DECIMAL | 精确小数(金额) |
Boolean | boolean | BOOLEAN | 布尔值 |
DateTime | Date | TIMESTAMP | 日期时间 |
Json | JsonValue | JSONB | JSON 数据 |
Bytes | Buffer | BYTEA | 二进制数据 |
特殊类型:
prisma
// 枚举类型
enum Role {
USER
ADMIN
MODERATOR
}
model User {
role Role @default(USER)
}
// 字符串数组(PostgreSQL 支持)
model Post {
tags String[]
}字段修饰符
可选与必填:
prisma
model User {
name String // 必填
nickname String? // 可选(可为 null)
}默认值:
prisma
model Post {
id String @id @default(cuid()) // CUID
uuid String @id @default(uuid()) // UUID
createdAt DateTime @default(now()) // 当前时间
status String @default("DRAFT") // 固定值
views Int @default(0) // 数字
isPublic Boolean @default(false) // 布尔
}数据库映射:
prisma
model User {
firstName String @map("first_name") // 字段映射
@@map("users") // 表名映射
}关系定义
一对一关系:
prisma
model User {
id String @id @default(cuid())
profile Profile?
}
model Profile {
id String @id @default(cuid())
bio String?
userId String @unique // 必须唯一
user User @relation(fields: [userId], references: [id])
}一对多关系:
prisma
model User {
id String @id @default(cuid())
posts Post[] // 一个用户有多篇文章
}
model Post {
id String @id @default(cuid())
authorId String
author User @relation(fields: [authorId], references: [id])
}多对多关系(隐式):
prisma
model Post {
id String @id @default(cuid())
tags Tag[]
}
model Tag {
id String @id @default(cuid())
name String @unique
posts Post[]
}
// Prisma 自动创建 _PostToTag 中间表多对多关系(显式):
prisma
model Post {
id String @id @default(cuid())
postTags PostTag[]
}
model Tag {
id String @id @default(cuid())
postTags PostTag[]
}
model PostTag {
postId String
tagId String
createdAt DateTime @default(now())
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@id([postId, tagId])
}级联行为
prisma
model Post {
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
}| 行为 | 删除父记录时 | 更新父记录时 |
|---|---|---|
Cascade | 子记录也删除 | 子记录也更新 |
SetNull | 外键设为 null | 外键设为 null |
Restrict | 阻止删除 | 阻止更新 |
NoAction | 同 Restrict | 同 Restrict |
自引用关系
prisma
// 用户关注关系
model User {
id String @id @default(cuid())
followers User[] @relation("UserFollows")
following User[] @relation("UserFollows")
}
// 评论回复
model Comment {
id String @id @default(cuid())
parentId String?
parent Comment? @relation("CommentReplies", fields: [parentId], references: [id])
replies Comment[] @relation("CommentReplies")
}表级约束
prisma
model TeamMember {
id String @id @default(cuid())
userId String
teamId String
role String
// 复合唯一约束
@@unique([userId, teamId])
// 复合索引
@@index([teamId, role])
// 复合主键(替代 @id)
// @@id([userId, teamId])
}验收清单
定义模型时,检查以下几点:
- [ ] 每个模型都有
@id主键 - [ ] 必填字段没有加
? - [ ] 外键字段类型与引用字段一致
- [ ] 一对一关系的外键有
@unique - [ ] 需要搜索/排序的字段有索引
- [ ] 审计字段(createdAt、updatedAt)已添加
本节小结
- 模型定义包括字段、类型、修饰符和关系
- 使用
?表示可选字段,@default()设置默认值 - 一对一需要
@unique外键,多对多可用隐式或显式 - 使用
@@index和@@unique定义表级约束
