# Models (Prisma ORM v7) (/docs/orm/v7/prisma-schema/data-model/models)

Learn about the concepts for building your data model with Prisma: Models, scalar types, enums, attributes, functions, IDs, default values and more

Location: ORM > v7 > Prisma Schema > Data Model > Models

The data model definition part of the [Prisma schema](/guides/prisma-schema-v7-overview) defines your application models (also called **Prisma models**). Models:

- Represent the **entities** of your application domain
- Map to the **tables** (relational databases like PostgreSQL) or **collections** (MongoDB) in your database
- Form the foundation of the **queries** available in the generated [Prisma Client API](/guides/prisma-client-v7-setup-and-configuration-introduction)
- When used with TypeScript, Prisma Client provides generated **type definitions** for your models and any [variations](/guides/prisma-client-v7-type-safety-operating-against-partial-structures-of-model-types) of them to make database access entirely type safe.

The following schema describes a blogging platform - the data model definition is highlighted:

#### Relational databases

```prisma highlight=10-46;normal 
datasource db {
  provider = "postgresql"
}

generator client {
  provider = "prisma-client"
  output   = "./generated"
}

model User { // [!code highlight]
  id      Int      @id @default(autoincrement()) // [!code highlight]
  email   String   @unique // [!code highlight]
  name    String? // [!code highlight]
  role    Role     @default(USER) // [!code highlight]
  posts   Post[] // [!code highlight]
  profile Profile? // [!code highlight]
} // [!code highlight]

model Profile { // [!code highlight]
  id     Int    @id @default(autoincrement()) // [!code highlight]
  bio    String // [!code highlight]
  user   User   @relation(fields: [userId], references: [id]) // [!code highlight]
  userId Int    @unique // [!code highlight]
} // [!code highlight]

model Post { // [!code highlight]
  id         Int        @id @default(autoincrement()) // [!code highlight]
  createdAt  DateTime   @default(now()) // [!code highlight]
  updatedAt  DateTime   @updatedAt // [!code highlight]
  title      String // [!code highlight]
  published  Boolean    @default(false) // [!code highlight]
  author     User       @relation(fields: [authorId], references: [id]) // [!code highlight]
  authorId   Int // [!code highlight]
  categories Category[] // [!code highlight]
} // [!code highlight]

model Category { // [!code highlight]
  id    Int    @id @default(autoincrement()) // [!code highlight]
  name  String // [!code highlight]
  posts Post[] // [!code highlight]
} // [!code highlight]

enum Role { // [!code highlight]
  USER // [!code highlight]
  ADMIN // [!code highlight]
} // [!code highlight]
```

#### MongoDB

```prisma highlight=10-45;normal 
datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User { // [!code highlight]
  id      String   @id @default(auto()) @map("_id") @db.ObjectId // [!code highlight]
  email   String   @unique // [!code highlight]
  name    String? // [!code highlight]
  role    Role     @default(USER) // [!code highlight]
  posts   Post[] // [!code highlight]
  profile Profile? // [!code highlight]
} // [!code highlight]

model Profile { // [!code highlight]
  id     String @id @default(auto()) @map("_id") @db.ObjectId // [!code highlight]
  bio    String // [!code highlight]
  user   User   @relation(fields: [userId], references: [id]) // [!code highlight]
  userId String @unique @db.ObjectId // [!code highlight]
} // [!code highlight]

model Post { // [!code highlight]
  id          String     @id @default(auto()) @map("_id") @db.ObjectId // [!code highlight]
  createdAt   DateTime   @default(now()) // [!code highlight]
  title       String // [!code highlight]
  published   Boolean    @default(false) // [!code highlight]
  author      User       @relation(fields: [authorId], references: [id]) // [!code highlight]
  authorId    String     @db.ObjectId // [!code highlight]
  categoryIDs String[]   @db.ObjectId // [!code highlight]
  categories  Category[] @relation(fields: [categoryIDs], references: [id]) // [!code highlight]
} // [!code highlight]

model Category { // [!code highlight]
  id      String   @id @default(auto()) @map("_id") @db.ObjectId // [!code highlight]
  name    String // [!code highlight]
  postIDs String[] @db.ObjectId // [!code highlight]
  posts   Post[]   @relation(fields: [postIDs], references: [id]) // [!code highlight]
} // [!code highlight]

enum Role { // [!code highlight]
  USER // [!code highlight]
  ADMIN
}
```

