> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Constraints

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

Constraints offer additional data integrity by enforcing conditions on the data within a column. Whenever values are manipulated (inserted, deleted, or updated), constraints are checked and modifications that violate constraints are rejected.

For example, the `UNIQUE` constraint requires that all values in a column be unique from one another (except `NULL` values). If you attempt to write a duplicate value, the constraint rejects the entire statement.

## Supported constraints

| Constraint                                                        | Description                                                                                                                                                                                                                                                          |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <InternalLink path="check">`CHECK`</InternalLink>                 | Values must return `TRUE` or `NULL` for a Boolean expression.                                                                                                                                                                                                        |
| <InternalLink path="default-value">`DEFAULT` value</InternalLink> | If a value is not defined for the constrained column in an `INSERT` statement, the `DEFAULT` value is written to the column.                                                                                                                                         |
| <InternalLink path="foreign-key">`FOREIGN KEY`</InternalLink>     | Values must exactly match existing values from the column it references.                                                                                                                                                                                             |
| <InternalLink path="not-null">`NOT NULL`</InternalLink>           | Values may not be `NULL`.                                                                                                                                                                                                                                            |
| <InternalLink path="primary-key">`PRIMARY KEY`</InternalLink>     | Values must uniquely identify each row *(one per table)*. This behaves as if the `NOT NULL` and `UNIQUE` constraints are applied, as well as automatically creates an <InternalLink path="indexes">index</InternalLink> for the table using the constrained columns. |
| <InternalLink path="unique">`UNIQUE`</InternalLink>               | Each non-`NULL` value must be unique. This also automatically creates an <InternalLink path="indexes">index</InternalLink> for the table using the constrained columns.                                                                                              |

## Using constraints

### Add constraints

How you add constraints depends on the number of columns you want to constrain, as well as whether or not the table is new.

* **One column of a new table** has its constraints defined after the column's data type. For example, this statement applies the `PRIMARY KEY` constraint to `foo.a`:

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  > CREATE TABLE foo (a INT PRIMARY KEY);
  ```
* **Multiple columns of a new table** have their constraints defined after the table's columns. For example, this statement applies the `PRIMARY KEY` constraint to `foo`'s columns `a` and `b`:

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  > CREATE TABLE bar (a INT, b INT, PRIMARY KEY (a,b));
  ```

<Note>
  The `DEFAULT` and `NOT NULL` constraints cannot be applied to multiple columns.
</Note>

* **Existing tables** can have the following constraints added:
  * `CHECK`, `FOREIGN KEY`, and `UNIQUE` constraints can be added through <InternalLink path="alter-table#add-constraint">`ALTER TABLE...ADD CONSTRAINT`</InternalLink>. For example, this statement adds the `UNIQUE` constraint to `baz.id`:

    ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
    > ALTER TABLE baz ADD CONSTRAINT id_unique UNIQUE (id);
    ```

  * `DEFAULT` values and `NOT NULL` constraints can be added through <InternalLink path="alter-table#set-or-change-a-default-value">`ALTER TABLE...ALTER COLUMN`</InternalLink>. For example, this statement adds the <InternalLink path="default-value">`DEFAULT` value constraint</InternalLink> to `baz.bool`:

    ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
    > ALTER TABLE baz ALTER COLUMN bool SET DEFAULT true;
    ```

  * <InternalLink path="primary-key">`PRIMARY KEY`</InternalLink> constraints can be added with <InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink>/<InternalLink path="alter-table">`ADD PRIMARY KEY`</InternalLink> in the following circumstances:

    * A <InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink> statement precedes the `ADD CONSTRAINT`/`ADD PRIMARY KEY` statement in the same transaction. For examples, see <InternalLink path="alter-table#add-constraints">Add constraints</InternalLink> and <InternalLink path="alter-table#drop-constraints">Drop constraints</InternalLink>.
    * The current <InternalLink path="indexes#creation">primary key is on `rowid`</InternalLink>, the default primary key created if none is explicitly defined at table creation.
    * The `ADD CONSTRAINT`/`ADD PRIMARY KEY` is in the same transaction as a `CREATE TABLE` statement with no primary key defined.

#### Order of constraints

The order in which you list constraints is not important because constraints are applied to every modification of their respective tables or columns.

#### Name constraints on new tables

