prisma-database-modelling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePrisma 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
不可妥协的原则
- Database enforces integrity: prefer real foreign keys and constraints in Postgres (avoid app-only integrity unless explicitly required).
- Schema is the source of truth: treat + migrations as canonical.
schema.prisma - Explicit > implicit: name relations, indexes, constraints; avoid “magic” conventions that are unclear.
- Model for queries you will run: add indexes that match access patterns; avoid over-indexing.
- 数据库强制完整性:优先在 PostgreSQL 中使用真实的外键和约束(除非明确要求,否则避免仅在应用层保证完整性)。
- 架构为唯一可信源:将 + 迁移文件视为权威依据。
schema.prisma - 显式优于隐式:为关系、索引、约束命名;避免使用模糊的“魔法”规范。
- 针对实际查询建模:添加与访问模式匹配的索引;避免过度索引。
Standard conventions (use unless user overrides)
标准规范(除非用户覆盖,否则默认遵循)
- Primary keys: for app-level IDs, or
id String @id @default(cuid())for DB-generated numeric IDs.id BigInt @id @default(autoincrement()) - Timestamps:
createdAt DateTime @default(now())updatedAt DateTime @updatedAt
- Soft delete (optional, only if asked): + indexes on
deletedAt DateTime?and hot query fields.(deletedAt) - Naming:
- Prisma model names:
PascalCase - Fields:
camelCase - DB naming: map to using
snake_caseand@maponly if the project standard requires it.@@map
- Prisma model names:
- Use for common filters/sorts and foreign keys; use
@@indexfor business uniqueness.@@unique
- 主键:应用级 ID 使用 ,数据库生成的数值 ID 使用
id String @id @default(cuid())。id BigInt @id @default(autoincrement()) - 时间戳:
createdAt DateTime @default(now())updatedAt DateTime @updatedAt
- 软删除(可选,仅在用户要求时使用):+ 为
deletedAt DateTime?和高频查询字段添加索引。(deletedAt) - 命名:
- Prisma 模型名称:使用 (大驼峰)
PascalCase - 字段:使用 (小驼峰)
camelCase - 数据库命名:仅当项目标准要求时,通过 和
@map映射为@@map(下划线命名)。snake_case
- Prisma 模型名称:使用
- 为常用筛选/排序字段和外键使用 ;为业务唯一性使用
@@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 on FK field (or
@uniquecomposite).@@unique - 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 only when deletion should delete children.
onDelete: Cascade - Prefer /
Restrictwhen deletion should be blocked until children are handled.NoAction - Use only if nullable and you want orphaning.
SetNull
(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.mdIndexing checklist
索引检查清单
- Index all foreign key columns.
- Add composite indexes that match:
- tenant scoping ()
tenantId, createdAt - common filters + sort (— in Prisma you express this as
status, createdAt DESCand query with@@index([status, createdAt])).orderBy
- tenant scoping (
- Use unique constraints for natural keys:
- or
(tenantId, slug).(workspaceId, email)
- 为所有外键列添加索引。
- 添加与以下场景匹配的复合索引:
- 租户隔离()
tenantId, createdAt - 常用筛选+排序(— 在 Prisma 中可表示为
status, createdAt DESC,查询时配合@@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 /
@mapwhen renaming in Prisma but keeping DB column stable.@@map - Never “edit” deployed migrations—create new migrations.
当演进架构时:
- 先将新增列设为可空,回填数据后再设为必填。
- 避免在未进行数据迁移的情况下删除/重命名列。
- 当需要在 Prisma 中重命名但保持数据库列稳定时,优先使用 /
@map。@@map - 切勿“编辑”已部署的迁移文件——应创建新的迁移。
Output format
输出格式
When asked to model something, respond with:
- Updated Prisma schema snippets (models/enums).
- Rationale (constraints, relations, indexes).
- Migration plan (steps if change is non-trivial).
当用户要求建模时,按以下格式响应:
- 更新后的 Prisma 架构代码片段(模型/枚举类型)。
- 设计依据(约束、关系、索引的说明)。
- 迁移计划(若变更非 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