The data model definition is made up of:

- [Models](#defining-models) ([`model`](/guides/reference-6-v7-reference-prisma-schema-reference#model) primitives) that define a number of fields, including [relations between models](#relation-fields)
- [Enums](#defining-enums) ([`enum`](/guides/reference-6-v7-reference-prisma-schema-reference#enum) primitives) (if your connector supports Enums)
- [Attributes](#defining-attributes) and [functions](#using-functions) that change the behavior of fields and models

The corresponding database looks like this:

<img src="https://www.prisma.io/img/orm/sample-database.png" alt="Sample database">

**A model maps to the underlying structures of the data source.**

- In relational databases like PostgreSQL and MySQL, a `model` maps to a **table**
- In MongoDB, a `model` maps to a **collection**

> **Note**: In the future there might be connectors for non-relational databases and other data sources. For example, for a REST API it would map to a _resource_.

The following query creates a `User` with nested `Post` and `Category` records:

```ts
const user = await prisma.user.create({
  data: {
    email: "ariadne@prisma.io",
    name: "Ariadne",
    posts: {
      create: [
        {
          title: "My first day at Prisma",
          categories: { create: { name: "Office" } },
        },
        {
          title: "How to connect to a SQLite database",
          categories: { create: [{ name: "Databases" }, { name: "Tutorials" }] },
        },
      ],
    },
  },
});
```

Your data model reflects _your_ application domain. For example:

- In an **ecommerce** application you probably have models like `Customer`, `Order`, `Item` and `Invoice`.
- In a **social media** application you probably have models like `User`, `Post`, `Photo` and `Message`.

## Introspection and migration

There are two ways to define a data model:

- **Write the data model manually and use Prisma Migrate**: You can write your data model manually and map it to your database using [Prisma Migrate](/guides/prisma-migrate-v7-prisma-migrate). In this case, the data model is the single source of truth for the models of your application.
- **Generate the data model via introspection**: When you have an existing database or prefer migrating your database schema with SQL, you generate the data model by [introspecting](/guides/prisma-schema-v7-introspection) your database. In this case, the database schema is the single source of truth for the models of your application.

## Defining models

Models represent the entities of your application domain. Models are represented by [`model`](/guides/reference-6-v7-reference-prisma-schema-reference#model) blocks and define a number of [fields](/guides/reference-6-v7-reference-prisma-schema-reference#model-fields). In the example data model above, `User`, `Profile`, `Post` and `Category` are models.

A blogging platform can be extended with the following models:

```prisma
model Comment {
  // Fields
}

model Tag {
  // Fields
}
```

### Mapping model names to tables or collections

Prisma model [naming conventions (singular form, PascalCase)](/guides/reference-6-v7-reference-prisma-schema-reference#naming-conventions) do not always match table names in the database. A common approach for naming tables/collections in databases is to use plural form and [snake\_case](https://en.wikipedia.org/wiki/Snake_case) notation - for example: `comments`. When you introspect a database with a table named `comments`, the resulting Prisma model will look like this:

```prisma
model comments {
  // Fields
}
```

However, you can still adhere to the naming convention without renaming the underlying `comments` table in the database by using the [`@@map`](/guides/reference-6-v7-reference-prisma-schema-reference) attribute:

```prisma
model Comment {
  // Fields

  @@map("comments")
}
```

With this model definition, Prisma ORM automatically maps the `Comment` model to the `comments` table in the underlying database.

> **Note**: You can also [`@map`](/guides/reference-6-v7-reference-prisma-schema-reference#map) a column name or enum value, and `@@map` an enum name.

`@map` and `@@map` allow you to [tune the shape of your Prisma Client API](/guides/prisma-client-v7-setup-and-configuration-custom-model-and-field-names#using-map-and-map-to-rename-fields-and-models-in-the-prisma-client-api) by decoupling model and field names from table and column names in the underlying database.

## Defining fields

The properties of a model are called _fields_, which consist of:

- A \*\*[field name](/guides/reference-6-v7-reference-prisma-schema-reference#model-fields)\*\*
- A \*\*[field type](/guides/reference-6-v7-reference-prisma-schema-reference#model-fields)\*\*
- Optional \*\*[type modifiers](#type-modifiers)\*\*
- Optional \*\*[attributes](#defining-attributes)\*\*, including [native database type attributes](#native-types-mapping)

A field's type determines its _structure_, and fits into one of two categories:

- [Scalar types](#scalar-fields) (includes [enums](#defining-enums)) that map to columns (relational databases) or document fields (MongoDB) - for example, [`String`](/guides/reference-6-v7-reference-prisma-schema-reference#string) or [`Int`](/guides/reference-6-v7-reference-prisma-schema-reference#int)
- Model types (the field is then called [relation field](/guides/prisma-schema-v7-data-model-relations#relation-fields)) - for example `Post` or `Comment[]`

### Scalar fields

The following example extends the `Comment` and `Tag` models with several scalar types. Some fields include [attributes](#defining-attributes):

#### Relational databases

```prisma highlight=2-4,8;normal 
model Comment {
  id      Int    @id @default(autoincrement()) // [!code highlight]
  title   String // [!code highlight]
  content String // [!code highlight]
}

model Tag {
  name String @id // [!code highlight]
}
```

#### MongoDB

```prisma highlight=2-4,8;normal 
model Comment {
  id      String @id @default(auto()) @map("_id") @db.ObjectId // [!code highlight]
  title   String // [!code highlight]
  content String // [!code highlight]
}

model Tag {
  name String @id @map("_id") // [!code highlight]
}
```

See [complete list of scalar field types](/guides/reference-6-v7-reference-prisma-schema-reference#model-field-scalar-types) .

### Relation fields

A relation field's type is another model - for example, a post (`Post`) can have multiple comments (`Comment[]`):

#### Relational databases

```prisma highlight=4,10;normal 
model Post {
  id       Int       @id @default(autoincrement())
  // Other fields
  comments Comment[] // A post can have many comments // [!code highlight]
}

model Comment {
  id     Int
  // Other fields
  post   Post @relation(fields: [postId], references: [id]) // A comment can have one post // [!code highlight]
  postId Int
}
```

#### MongoDB

```prisma highlight=4,10;normal 
model Post {
  id       String    @id @default(auto()) @map("_id") @db.Objectid
  // Other fields
  comments Comment[] // A post can have many comments // [!code highlight]
}

model Comment {
  id     String @id @default(auto()) @map("_id") @db.Objectid
  // Other fields
  post   Post   @relation(fields: [postId], references: [id]) // A comment can have one post // [!code highlight]
  postId String @db.ObjectId
}
```

Refer to the [relations documentation](/guides/prisma-schema-v7-data-model-relations) for more examples and information about relationships between models.

### Native types mapping

**Native database type attributes** describe the underlying database type:

```prisma
model Post {
  id      Int    @id
  title   String @db.VarChar(200)
  content String
}
```

Type attributes are:

- Specific to the underlying provider (e.g., PostgreSQL uses `@db.Boolean`, MySQL uses `@db.TinyInt(1)`)
- Written in PascalCase and prefixed by `@db`
- Only added during [introspection](/guides/prisma-schema-v7-introspection) if the native type differs from the default

See [native database type attributes](/guides/reference-6-v7-reference-prisma-schema-reference#model-field-scalar-types) for the complete list.

### Type modifiers

The type of a field can be modified by appending either of two modifiers:

- [`[]`](/guides/reference-6-v7-reference-prisma-schema-reference#-modifier) Make a field a list
- [`?`](/guides/reference-6-v7-reference-prisma-schema-reference#-modifier-1) Make a field optional

> **Note**: You **cannot** combine type modifiers - optional lists are not supported.

#### Lists

The following example includes a scalar list and a list of related models:

```prisma
model Post {
  id       Int       @id @default(autoincrement())
  comments Comment[] // A list of comments
  keywords String[]  // A scalar list
}
```

> \[!NOTE]
> Scalar lists are only supported if the database connector supports them natively or at a Prisma ORM level.

#### Optional and mandatory fields

```prisma
model Comment {
  id      Int     @id @default(autoincrement())
  title   String       // Required field
  content String?      // Optional field (nullable)
}
```

Fields without `?` are required:

- **Relational databases**: Represented via `NOT NULL` constraints
- **Prisma Client**: TypeScript types enforce these fields at compile time

### Unsupported types

When you introspect a relational database, unsupported data types are added as [`Unsupported`](/guides/reference-6-v7-reference-prisma-schema-reference#unsupported):

```prisma
location    Unsupported("POLYGON")?
```

Fields of type `Unsupported` don't appear in the generated Prisma Client API, but you can still use [raw database access](/guides/prisma-client-v7-using-raw-sql-raw-queries) to query them.

> \[!NOTE]
> The MongoDB connector doesn't support `Unsupported` types because it supports all scalar types.

## Defining attributes

Attributes modify the behavior of fields or model blocks. The following example includes three field attributes ([`@id`](/guides/reference-6-v7-reference-prisma-schema-reference#id) , [`@default`](/guides/reference-6-v7-reference-prisma-schema-reference#default) , and [`@unique`](/guides/reference-6-v7-reference-prisma-schema-reference#unique) ) and one block attribute ([`@@unique`](/guides/reference-6-v7-reference-prisma-schema-reference)):

#### Relational databases

```prisma
model User {
  id        Int     @id @default(autoincrement())
  firstName String
  lastName  String
  email     String  @unique
  isAdmin   Boolean @default(false)

  @@unique([firstName, lastName])
}
```

#### MongoDB

```prisma
model User {
  id        String  @id @default(auto()) @map("_id") @db.ObjectId
  firstName String
  lastName  String
  email     String  @unique
  isAdmin   Boolean @default(false)

  @@unique([firstName, lastName])
}
```

Some attributes accept [arguments](/guides/reference-6-v7-reference-prisma-schema-reference#attribute-argument-types) - for example, `@default` accepts `true` or `false`:

```prisma
isAdmin   Boolean @default(false) // short form of @default(value: false)
```

See [complete list of field and block attributes](/guides/reference-6-v7-reference-prisma-schema-reference#attributes)

### Defining an ID field

An ID uniquely identifies individual records of a model. A model can only have _one_ ID:

- In **relational databases**, the ID can be a single field or based on multiple fields. If a model does not have an `@id` or an `@@id`, you must define a mandatory `@unique` field or `@@unique` block instead.
- In **MongoDB**, an ID must be a single field that defines an `@id` attribute and a `@map("_id")` attribute.

#### Defining IDs in relational databases

In relational databases, an ID can be defined by a single field using the [`@id`](/guides/reference-6-v7-reference-prisma-schema-reference#id) attribute, or multiple fields using the [`@@id`](/guides/reference-6-v7-reference-prisma-schema-reference) attribute.

##### Single field IDs

In the following example, the `User` ID is represented by the `id` integer field:

```prisma highlight=2;normal
model User {
  id      Int      @id @default(autoincrement()) // [!code highlight]
  email   String   @unique
  name    String?
  role    Role     @default(USER)
  posts   Post[]
  profile Profile?
}
```

##### Composite IDs

In the following example, the `User` ID is represented by a combination of the `firstName` and `lastName` fields:

```prisma highlight=7;normal
model User {
  firstName String
  lastName  String
  email     String  @unique
  isAdmin   Boolean @default(false)

  @@id([firstName, lastName]) // [!code highlight]
}
```

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`](/guides/reference-6-v7-reference-prisma-schema-reference) 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]) // [!code highlight]
}
```

The `firstName_lastName` field will now be named `fullName` instead.

> \[!NOTE]
> Refer to the documentation on [working with composite IDs](/guides/prisma-client-v7-special-fields-and-types-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), it must be mandatory:

```prisma highlight=2;normal
model User {
  email   String   @unique // [!code highlight]
  name    String?
  role    Role     @default(USER)
  posts   Post[]
  profile Profile?
}
```

> \[!NOTE]
> **Constraint names in relational databases**

> You can optionally define a [custom primary key constraint name](/guides/prisma-schema-v7-data-model-database-mapping#constraint-and-index-names) in the underlying database.

#### Defining IDs in MongoDB

The MongoDB connector has [specific rules for defining an ID field](/guides/reference-6-v7-reference-prisma-schema-reference#mongodb-1) that differs from relational databases. An ID must be defined by a single field using the [`@id`](/guides/reference-6-v7-reference-prisma-schema-reference#id) attribute and must include `@map("_id")`.

In the following example, the `User` ID is represented by the `id` string field that accepts an auto-generated `ObjectId`:

```prisma highlight=2;normal
model User {
  id      String   @id @default(auto()) @map("_id") @db.ObjectId // [!code highlight]
  email   String   @unique
  name    String?
  role    Role     @default(USER)
  posts   Post[]
  profile Profile?
}
```

In the following example, the `User` ID is represented by the `id` string field that accepts something other than an `ObjectId` - for example, a unique username:

```prisma highlight=2;normal
model User {
  id      String   @id @map("_id") // [!code highlight]
  email   String   @unique
  name    String?
  role    Role     @default(USER)
  posts   Post[]
  profile Profile?
}
```

> \[!WARNING]
> **MongoDB does not support `@@id`**

> MongoDB does not support composite IDs, which means you cannot identify a model with a `@@id` block.

### Defining a default value

You can define default values for scalar fields using the [`@default`](/guides/reference-6-v7-reference-prisma-schema-reference#default) attribute:

```prisma
model Post {
  id         Int        @id @default(autoincrement())
  createdAt  DateTime   @default(now())
  title      String
  published  Boolean    @default(false)
  data       Json       @default("{ \"hello\": \"world\" }")
}
```

Default values can be:

- **Static values**: `5` (`Int`), `"Hello"` (`String`), `false` (`Boolean`)
- **Lists**: `[5, 6, 8]` (`Int[]`), `["Hello", "Goodbye"]` (`String[]`)
- **Functions**: [`now()`](/guides/reference-6-v7-reference-prisma-schema-reference#now), [`uuid()`](/guides/reference-6-v7-reference-prisma-schema-reference#uuid), [`cuid()`](/guides/reference-6-v7-reference-prisma-schema-reference#cuid)
- **JSON**: Use escaped strings, e.g., `@default("{ \"hello\": \"world\" }")`

See [attribute functions](/guides/reference-6-v7-reference-prisma-schema-reference#attribute-functions) for connector support details.

### Defining a unique field

Unique attributes can be defined on a single field using [`@unique`](/guides/reference-6-v7-reference-prisma-schema-reference#unique), or on multiple fields using [`@@unique`](/guides/reference-6-v7-reference-prisma-schema-reference):

```prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique      // Single field unique
  name  String?
}

model Post {
  id       Int    @id @default(autoincrement())
  title    String
  authorId Int

  @@unique([authorId, title]) // Composite unique
}
```

You can customize the constraint name with the `name` field: `@@unique(name: "authorTitle", [authorId, title])`

See [working with composite unique identifiers](/guides/prisma-client-v7-special-fields-and-types-working-with-composite-ids-and-constraints) for Prisma Client usage.

#### Composite type unique constraints (MongoDB)

For MongoDB composite types, you can define unique constraints on nested fields:

```prisma
type Address {
  street String
  number Int
}

model User {
  id      Int     @id
  email   String
  address Address

  @@unique([email, address.number])
}
```

### Defining an index

Define indexes via [`@@index`](/guides/reference-6-v7-reference-prisma-schema-reference#index):

```prisma
model Post {
  id      Int     @id @default(autoincrement())
  title   String
  content String?

  @@index([title, content])
}
```

For MongoDB composite types, use dot notation: `@@index([address.city.name])`

See [custom index names](/guides/prisma-schema-v7-data-model-database-mapping#constraint-and-index-names) for naming customization.

## Defining enums

Enums are defined via the [`enum`](/guides/reference-6-v7-reference-prisma-schema-reference#enum) block when [supported by your database](/guides/reference-6-v7-reference-database-features#misc):

```prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  role  Role    @default(USER)
}

enum Role {
  USER
  ADMIN
}
```

## Defining composite types (MongoDB)

> \[!WARNING]
> Composite types are only available on MongoDB.

Composite types (embedded documents) allow embedding records inside other records:

```prisma
model Product {
  id     String  @id @default(auto()) @map("_id") @db.ObjectId
  name   String
  photos Photo[]
}

type Photo {
  height Int
  width  Int
  url    String
}
```

**Supported attributes in composite types:** `@default`, `@map`, native types (`@db.ObjectId`)

**Not supported:** `@unique`, `@id`, `@relation`, `@ignore`, `@updatedAt`

## Using functions

The Prisma schema supports [functions](/guides/reference-6-v7-reference-prisma-schema-reference#attribute-functions) for default values:

```prisma
model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  uuid      String   @default(uuid())
}
```

Common functions: `now()`, `uuid()`, `cuid()`, `autoincrement()`, `auto()` (MongoDB ObjectId)

## Relations

See [relations documentation](/guides/prisma-schema-v7-data-model-relations) for relationship details.

## Models in Prisma Client

### Queries (CRUD)

Every model generates CRUD queries in the [Prisma Client API](/guides/prisma-client-v7-setup-and-configuration-introduction):

`findMany()` | `findFirst()` | `findUnique()` | `create()` | `update()` | `upsert()` | `delete()` | `createMany()` | `updateMany()` | `deleteMany()`

Access via the lowercase model name property: `prisma.user.create({ ... })`

### Type definitions

Prisma Client generates TypeScript types for your models:

```ts
export type User = {
  id: number;
  email: string;
  name: string | null;
};
```

These types ensure type-safe database queries.

## Limitations

Every Prisma model must have at least one unique identifier:

- `@id` or `@@id` for primary key
- `@unique` or `@@unique` for unique constraint

## Related pages

- [`Database mapping`](/guides/prisma-schema-v7-data-model-database-mapping): Learn how to map model and field names to database tables and columns
- [`External tables`](/guides/prisma-schema-v7-data-model-externally-managed-tables): How to declare and use externally managed tables in Prisma ORM
- [`Indexes`](/guides/prisma-schema-v7-data-model-indexes): How to configure index functionality and add full text indexes
- [`Multi-schema`](/guides/prisma-schema-v7-data-model-multi-schema): How to use Prisma ORM with multiple database schemas
- [`Relations`](/guides/prisma-schema-v7-data-model-relations): A relation is a connection between two models in the Prisma schema. This page explains how you can define one-to-one, one-to-many and many-to-many relations in Prisma

## Related pages

- [Authentication & Tools](./authentication-tools-index.md)
- [Build](./build-index.md)
- [Changelog](../changelog.md)
- [Concepts](./concepts-index.md)
- [Console commands](./console-commands-index.md)
- [Contract Authoring](./contract-authoring-index.md)
- [Core Concepts](./core-concepts-index.md)
- [Data Modeling](./data-modeling-index.md)
- [Database](./database-index.md)
- [DB commands](./db-commands-index.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