You can name constraints applied to new tables using the `CONSTRAINT` clause before defining the constraint:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> CREATE TABLE foo (a INT CONSTRAINT another_name PRIMARY KEY);
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> CREATE TABLE bar (a INT, b INT, CONSTRAINT yet_another_name PRIMARY KEY (a,b));
```

### View constraints

To view a table's constraints, use <InternalLink path="show-constraints">`SHOW CONSTRAINTS`</InternalLink> or <InternalLink path="show-create">`SHOW CREATE`</InternalLink>.

### Remove constraints

The procedure for removing a constraint depends on its type:

| Constraint Type                                                   | Procedure                                                                                                                                                                                                                                                                                      |
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <InternalLink path="check">`CHECK`</InternalLink>                 | Use <InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>.                                                                                                                                                                                                         |
| <InternalLink path="default-value">`DEFAULT` value</InternalLink> | Use <InternalLink path="alter-table#remove-default-constraint">`ALTER COLUMN`</InternalLink>.                                                                                                                                                                                                  |
| <InternalLink path="foreign-key">`FOREIGN KEY`</InternalLink>     | Use <InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>.                                                                                                                                                                                                         |
| <InternalLink path="not-null">`NOT NULL`</InternalLink>           | Use <InternalLink path="alter-table#remove-not-null-constraint">`ALTER COLUMN`</InternalLink>.                                                                                                                                                                                                 |
| <InternalLink path="primary-key">`PRIMARY KEY`</InternalLink>     | Primary key constraints can be dropped with <InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink> if an <InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink> statement follows the `DROP CONSTRAINT` statement in the same transaction. |
| <InternalLink path="unique">`UNIQUE`</InternalLink>               | The `UNIQUE` constraint cannot be dropped directly.  To remove the constraint, <InternalLink path="drop-index">drop the index</InternalLink> that was created by the constraint, e.g., `DROP INDEX my_unique_constraint`.                                                                      |

### Change constraints

The procedure for changing a constraint depends on its type:

| Constraint Type                                                   | Procedure                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <InternalLink path="check">`CHECK`</InternalLink>                 | <InternalLink path="transactions#syntax">Issue a transaction</InternalLink> that adds a new `CHECK` constraint (<InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink>), and then remove the existing one (<InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>).                                                                                                                                                                                                                                                                                         |
| <InternalLink path="default-value">`DEFAULT` value</InternalLink> | The `DEFAULT` value can be changed through <InternalLink path="alter-table#alter-column">`ALTER COLUMN`</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| <InternalLink path="foreign-key">`FOREIGN KEY`</InternalLink>     | <InternalLink path="transactions#syntax">Issue a transaction</InternalLink> that adds a new `FOREIGN KEY` constraint (<InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink>), and then remove the existing one (<InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>).                                                                                                                                                                                                                                                                                   |
| <InternalLink path="not-null">`NOT NULL`</InternalLink>           | The `NOT NULL` constraint cannot be changed, only added and removed with <InternalLink path="alter-table#alter-column">`ALTER COLUMN`</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| <InternalLink path="primary-key">`PRIMARY KEY`</InternalLink>     | To change a primary key, use an <InternalLink path="alter-table#alter-primary-key">`ALTER TABLE ... ALTER PRIMARY KEY`</InternalLink> statement.<br /><br />When you change a primary key with <InternalLink path="alter-table#alter-primary-key">`ALTER PRIMARY KEY`</InternalLink>, the old primary key index becomes a secondary index. If you do not want the old primary key to become a secondary index, use <InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>/<InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink> to change the primary key. |
| <InternalLink path="unique">`UNIQUE`</InternalLink>               | <InternalLink path="transactions#syntax">Issue a transaction</InternalLink> that adds a new `UNIQUE` constraint (<InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink>), and then remove the existing one (<InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>).                                                                                                                                                                                                                                                                                        |

## See also

* <InternalLink path="create-table">`CREATE TABLE`</InternalLink>
* <InternalLink path="alter-table#add-constraint">`ADD CONSTRAINT`</InternalLink>
* <InternalLink path="alter-table#drop-constraint">`DROP CONSTRAINT`</InternalLink>
* <InternalLink path="show-constraints">`SHOW CONSTRAINTS`</InternalLink>
* <InternalLink path="show-create">`SHOW CREATE`</InternalLink>
* <InternalLink path="alter-table#alter-primary-key">`ALTER PRIMARY KEY`</InternalLink>
* <InternalLink path="alter-table">`ALTER TABLE`</InternalLink>
* <InternalLink path="alter-table#alter-column">`ALTER COLUMN`</InternalLink>
