⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

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 类型TypeScriptPostgreSQL说明
StringstringTEXT字符串
IntnumberINTEGER整数
BigIntbigintBIGINT大整数
FloatnumberDOUBLE PRECISION浮点数
DecimalDecimalDECIMAL精确小数(金额)
BooleanbooleanBOOLEAN布尔值
DateTimeDateTIMESTAMP日期时间
JsonJsonValueJSONBJSON 数据
BytesBufferBYTEA二进制数据

特殊类型

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 定义表级约束