Skip to main content

一对多关系

本页介绍一对多关系并解释如何在 Prisma 模式中使用它们。

¥This page introduces one-to-many relations and explains how to use them in your Prisma schema.

概述

¥Overview

一对多 (1-n) 关系是指关系一侧的一条记录可以连接到另一侧的零个或多个记录的关系。在以下示例中,UserPost 模型之间存在一对多关系:

¥One-to-many (1-n) relations refer to relations where one record on one side of the relation can be connected to zero or more records on the other side. In the following example, there is one one-to-many relation between the User and Post models:

model User {
id Int @id @default(autoincrement())
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int
}

注意 posts 字段在底层数据库模式中不存在 "manifest"。在关系的另一侧,带注释的关系字段 author 及其关系标量 authorId 表示关系中将外键存储在基础数据库中的一侧。

¥The posts field does not "manifest" in the underlying database schema. On the other side of the relation, the annotated relation field author and its relation scalar authorId represent the side of the relation that stores the foreign key in the underlying database.

这种一对多关系表达如下:

¥This one-to-many relation expresses the following:

  • "一个用户可以有零个或多个帖子"

    ¥"a user can have zero or more posts"

  • "帖子必须始终有作者"

    ¥"a post must always have an author"

在前面的示例中,Post 模型的 author 关系字段引用了 User 模型的 id 字段。你还可以引用不同的字段。在这种情况下,你需要使用 @unique 属性来标记该字段,以保证每个 Post 上只有一个 User 连接。在以下示例中,author 字段引用 User 模型中的 email 字段,该字段用 @unique 属性标记:

¥In the previous example, the author relation field of the Post model references the id field of the User model. You can also reference a different field. In this case, you need to mark the field with the @unique attribute, to guarantee that there is only a single User connected to each Post. In the following example, the author field references an email field in the User model, which is marked with the @unique attribute:

model User {
id Int @id @default(autoincrement())
email String @unique // <-- add unique attribute
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
authorEmail String
author User @relation(fields: [authorEmail], references: [email])
}
warning

在 MySQL 中,你可以创建仅在引用端有索引且没有唯一约束的外键。在 Prisma ORM 版本 4.0.0 及更高版本中,如果你内省这种类型的关系,它将触发验证错误。要解决此问题,你需要向引用的字段添加 @unique 约束。

¥In MySQL, you can create a foreign key with only an index on the referenced side, and not a unique constraint. In Prisma ORM versions 4.0.0 and later, if you introspect a relation of this type it will trigger a validation error. To fix this, you will need to add a @unique constraint to the referenced field.

关系数据库中的多字段关系

¥Multi-field relations in relational databases

仅在关系数据库中,你还可以使用 多字段 ID/复合键定义此关系:

¥In relational databases only, you can also define this relation using multi-field IDs/composite key:

model User {
firstName String
lastName String
post Post[]

@@id([firstName, lastName])
}

model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorFirstName, authorLastName], references: [firstName, lastName])
authorFirstName String // relation scalar field (used in the `@relation` attribute above)
authorLastName String // relation scalar field (used in the `@relation` attribute above)
}

数据库中的 1-n 关系

¥1-n relations in the database

关系数据库

¥Relational databases

以下示例演示如何在 SQL 中创建 1-n 关系:

¥The following example demonstrates how to create a 1-n relation in SQL:

CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"authorId" integer NOT NULL,
FOREIGN KEY ("authorId") REFERENCES "User"(id)
);

由于 authorId 列(外键)上没有 UNIQUE 约束,因此你可以创建指向同一 User 记录的多个 Post 记录。这使得关系成为一对多而不是一对一。

¥Since there's no UNIQUE constraint on the authorId column (the foreign key), you can create multiple Post records that point to the same User record. This makes the relation a one-to-many rather than a one-to-one.

以下示例演示如何使用组合键(firstNamelastName)在 SQL 中创建 1-n 关系:

¥The following example demonstrates how to create a 1-n relation in SQL using a composite key (firstName and lastName):

CREATE TABLE "User" (
firstName TEXT,
lastName TEXT,
PRIMARY KEY ("firstName","lastName")
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"authorFirstName" TEXT NOT NULL,
"authorLastName" TEXT NOT NULL,
FOREIGN KEY ("authorFirstName", "authorLastName") REFERENCES "User"("firstName", "lastName")
);

比较一对一和一对多关系

¥Comparing one-to-one and one-to-many relations

在关系数据库中,1-1 和 1-n 关系之间的主要区别在于,在 1-1 关系中,外键必须定义有 UNIQUE 约束。

¥In relational databases, the main difference between a 1-1 and a 1-n-relation is that in a 1-1-relation the foreign key must have a UNIQUE constraint defined on it.

MongoDB

对于 MongoDB,Prisma ORM 目前使用 规范化数据模型设计,这意味着文档以与关系数据库类似的方式通过 ID 相互引用。

¥For MongoDB, Prisma ORM currently uses a normalized data model design, which means that documents reference each other by ID in a similar way to relational databases.

以下 MongoDB 文档代表 User

¥The following MongoDB document represents a User:

{ "_id": { "$oid": "60d5922d00581b8f0062e3a8" }, "name": "Ella" }

以下每个 Post MongoDB 文档都有一个引用同一用户的 authorId 字段:

¥Each of the following Post MongoDB documents has an authorId field which references the same user:

[
{
"_id": { "$oid": "60d5922e00581b8f0062e3a9" },
"title": "How to make sushi",
"authorId": { "$oid": "60d5922d00581b8f0062e3a8" }
},
{
"_id": { "$oid": "60d5922e00581b8f0062e3aa" },
"title": "How to re-install Windows",
"authorId": { "$oid": "60d5922d00581b8f0062e3a8" }
}
]

比较一对一和一对多关系

¥Comparing one-to-one and one-to-many relations

在 MongoDB 中,1-1 和 1-n 之间的唯一区别是引用数据库中另一个文档的文档数量 - 没有任何限制。

¥In MongoDB, the only difference between a 1-1 and a 1-n is the number of documents referencing another document in the database - there are no constraints.

一对多关系中的必填和可选关系字段

¥Required and optional relation fields in one-to-many relations

1-n-关系始终有两个关系字段:

¥A 1-n-relation always has two relation fields:

1-n 关系的带注释的关系字段和关系标量可以都是可选的,也可以都是强制的。另一方面,该列表始终是强制性的。

¥The annotated relation field and relation scalar of a 1-n relation can either both be optional, or both be mandatory. On the other side of the relation, the list is always mandatory.

可选的一对多关系

¥Optional one-to-many relation

在以下示例中,你可以创建 Post 而不分配 User

¥In the following example, you can create a Post without assigning a User:

model User {
id Int @id @default(autoincrement())
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}

强制一对多关系

¥Mandatory one-to-many relation

在以下示例中,你在创建 Post 时必须分配 User

¥In the following example, you must assign a User when you create a Post:

model User {
id Int @id @default(autoincrement())
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int
}