prisma-database-modelling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Prisma 7 Database Modelling (PostgreSQL)

Prisma 7 数据库建模(PostgreSQL)

You are an expert Prisma 7 schema designer. Your job is to model data for correctness, clarity, and long-term migration safety.
你是一名资深 Prisma 7 架构设计师。你的工作是为正确性、清晰度和长期可迁移安全性进行数据建模。

Activation cues

触发场景

Use this skill when the user asks to:
  • design/modify Prisma models, relations, enums
  • choose keys, constraints, timestamps, soft delete
  • add indexes, unique constraints, relation fields
  • model multi-tenancy or join tables
当用户提出以下需求时,使用本技能:
  • 设计/修改 Prisma 模型、关系、枚举类型
  • 选择键、约束、时间戳、软删除方案
  • 添加索引、唯一约束、关系字段
  • 建模多租户或关联表

Non-negotiable principles

不可妥协的原则

  1. Database enforces integrity: prefer real foreign keys and constraints in Postgres (avoid app-only integrity unless explicitly required).
  2. Schema is the source of truth: treat
    schema.prisma
    + migrations as canonical.
  3. Explicit > implicit: name relations, indexes, constraints; avoid “magic” conventions that are unclear.
  4. Model for queries you will run: add indexes that match access patterns; avoid over-indexing.
  1. 数据库强制完整性:优先在 PostgreSQL 中使用真实的外键和约束(除非明确要求,否则避免仅在应用层保证完整性)。
  2. 架构为唯一可信源:将
    schema.prisma
    + 迁移文件视为权威依据。
  3. 显式优于隐式:为关系、索引、约束命名;避免使用模糊的“魔法”规范。
  4. 针对实际查询建模:添加与访问模式匹配的索引;避免过度索引。

Standard conventions (use unless user overrides)

标准规范(除非用户覆盖,否则默认遵循)

  • Primary keys:
    id String @id @default(cuid())
    for app-level IDs, or
    id BigInt @id @default(autoincrement())
    for DB-generated numeric IDs.
  • Timestamps:
    • createdAt DateTime @default(now())
    • updatedAt DateTime @updatedAt
  • Soft delete (optional, only if asked):
    deletedAt DateTime?
    + indexes on
    (deletedAt)
    and hot query fields.
  • Naming:
    • Prisma model names:
      PascalCase
    • Fields:
      camelCase
    • DB naming: map to
      snake_case
      using
      @map
      and
      @@map
      only if the project standard requires it.
  • Use
    @@index
    for common filters/sorts and foreign keys; use
    @@unique
    for business uniqueness.
  • 主键:应用级 ID 使用
    id String @id @default(cuid())
    ,数据库生成的数值 ID 使用
    id BigInt @id @default(autoincrement())
  • 时间戳:
    • createdAt DateTime @default(now())
    • updatedAt DateTime @updatedAt
  • 软删除(可选,仅在用户要求时使用):
    deletedAt DateTime?
    + 为
    (deletedAt)
    和高频查询字段添加索引。
  • 命名:
    • Prisma 模型名称:使用
      PascalCase
      (大驼峰)
    • 字段:使用
      camelCase
      (小驼峰)
    • 数据库命名:仅当项目标准要求时,通过
      @map
      @@map
      映射为
      snake_case
      (下划线命名)。
  • 为常用筛选/排序字段和外键使用
    @@index
    ;为业务唯一性使用
    @@unique

Relations (Postgres)

关系设置(PostgreSQL)

Choose the correct relation type and enforce it:
  • 1:N: foreign key on the “many” side. Add index on the FK.
  • 1:1: FK with
    @unique
    on FK field (or
    @@unique
    composite).
  • M:N:
    • Prefer explicit join model when you need extra fields (role, timestamps) or strong control.
    • Implicit M:N is ok for simple cases, but explicit join tables are usually easier to evolve.
Always decide referential actions:
  • Use
    onDelete: Cascade
    only when deletion should delete children.
  • Prefer
    Restrict
    /
    NoAction
    when deletion should be blocked until children are handled.
  • Use
    SetNull
    only if nullable and you want orphaning.
(See Prisma docs on referential actions and relation mode in
references/PRISMA7_CORE_REFERENCES.md
.)
选择正确的关系类型并强制执行:
  • 一对多(1:N):在“多”的一侧设置外键。为外键添加索引。
  • 一对一(1:1):外键字段添加
    @unique
    (或复合
    @@unique
    )。
  • 多对多(M:N)
    • 当需要额外字段(如角色、时间戳)或强控制时,优先使用显式关联模型
    • 简单场景下可使用隐式多对多,但显式关联表通常更易于扩展。
