首页 / Prisma ORM 入门教程 / 模型与字段:标量类型与修饰符

Prisma ORM 入门教程

模型与字段:标量类型与修饰符

本教程共 54 篇 · 第 8 篇 · 更新于 2026-08-11 · 约 6 分钟阅读

Prisma模型标量类型修饰符字段属性@default@map数据建模

本节目标:掌握 model 块的写法、九种标量类型与 ?/[] 修饰符,认识常用字段属性。

模型(model)是 Schema 的主角。一个模型代表业务里的一个实体,比如用户、订单、文章;在关系型数据库里,它对应一张表。模型的名字用 PascalCase 单数形式(User 而不是 users),字段名用 camelCase(firstName)。命名要满足正则 [A-Za-z][A-Za-z0-9_]*:字母开头,后面可以是字母、数字、下划线。表名想用复数或 snake_case,那是数据库层的事,用 @@map 解耦(下文细说)。

字段的四要素

每个字段由四部分组成:名字、类型、可选的修饰符、可选的属性。

model User {
  id        Int      @id @default(autoincrement())  // 名字 类型 属性
  email     String   @unique
  name      String?                                // ? 是修饰符
  createdAt DateTime @default(now())
}

字段类型分两类:标量类型(对应数据库的一列)和模型类型(即关系字段,指向另一个模型,第 11 章详解)。本节只看标量。

九种标量类型

Prisma 类型TypeScript 类型PostgreSQL 默认用途
Stringstringtext文本
Booleanbooleanboolean真假值
Intnumberinteger32 位整数
BigIntbigintbigint大整数,超出 Int 范围时用
Floatnumberdouble precision浮点数
DecimalDecimal.jsdecimal(65,30)高精度小数,金额推荐
DateTimeDatetimestamp(3)时间
JsonJsonValuejsonb任意 JSON 数据
BytesUint8Arraybytea二进制数据

选择原则很简单:整数用 Int,超大整数用 BigInt,钱用 Decimal 而不是 Float(浮点有精度误差),结构化数据用 Json

几个容易踩的类型细节:

  • Int 是 32 位整数,上限约 21 亿。计数、ID 完全够用;一旦可能超过(比如埋点数据的累计值),提前用 BigInt
  • Decimal 精度可达 65 位,钱和精确计算用它;Float 适合不需要精确相等的科学计算。
  • Json 适合结构不固定的数据(配置、元数据)。注意它是「不透明」的,查询过滤能力有限。
  • Bytes 存二进制,比如文件哈希、图片数据。
  • DateTime 在 JS 侧永远是 Date 对象,存的是时间戳语义,别拿它当字符串用。

修饰符:? 与 []

修饰符改变字段的可选性:

  • ? 让字段可空,对应数据库的 NULLname String? 表示名字可以没有。
  • [] 让字段变成列表,如 String[] 存多个字符串。列表修饰符在关系里更常见(Post[])。
model Comment {
  id      Int      @id @default(autoincrement())
  title   String        // 必填,数据库里是 NOT NULL
  content String?       // 可选,可为 NULL
  tags    String[]      // 标量列表
}

不加修饰符的字段必填。在 TypeScript 侧,可选字段类型是 string | null,编译期就强制你处理空值。数据库层面对应 NOT NULL 约束——迁移时 Prisma 会按修饰符自动生成 NOT NULL 或可空列。

一个完整的模型

把本节知识拼起来,看一个完整例子:

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  age       Int      @default(18)
  score     Decimal  @default(0) @db.Decimal(10, 2)
  createdAt DateTime @default(now())
  posts     Post[]

  @@map("users")
}

既有必填、可选、默认值,又有原生类型和表名映射。模型之间的关系字段(posts Post[])留到第 11 章,这里先把标量字段的骨架搭扎实。

Note

?[] 不能组合使用——不支持「可选的列表」。另外标量列表需要数据库原生支持,PostgreSQL 没问题,SQLite 不支持。

常用字段属性总览

属性(attribute)以 @ 开头,修改字段或模型的行为。先认识最常见的几个,细节在后续章节展开:

属性作用
@id标记为主键(第 9 章)
@unique唯一约束(第 9 章)
@default(...)默认值,可填静态值或函数(第 9 章)
@map("列名")把字段映射到指定数据库列名
@updatedAt更新时自动写时间(第 9 章)
@ignore从生成的 Prisma Client 中排除该字段
@db.XXX指定原生数据库类型,如 @db.VarChar(255)(第 10 章)

@@ 开头的是块属性,作用于整个模型:@@map("表名")@@id([...])@@unique([...])@@index([...])

@map:模型名与表名解耦

Prisma 的命名习惯(PascalCase 单数)未必和数据库一致。数据库表常用复数 snake_case,比如 comments。用 @@map 让两边各用各的名字:

model Comment {
  id      Int    @id @default(autoincrement())
  author  String @map("author_name")  // 列名是 author_name
  content String

  @@map("comments")                    // 表名是 comments
}

代码里依然用 prisma.commentauthor,数据库里却是 comments 表和 author_name 列。@map 管字段,@@map 管模型,互不干扰。

@ignore:不想暴露的字段

有些字段(比如内部标志位)不想让 Prisma Client 碰。加上 @ignore,它就从生成的客户端里消失:

model User {
  id        Int    @id @default(autoincrement())
  name      String
  email     String @ignore   // 客户端看不到这个字段
}
Note

必填字段若加 @ignore 且没有默认值,模型的 create 方法会被禁用,因为数据库无法在没有该数据的情况下建行。内省对无法表达的列用 Unsupported 标记;想排除模型需手动加 @@ignore

默认值函数一览

@default() 除了填静态值(5"draft"false),还可以调函数:

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  uuid      String   @default(uuid())
  status    String   @default("draft")
}

常用函数有 now()(当前时间)、uuid()(UUID)、cuid()(CUID)、nanoid()(NanoID)、autoincrement()(自增)、dbgenerated("SQL")(原生 SQL 默认值)。每个函数的适用场景和细节,第 9 章逐个讲透。

参考来源

  • Prisma 官方文档:Models(数据模型定义)、Prisma schema reference(标量类型与属性)
  • Prisma 官方文档:Attribute functions