# Lesson 5.3: Defining data constraints

## [](#_cardinality)Cardinality

The most important type of data constraint is configuring **cardinality**. Cardinality indicates how many times a connection is allowed between instances of a type.

For example:

```typeql
define
entity book,
  owns title @card(1),
  owns genre @card(0..);
```

_→ Commit_

Indicates that every book instance must have exactly 1 title, and 0 or more genres. You can configure any cardinality range you like, such as `@card(10..20)`, which allows between 10 and 20 (inclusive of both) connections.

Cardinalities can be set on `plays` and `relates` as well:

```typeql
define
entity book,
  plays publishing:published @card(1);

relation publishing,
  relates publisher @card(0..),
  relates published @card(1),
  relates publication @card(0..);
```

_→ Don’t commit, we don’t want to keep these_

This configures that every book has must be in 1 publishing relationship, and every publishing relationship connect to exactly 1 published role player, and 0 or more of either publisher or publication.

By default the following cardinalities are set:

*   `owns` has `@card(0..1)` - there are 0 or 1 ownerships from an owner to the attribute type
    
*   `relates` has `@card(0..1)` - there are 0 or 1 players of a role in a relation type
    
*   `plays` has `@card(0..)` - any number of relations may be participated in
    

## [](#_constraining_values)Constraining values

### [](#_strings)Strings

The values of string attribute types can be constrained with the `@values` or the `@regex` annotation, which specifies a [Rust regex pattern](https://docs.rs/regex/latest/regex/) validated when instantiating the attribute or on ownership.

```typeql
define
attribute status, value string @values("paid", "dispatched", "delivered", "returned", "canceled");
attribute isbn-10, value string @regex(".{10}");

entity book, owns isbn-10;
entity order, owns status;
```

_→ Commit_

### [](#_numerical_values)Numerical values

For numerical value types, you can provide allowed value ranges. You can use also `@values` to also restrict numerical value types to a specific set:

```typeql
define
attribute page-count, value integer @range(0..);
attribute discount, value double @values(0.1, 0.2, 0.3);
```

_→ Commit_

## [](#_attribute_ownership_constraints_and_uniqueness)Attribute ownership constraints and uniqueness

Value constraint annotations also by applied only to `owns` declarations.

Additionally, TypeQL has syntax for defining key and unique constraints on attribute ownerships via annotations, to enforce uniqueness.

```typeql
define
attribute id, value string;
entity book,
  owns isbn-13 @key,
  owns isbn-10 @unique;
entity user, owns id @key;
entity order, owns id @key;
entity review, owns id @key;
```

_→ Commit_

When applied to an ownership statement in a Define query, the `@key` and `@unique` annotations apply a key or unique constraint respectively to that ownership.

A **key constraint annotation** requires that instances of the owner type own exactly one instance of the attribute type, and that it must be uniquely owned by the owner type. In the example above, every instance of `book` must own exactly one instance of `isbn-13`, and no two instances of `book` can own the same instance of `isbn-13`.

A **unique constraint annotation** requires only that instances of the attribute type are uniquely owned by the owner type. In the example above, no two instances of `book` can own the same instance of `isbn-10`, but an instance of `book` can own any number of instances of `isbn-10` (including none).

Ownership annotations apply to the _specific ownerships_ they are defined on rather than to the attribute in general. In the example above, key constraints are applied to the ownership of `id` by `user`, `order`, and `review`. This means that, while two instances of `user` (or two of `order`, or two of `review`) could not own the same instance of `id`, it is perfectly permissible for an instance of `user` and an instance of `order` to own the same instance of `id`.

[Defining type hierarchies](../5.2-defining-type-hierarchies/index.md) [Defining functions](../5.4-defining-functions/index.md)

[Edit on GitHub](https://github.com/typedb/typedb-docs/edit/3.x-development/academy/modules/ROOT/pages/5-defining-schemas/5.3-defining-constraints.adoc) Edit this page on GitHub.