Skip to content
On this page

Prisma Schema 定义

Prisma Schema 文件(通常命名为 schema.prisma)是 Prisma 项目的中心配置文件。它定义了数据模型、数据库连接和客户端生成器。本指南将详细介绍如何定义和使用 Prisma Schema。

Schema 文件结构

每个 Prisma Schema 文件包含三个主要部分:

prisma
// schema.prisma

// 1. 生成器定义 - 定义如何生成客户端代码
generator client {
  provider = "prisma-client-js"
  output   = "../node_modules/@prisma/client"
}

// 2. 数据源定义 - 定义数据库连接
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// 3. 数据模型定义 - 定义数据库表结构
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
}

生成器(Generator)

生成器定义了如何生成 Prisma Client 代码:

prisma
generator client {
  provider        = "prisma-client-js"           // 指定生成器提供者
  output          = "../generated/client"        // 输出目录
  engineType      = "binary"                     // 引擎类型
  previewFeatures = ["fullTextSearch"]          // 预览功能
}

常用生成器选项

  • provider: 指定生成器,通常是 "prisma-client-js"
  • output: 指定生成代码的输出位置
  • previewFeatures: 启用预览功能

数据源(Datasource)

数据源定义了数据库连接信息:

prisma
datasource db {
  provider = "postgresql"                        // 数据库类型
  url      = env("DATABASE_URL")                // 连接字符串
  directUrl = env("DIRECT_URL")                 // 直接连接 URL(用于迁移)
}

支持的数据库类型

  • postgresql - PostgreSQL
  • mysql - MySQL
  • sqlite - SQLite
  • sqlserver - Microsoft SQL Server
  • mongodb - MongoDB

环境变量配置

在 .env 文件中配置数据库连接:

text
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
DIRECT_URL="postgresql://user:password@localhost:5432/mydb?schema=public"

数据模型(Data Model)

数据模型定义了数据库表的结构:

prisma
model User {
  id        Int      @id @default(autoincrement())  // 主键
  createdAt DateTime @default(now())                // 默认值
  email     String   @unique                        // 唯一约束
  name      String?                                 // 可选字段
  posts     Post[]                                  // 一对多关系
  profile   Profile?                                // 一对一关系
}

字段类型

标量类型

prisma
model DataTypes {
  // 数字类型
  id        Int      @id @default(autoincrement())
  bigId     BigInt
  score     Float
  amount    Decimal
  
  // 字符串类型
  name      String
  slug      String @db.VarChar(255)
  
  // 布尔类型
  isActive  Boolean
  
  // 日期时间类型
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  
  // 二进制类型
  avatar    Bytes?
  
  // JSON 类型(根据数据库支持)
  metadata  Json?
}

枚举类型

prisma
enum Role {
  USER
  ADMIN
  MODERATOR
}

model User {
  id   Int  @id @default(autoincrement())
  role Role @default(USER)
}

字段属性(Attributes)

字段属性用于定义字段的行为和约束:

ID 相关属性

prisma
model User {
  // 自增主键
  id Int @id @default(autoincrement())
  
  // UUID 主键
  uuid String @id @default(uuid())
  
  // CUID 主键
  cuid String @id @default(cuid())
  
  // 复合主键
  email String
  tenantId String
  @@id([email, tenantId])
}

默认值属性

prisma
model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  published Boolean  @default(false)
  views     Int      @default(0)
  rating    Float    @default(0.0)
}

唯一性约束

prisma
model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  // 复合唯一约束
  username String
  tenantId String
  @@unique([username, tenantId])
}

索引

prisma
model Post {
  id        Int    @id @default(autoincrement())
  title     String
  slug      String @unique
  createdAt DateTime
  
  // 复合索引
  @@index([createdAt, title])
  
  // 唯一复合索引
  @@unique([title, createdAt])
  
  // 指定索引名称
  @@index([slug], map: "idx_post_slug")
}

关系定义

一对一关系

prisma
model User {
  id      Int     @id @default(autoincrement())
  email   String  @unique
  profile Profile?
}

model Profile {
  id     Int    @id @default(autoincrement())
  bio    String?
  user   User   @relation(fields: [userId], references: [id])
  userId Int    @unique  // 外键,也是唯一约束(一对一)
}

一对多关系

prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  posts Post[]  // 一对多:一个用户有多篇文章
}

model Post {
  id       Int    @id @default(autoincrement())
  title    String
  author   User   @relation(fields: [authorId], references: [id])
  authorId Int    // 关系标量字段(外键)
}

多对多关系

prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  roles     Role[]   // 多对多关系
  createdAt DateTime @default(now())
}

model Role {
  id          Int     @id @default(autoincrement())
  name        String  @unique
  users       User[]
  permissions Permission[]
}

model Permission {
  id    Int   @id @default(autoincrement())
  name  String @unique
  roles Role[]
}

模型属性(Model Attributes)

行为属性

prisma
model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String
  
  // 定义映射到数据库的实际表名
  @@map("users_table")
  
  // 定义评论
  @@doc("用户信息表")
}

安全相关属性

prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  password  String   @omit  // 在客户端中省略此字段
  createdAt DateTime @default(now())
  
  // 省略整个模型
  @@ignore  // 不会在客户端中生成此模型
}

自定义数据库列名

prisma
model User {
  id    Int    @id @default(autoincrement()) @map("user_id")
  email String @unique @map("email_address")
  name  String @map("full_name")
  
  @@map("app_users")  // 数据库表名
}

数据库特定类型

PostgreSQL 特定类型

prisma
model PostgresSpecific {
  id          Int      @id @default(autoincrement())
  jsonArray   Json?
  inetAddr    String   @db.Inet
  citext      String   @db.Citext
  arrayField  String[] @db.Text[]
  enumArray   Status[]
  
  @@map("postgres_specific_table")
}

MySQL 特定类型

prisma
model MySQLSpecific {
  id        Int     @id @default(autoincrement())
  longtext  String  @db.LongText
  tinyint   Int     @db.TinyInt
  datetime  DateTime @db.DateTime(6)
  
  @@map("mysql_specific_table")
}

高级 Schema 配置

使用多个数据源

prisma
generator client {
  provider = "prisma-client-js"
}

datasource mysql {
  provider = "mysql"
  url      = env("MYSQL_URL")
}

datasource postgresql {
  provider = "postgresql"
  url      = env("POSTGRES_URL")
}

// 模型需要明确指定数据源
model User {
  id    Int @id @default(autoincrement())
  email String @unique
  
  @@schema("mysql")  // 指定使用哪个数据源
}

模型映射到现有数据库

prisma
model User {
  id    Int    @id @default(autoincrement())
  email String @unique @map("email_address")
  name  String @map("full_name")
  
  @@map("existing_users_table")  // 映射到现有的数据库表
}

Schema 验证和最佳实践

验证 Schema

bash
# 验证 Schema 语法
npx prisma validate

# 生成客户端
npx prisma generate

# 检查数据库连接
npx prisma db pull

Schema 设计最佳实践

  1. 使用有意义的模型和字段名称
  2. 适当使用索引优化查询性能
  3. 考虑数据一致性,合理设计关系
  4. 使用枚举类型约束字段值
  5. 为敏感数据使用 @omit 属性

通过正确配置 Prisma Schema,您可以充分利用 Prisma 的强大功能来管理数据库架构和数据访问逻辑。