diff --git a/content/200-concepts/100-components/01-prisma-schema/04-data-model.mdx b/content/200-concepts/100-components/01-prisma-schema/04-data-model.mdx
index 1401d0a3dc..cf742d158c 100644
--- a/content/200-concepts/100-components/01-prisma-schema/04-data-model.mdx
+++ b/content/200-concepts/100-components/01-prisma-schema/04-data-model.mdx
@@ -637,6 +637,29 @@ model User {
}
```
+By default, the name of this field in Prisma Client queries will be `firstName_lastName`.
+
+You can also provide your own name for the composite ID using the [`@@id`](/reference/api-reference/prisma-schema-reference#id-1) attribute's `name` field:
+
+```prisma highlight=7;normal
+model User {
+ firstName String
+ lastName String
+ email String @unique
+ isAdmin Boolean @default(false)
+
+ @@id(name: "fullName", fields: [firstName, lastName])
+}
+```
+
+The `firstName_lastName` field will now be named `fullName` instead.
+
+
+
+Refer to the documentation on [working with composite IDs](/concepts/components/prisma-client/working-with-fields/working-with-composite-ids-and-constraints) to learn how to interact with a composite ID in Prisma Client.
+
+
+
##### @unique fields as unique identifiers
In the following example, users are uniquely identified by a `@unique` field. Because the `email` field functions as a unique identifier for the model (which is required by Prisma), it must be mandatory:
@@ -826,6 +849,32 @@ You can optionally define a [custom unique constraint name](/concepts/components
+By default, the name of this field in Prisma Client queries will be `authorId_title`.
+
+You can also provide your own name for the composite unique constraint using the [`@@unique`](/concepts/components/prisma-schema/names-in-underlying-database#constraint-and-index-names) attribute's `name` field:
+
+```prisma highlight=10;normal
+model Post {
+ id String @id @default(auto()) @map("_id") @db.ObjectId
+ createdAt DateTime @default(now())
+ title String
+ published Boolean @default(false)
+ author User @relation(fields: [authorId], references: [id])
+ authorId String @db.ObjectId
+ categories Category[] @relation(references: [id])
+
+ @@unique(name: "authorTitle", [authorId, title])
+}
+```
+
+The `authorId_title` field will now be named `authorTitle` instead.
+
+
+
+Refer to the documentation on [working with composite unique identifiers](/concepts/components/prisma-client/working-with-fields/working-with-composite-ids-and-constraints) to learn how to interact with a composite unique constraints in Prisma Client.
+
+
+
#### Composite type unique constraints
When using the MongoDB provider in version `3.12.0` and later, you can define a unique constraint on a field of a [composite type](#defining-composite-types) using the syntax `@@unique([compositeType.field])`. As with other fields, composite type fields can be used as part of a multi-column unique constraint.
diff --git a/content/200-concepts/100-components/02-prisma-client/030-crud.mdx b/content/200-concepts/100-components/02-prisma-client/030-crud.mdx
index 65737ec58a..736b90035d 100644
--- a/content/200-concepts/100-components/02-prisma-client/030-crud.mdx
+++ b/content/200-concepts/100-components/02-prisma-client/030-crud.mdx
@@ -325,99 +325,6 @@ const user = await prisma.user.findUnique({
})
```
-### Get record by compound ID or compound unique identifier
-
-
-
-**MongoDB does not support `@@id`**
-MongoDB does not support composite IDs, which means you cannot identify a model with a `@@id` attribute.
-
-
-
-The following examples demonstrate how to retrieve records by a compound ID or unique identifier, defined by [`@@id`](/reference/api-reference/prisma-schema-reference#id-1) or [`@@unique`](/reference/api-reference/prisma-schema-reference#unique-1) .
-
-The following Prisma model defines a compound ID:
-
-]}>
-
-
-```prisma highlight=6;normal
-model TimePeriod {
- year Int
- quarter Int
- total Decimal
-
- @@id([year, quarter])
-}
-```
-
-
-
-
-
-
-To retrieve a time period by this compound ID, use the generated `year_quarter` field, which follows the `fieldName1_fieldName2` pattern:
-
-]}>
-
-
-```ts
-const timePeriod = await prisma.timePeriod.findUnique({
- where: {
- year_quarter: {
- quarter: 4,
- year: 2020,
- },
- },
-})
-```
-
-
-
-
-
-
-The following Prisma model defines a compound unique identifier with a custom name (`timePeriodId`)
-
-]}>
-
-
-```prisma highlight=6;normal
-model TimePeriod {
- year Int
- quarter Int
- total Decimal
-
- @@unique(fields: [year, quarter], name: "timePeriodId")
-}
-```
-
-
-
-
-
-
-To retrieve a time period by this unique identifier, use the custom `timePeriodId` field:
-
-]}>
-
-
-```ts
-const timePeriod = await prisma.timePeriod.findUnique({
- where: {
- timePeriodId: {
- quarter: 4,
- year: 2020,
- },
- },
-})
-```
-
-
-
-
-
-
### Get all records
The following [`findMany`](/reference/api-reference/prisma-client-reference#findmany) query returns _all_ `User` records:
diff --git a/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/300-working-with-composite-ids-and-constraints.mdx b/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/300-working-with-composite-ids-and-constraints.mdx
new file mode 100644
index 0000000000..3d2f160012
--- /dev/null
+++ b/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/300-working-with-composite-ids-and-constraints.mdx
@@ -0,0 +1,206 @@
+---
+title: 'Working with compound IDs and unique constraints'
+metaTitle: 'Working with compound IDs and unique constraints (Concepts)'
+metaDescription: 'How to read, write, and filter by compound IDs and unique constraints.'
+tocDepth: 2
+---
+
+
+
+Composite IDs and compound unique constraints can be defined in your Prisma schema using the [`@@id`](/reference/api-reference/prisma-schema-reference#id-1) and [`@@unique`](/reference/api-reference/prisma-schema-reference#unique-1) attributes.
+
+
+
+**MongoDB does not support `@@id`**
+MongoDB does not support composite IDs, which means you cannot identify a model with a `@@id` attribute.
+
+
+
+A composite ID or compound unique constraint uses the combined values of two fields as a primary key or identifier in your database table. In the following example, the `postId` field and `userId` field are used as a composite ID for a `Like` table:
+
+```prisma highlight=22;normal
+model User {
+ id Int @id @default(autoincrement())
+ name String
+ post Post[]
+ likes Like[]
+}
+
+model Post {
+ id Int @id @default(autoincrement())
+ content String
+ User User? @relation(fields: [userId], references: [id])
+ userId Int?
+ likes Like[]
+}
+
+model Like {
+ postId Int
+ userId Int
+ User User @relation(fields: [userId], references: [id])
+ Post Post @relation(fields: [postId], references: [id])
+
+ @@id([postId, userId])
+}
+```
+
+Querying for records from the `Like` table (e.g. using `prisma.like.findMany()`) would return objects that look as follows:
+
+```json
+{
+ "postId": 1,
+ "userId": 1
+}
+```
+
+Although there are only two fields in the response, those two fields make up a compound ID named `postId_userId`.
+
+You can also create a named compound ID or compound unique constraint by using the `@@id` or `@@unique` attributes' `name` field. For example:
+
+```prisma highlight=7;normal
+model Like {
+ postId Int
+ userId Int
+ User User @relation(fields: [userId], references: [id])
+ Post Post @relation(fields: [postId], references: [id])
+
+ @@id(name: "likeId", [postId, userId])
+}
+```
+
+
+
+## Where you can use compound IDs and unique constraints
+
+Compound IDs and compound unique constraints can be used when working with _unique_ data.
+
+Below is a list of Prisma Client functions that accept a compound ID or compound unique constraint in the `where` filter of the query:
+
+- `findUnique`
+- `findUniqueOrThrow`
+- `delete`
+- `update`
+- `upsert`
+
+A composite ID and a composite unique constraint is also usable when creating relational data with `connect` and `connectOrCreate`.
+
+## Filtering records by a compound ID or unique constraint
+
+Although your query results will not display a compound ID or unique constraint as a field, you can use these compound values to filter your queries for unique records:
+
+```ts highlight=3-6;normal
+const like = await prisma.like.findUnique({
+ where: {
+ likeId: {
+ userId: 1,
+ postId: 1,
+ },
+ },
+})
+```
+
+
+
+Note composite ID and compound unique constraint keys are only available as filter options for _unique_ queries such as `findUnique` and `findUniqueOrThrow`. See the [section](/concepts/components/prisma-client/working-with-fields/working-with-composite-ids/#where-you-can-use-compound-ids-and-unique-identifiers) above for a list of places these fields may be used.
+
+
+
+## Deleting records by a compound ID or unique constraint
+
+A compound ID or compound unique constraint may be used in the `where` filter of a `delete` query:
+
+```ts highlight=3-6;normal
+const like = await prisma.like.delete({
+ where: {
+ likeId: {
+ userId: 1,
+ postId: 1,
+ },
+ },
+})
+```
+
+## Updating and upserting records by a compound ID or unique constraint
+
+A compound ID or compound unique constraint may be used in the `where` filter of an `update` query:
+
+```ts highlight=3-6;normal
+const like = await prisma.like.update({
+ where: {
+ likeId: {
+ userId: 1,
+ postId: 1,
+ },
+ },
+ data: {
+ postId: 2,
+ },
+})
+```
+
+They may also be used in the `where` filter of an `upsert` query:
+
+```ts highlight=3-6;normal
+await prisma.like.upsert({
+ where: {
+ likeId: {
+ userId: 1,
+ postId: 1,
+ },
+ },
+ update: {
+ userId: 2,
+ },
+ create: {
+ userId: 2,
+ postId: 1,
+ },
+})
+```
+
+## Filtering relation queries by a compound ID or unique constraint
+
+Compound IDs and compound unique constraint can also be used in the `connect` and `connectOrCreate` keys used when connecting records to create a relationship.
+
+For example, consider this query:
+
+```ts highlight=6-9;normal
+await prisma.user.create({
+ data: {
+ name: 'Alice',
+ likes: {
+ connect: {
+ likeId: {
+ postId: 1,
+ userId: 2,
+ },
+ },
+ },
+ },
+})
+```
+
+The `likeId` compound ID is used as the identifier in the `connect` object that is used to locate the `Like` table's record that will be linked to the new user: `"Alice"`.
+
+Similarly, the `likeId` can be used in `connectOrCreate`'s `where` filter to attempt to locate an existing record in the `Like` table:
+
+```ts highlight=10-13;normal
+await prisma.user.create({
+ data: {
+ name: 'Alice',
+ likes: {
+ connectOrCreate: {
+ create: {
+ postId: 1,
+ },
+ where: {
+ likeId: {
+ postId: 1,
+ userId: 1,
+ },
+ },
+ },
+ },
+ },
+})
+```
diff --git a/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/index.mdx b/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/index.mdx
index 767eb73ceb..725aa182bf 100644
--- a/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/index.mdx
+++ b/content/200-concepts/100-components/02-prisma-client/051-working-with-fields/index.mdx
@@ -83,3 +83,7 @@ See: [Working with `Json` fields](working-with-json-fields)
## Working with scalar lists / scalar arrays
See: [Working with scalar lists / arrays](working-with-scalar-lists-arrays)
+
+## Working with composite IDs and compound unique constraints
+
+See: [Working with composite IDs and compound unique constraints](working-with-composite-ids-and-constraints)