# Working with compound IDs and unique constraints (/docs/orm/prisma-client/special-fields-and-types/working-with-composite-ids-and-constraints)

Location: ORM > Prisma Client > Special Fields and Types > Working with compound IDs and unique constraints

Composite IDs and compound unique constraints can be defined in your Prisma schema using the [`@@id`](/orm/reference/prisma-schema-reference) and [`@@unique`](/orm/reference/prisma-schema-reference) attributes.

> [!WARNING]
> **MongoDB does not support `@@id`**<br />
> 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]) // [!code highlight]
}
```

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]) // [!code highlight]
}
```

Where you can use compound IDs and unique constraints [#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 [#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]
> 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](/orm/prisma-client/special-fields-and-types/working-with-composite-ids-and-constraints#where-you-can-use-compound-ids-and-unique-constraints) above for a list of places these fields may be used.

Deleting records by a compound ID or unique constraint [#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 [#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 [#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,
          },
        },
      },
    },
  },
});
```

## Related pages

- [`Composite types`](https://www.prisma.io/docs/orm/prisma-client/special-fields-and-types/composite-types): Work with composite types and embedded documents in MongoDB
- [`Null and undefined`](https://www.prisma.io/docs/orm/prisma-client/special-fields-and-types/null-and-undefined): How Prisma Client handles null and undefined
- [`Working with geometry fields`](https://www.prisma.io/docs/orm/prisma-client/special-fields-and-types/working-with-geometry-fields): How to read, write, and filter by geometry fields in PostgreSQL
- [`Working with Json fields`](https://www.prisma.io/docs/orm/prisma-client/special-fields-and-types/working-with-json-fields): How to read, write, and filter by Json fields
- [`Working with scalar lists`](https://www.prisma.io/docs/orm/prisma-client/special-fields-and-types/working-with-scalar-lists-arrays): How to read, write, and filter by scalar lists / arrays