# Models

https://docs.serverpod.dev/3.3.0/concepts/database/models

It's possible to map serializable models to tables in your database. To do this, add the `table` key to your yaml file:

```yaml
class: Company
table: company
fields:
  name: String
```

When the `table` keyword is added to the model, the `serverpod generate` command will generate new methods for [interacting](https://docs.serverpod.dev/3.3.0/concepts/database/crud.md) with the database. The addition of the keyword will also be detected by the `serverpod create-migration` command that will generate the necessary [migrations](https://docs.serverpod.dev/3.3.0/concepts/database/migrations.md) needed to update the database.

:::info

When you add a `table` to a serializable class, Serverpod will automatically add an `id` field of type `int?` to the class. You should not define this field yourself. The `id` is set when you interact with an object stored in the database.

:::

### Non persistent fields

You can opt out of creating a column in the database for a specific field by using the `!persist` keyword.

```yaml
class: Company
table: company
fields:
  name: String, !persist 
```

All fields are persisted by default and have an implicit `persist` set on each field.

### Data representation

Storing a field with a primitive / core dart type will be handled as its respective type. However, if you use a complex type, such as another model, a `List`, or a `Map`, these will be stored as a `json` object in the database.

```yaml
class: Company
table: company
fields:
  address: Address # Stored as a json column
```

This means that each row has its own copy of the nested object that needs to be updated individually. If you instead want to reference the same object from multiple different tables, you can use the `relation` keyword.

This creates a database relation between two tables and always keeps the data in sync.

```yaml
class: Company
table: company
fields:
  address: Address?, relation
```

For a complete guide on how to work with relations see the [relation section](https://docs.serverpod.dev/3.3.0/concepts/database/relations/one-to-one.md).

## Change ID type

Changing the type of the `id` field allows you to customize the identifier type for your database tables. This is done by declaring the `id` field on table models with one of the supported types. If the field is omitted, the id field will still be created with type `int`, as have always been.

The following types are supported for the `id` field:

| **Type**      | Default | Default Persist options | Default Model options | Description            |
| :------------ | :------ | :---------------------- | :-------------------- | :--------------------- |
| **int**       | serial  | serial (optional)       | -                     | 64-bit serial integer. |
| **UuidValue** | random  | random                  | random                | UUID v4 value.         |

### Declaring a Custom ID Type

To declare a custom type for the `id` field in a table model file, use the following syntax:

```yaml
class: UuidIdTable
table: uuid_id_table
fields:
  id: UuidValue?, defaultPersist=random
```

```yaml
class: IntIdTable
table: int_id_table
fields:
  id: int?, defaultPersist=serial  // The default keyword for 'int' is optional.
```

#### Default Uuid model value

For UUIDs, it is possible to configure the `defaultModel` value. This will ensure that UUIDs are generated as soon as the object is created, rather than when it is persisted to the database. This is useful for creating objects offline or using them before they are sent to the server.

```yaml
class: UuidIdTable
table: uuid_id_table
fields:
  id: UuidValue, defaultModel=random
```

When using `defaultModel=random`, the UUID will be generated when the object is created. Since an id is always assigned the `id` field can be non-nullable.