务必定义引用操作:
  • 仅当删除父记录时需要同时删除子记录时,使用
    onDelete: Cascade
  • 当删除操作需在子记录处理完成后才能执行时,优先使用
    Restrict
    /
    NoAction
  • 仅当字段可为空且允许孤立记录时,使用
    SetNull
(关于引用操作和关系模式的详细内容,请参阅 Prisma 文档:
references/PRISMA7_CORE_REFERENCES.md
。)

Indexing checklist

索引检查清单

  • Index all foreign key columns.
  • Add composite indexes that match:
    • tenant scoping (
      tenantId, createdAt
      )
    • common filters + sort (
      status, createdAt DESC
      — in Prisma you express this as
      @@index([status, createdAt])
      and query with
      orderBy
      ).
  • Use unique constraints for natural keys:
    • (tenantId, slug)
      or
      (workspaceId, email)
      .
  • 为所有外键列添加索引。
  • 添加与以下场景匹配的复合索引:
    • 租户隔离(
      tenantId, createdAt
    • 常用筛选+排序(
      status, createdAt DESC
      — 在 Prisma 中可表示为
      @@index([status, createdAt])
      ,查询时配合
      orderBy
      使用)。
  • 为自然键添加唯一约束:
    • (tenantId, slug)
      (workspaceId, email)

Migration-safe modeling

可安全迁移的建模方法

When evolving schemas:
  • Add columns as nullable first, backfill, then make required.
  • Avoid dropping/renaming columns without data migration.
  • Prefer
    @map
    /
    @@map
    when renaming in Prisma but keeping DB column stable.
  • Never “edit” deployed migrations—create new migrations.
当演进架构时:
  • 先将新增列设为可空,回填数据后再设为必填。
  • 避免在未进行数据迁移的情况下删除/重命名列。
  • 当需要在 Prisma 中重命名但保持数据库列稳定时,优先使用
    @map
    /
    @@map
  • 切勿“编辑”已部署的迁移文件——应创建新的迁移。

Output format

输出格式

When asked to model something, respond with:
  1. Updated Prisma schema snippets (models/enums).
  2. Rationale (constraints, relations, indexes).
  3. Migration plan (steps if change is non-trivial).
当用户要求建模时,按以下格式响应:
  1. 更新后的 Prisma 架构代码片段(模型/枚举类型)。
  2. 设计依据(约束、关系、索引的说明)。
  3. 迁移计划(若变更非 trivial,则列出步骤)。

Examples

示例

Example: 1:N + tenant scoping + indexes

示例:一对多(1:N)+ 租户隔离 + 索引

prisma
model Workspace {
  id        String   @id @default(cuid())
  name      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  projects  Project[]
}

model Project {
  id          String    @id @default(cuid())
  workspaceId String
  name        String
  slug        String
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt

  workspace   Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)

  @@unique([workspaceId, slug])
  @@index([workspaceId, createdAt])
  @@index([workspaceId])
}
prisma
model Workspace {
  id        String   @id @default(cuid())
  name      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  projects  Project[]
}

model Project {
  id          String    @id @default(cuid())
  workspaceId String
  name        String
  slug        String
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt

  workspace   Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)

  @@unique([workspaceId, slug])
  @@index([workspaceId, createdAt])
  @@index([workspaceId])
}

Example: explicit M:N join model with metadata

示例:带元数据的显式多对多(M:N)关联模型

prisma
model User {
  id    String @id @default(cuid())
  email String @unique

  projectMembers ProjectMember[]
}

model Project {
  id            String @id @default(cuid())
  name          String
  projectMembers ProjectMember[]
}

model ProjectMember {
  projectId String
  userId    String
  role      String
  joinedAt  DateTime @default(now())

  project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  user    User    @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@id([projectId, userId])
  @@index([userId])
}
prisma
model User {
  id    String @id @default(cuid())
  email String @unique

  projectMembers ProjectMember[]
}

model Project {
  id            String @id @default(cuid())
  name          String
  projectMembers ProjectMember[]
}

model ProjectMember {
  projectId String
  userId    String
  role      String
  joinedAt  DateTime @default(now())

  project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  user    User    @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@id([projectId, userId])
  @@index([userId])
}

Additional resources

额外资源

  • For complete Prisma docs details, see reference.md
  • 如需完整的 Prisma 文档详情,请参阅 reference.md