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

4.3.3 如何给数据上规矩——约束定义:主键/外键/唯一/检查约束

一句话破题

约束是数据库的"规矩"——它在数据层面强制执行业务规则,防止脏数据进入系统。

约束类型概览

约束作用SQLPrisma
主键唯一标识每一行PRIMARY KEY@id
外键关联其他表FOREIGN KEY@relation
唯一值不能重复UNIQUE@unique
非空值不能为 NULLNOT NULL字段不加 ?
检查自定义条件CHECK需原生 SQL
默认值未指定时的默认值DEFAULT@default()

主键约束(Primary Key)

作用:唯一标识表中的每一行

SQL

sql
CREATE TABLE users (
  id VARCHAR(36) PRIMARY KEY,
  email VARCHAR(255)
);

Prisma

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

主键特点

  • 必须唯一
  • 不能为 NULL
  • 一个表只能有一个主键

外键约束(Foreign Key)

作用:保证关联数据的完整性

SQL

sql
CREATE TABLE posts (
  id VARCHAR(36) PRIMARY KEY,
  author_id VARCHAR(36) REFERENCES users(id)
);

Prisma

prisma
model Post {
  id       String @id
  authorId String
  author   User   @relation(fields: [authorId], references: [id])
}

外键行为选项

行为说明Prisma
CASCADE父记录删除,子记录也删除onDelete: Cascade
SET NULL父记录删除,子记录外键设为 NULLonDelete: SetNull
RESTRICT有子记录时禁止删除父记录onDelete: Restrict
prisma
model Post {
  id       String @id
  authorId String
  author   User   @relation(fields: [authorId], references: [id], onDelete: Cascade)
}

唯一约束(Unique)

作用:保证字段值不重复

SQL

sql
CREATE TABLE users (
  id VARCHAR(36) PRIMARY KEY,
  email VARCHAR(255) UNIQUE
);

Prisma

prisma
model User {
  id    String @id
  email String @unique
}

复合唯一约束:多个字段组合唯一

prisma
model TeamMember {
  id     String @id
  userId String
  teamId String
  
  @@unique([userId, teamId])  // 一个用户在一个团队只能有一条记录
}

非空约束(Not Null)

作用:字段不能为空

SQL

sql
CREATE TABLE users (
  id VARCHAR(36) PRIMARY KEY,
  email VARCHAR(255) NOT NULL
);

Prisma

prisma
model User {
  id    String @id
  email String      // 不加 ? 就是 NOT NULL
  name  String?     // 加 ? 表示可以为 NULL
}

检查约束(Check)

作用:自定义数据验证规则

SQL

sql
CREATE TABLE products (
  id VARCHAR(36) PRIMARY KEY,
  price DECIMAL(10,2) CHECK (price > 0),
  stock INTEGER CHECK (stock >= 0)
);

Prisma 不直接支持,需要用原生 SQL

sql
ALTER TABLE products ADD CONSTRAINT price_positive CHECK (price > 0);

默认值约束(Default)

作用:未指定值时使用默认值

SQL

sql
CREATE TABLE users (
  id VARCHAR(36) PRIMARY KEY,
  status VARCHAR(20) DEFAULT 'ACTIVE',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Prisma

prisma
model User {
  id        String   @id @default(cuid())
  status    String   @default("ACTIVE")
  createdAt DateTime @default(now())
}

约束的价值

为什么要用约束

  1. 应用层验证可能被绕过(API 直接调用、SQL 注入)
  2. 数据库约束是最后一道防线
  3. 约束能提供更好的错误信息

本节小结

  • 约束在数据库层面强制执行规则
  • 主键唯一标识记录,外键保证关联完整性
  • 唯一约束防止重复,检查约束自定义规则
  • 应用层验证 + 数据库约束 = 双重保障