Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. SQL Dictionary
  3. Constraints (NOT NULL / UNIQUE / DEFAULT)

Constraints (NOT NULL / UNIQUE / DEFAULT)

Since: SQL-92(1992)

A constraint is a rule applied to a column. Constraints prevent invalid data from being inserted and maintain the integrity of your data.

Syntax

Prohibits NULL values.

column_name data_type NOT NULL

Prohibits duplicate values in the column.

column_name data_type UNIQUE

Sets the default value used when a value is omitted.

column_name data_type DEFAULT default_value

Restricts the values that can be inserted (MySQL 8.0.16 and later).

column_name data_type CHECK (condition)

Named constraint (table-level).

CONSTRAINT constraint_name CHECK (condition)

Constraint List

ConstraintDescription
NOT NULLProhibits NULL values. Use this for columns that require a value.
UNIQUEProhibits duplicate values within the column. Use this for columns that must be unique, such as email addresses or employee IDs.
DEFAULT valueSpecifies the value automatically assigned when a value is omitted during INSERT.
CHECK (condition)Restricts insertable values using a condition expression (MySQL 8.0.16 and later, PostgreSQL).
CONSTRAINT nameAssigns a name to a constraint. The name appears in error messages, making it easier to identify the cause.

Sample Code

The following examples create an employees table like the one shown below.

employees employee_id name email department (empty set) Empty set

Creates a table with various constraints applied.

Note: The chk_age CHECK constraint skips validation when age is NULL, and only checks that the value is between 18 and 100 when a value is provided.

sample_constraints.sql
CREATE TABLE employees (
    employee_id INT           NOT NULL AUTO_INCREMENT,
    name        VARCHAR(100)  NOT NULL,
    email       VARCHAR(255)  NOT NULL UNIQUE,
    department  VARCHAR(50)   NOT NULL DEFAULT 'Unassigned',
    salary      INT           NOT NULL DEFAULT 0,
    age         INT,
    PRIMARY KEY (employee_id),
    CONSTRAINT chk_salary CHECK (salary >= 0),
    CONSTRAINT chk_age    CHECK (age IS NULL OR age BETWEEN 18 AND 100)
);
Query OK, 0 rows affected

Verifies the table structure. The constraints and default values set on each column are reflected.

sample_constraints.sql
DESCRIBE employees;
+-------------+--------------+------+-----+------------+----------------+
| Field       | Type         | Null | Key | Default    | Extra          |
+-------------+--------------+------+-----+------------+----------------+
| employee_id | int          | NO   | PRI | NULL       | auto_increment |
| name        | varchar(100) | NO   |     | NULL       |                |
| email       | varchar(255) | NO   | UNI | NULL       |                |
| department  | varchar(50)  | NO   |     | Unassigned |                |
| salary      | int          | NO   |     |          0 |                |
| age         | int          | YES  |     | NULL       |                |
+-------------+--------------+------+-----+------------+----------------+
6 rows in set

Applies a UNIQUE constraint across multiple columns (composite unique).

sample_constraints.sql
CREATE TABLE schedule (
    room_id  INT  NOT NULL,
    date     DATE NOT NULL,
    slot     INT  NOT NULL,
    UNIQUE (room_id, date, slot)
);
Query OK, 0 rows affected

Inserts data that satisfies all constraints.

sample_constraints.sql
INSERT INTO employees (name, email, department, salary, age)
VALUES ('user_a', 'rintaro@wp-p.info', 'org_a', 250000, 24);
Query OK, 1 row affected (0.01 sec)
sample_constraints.sql
SELECT * FROM employees;
+-------------+--------+-------------------+------------+--------+-----+
| employee_id | name   | email             | department | salary | age |
+-------------+--------+-------------------+------------+--------+-----+
|           1 | user_a | rintaro@wp-p.info | org_a      | 250000 |  24 |
+-------------+--------+-------------------+------------+--------+-----+
1 row in set

Output

Error when an INSERT violates a UNIQUE constraint (MySQL).

-- ERROR 1062 (23000): Duplicate entry 'rintaro@wp-p.info' for key 'employees.email'

Error when an INSERT violates a CHECK constraint (MySQL 8.0.16 and later).

-- ERROR 3819 (HY000): Check constraint 'chk_salary' is violated.

Syntax by Database

NOT NULL, UNIQUE, and DEFAULT are supported across all major databases.

CREATE TABLE employees (
    employee_id INT          NOT NULL,
    name        VARCHAR(100) NOT NULL,
    email       VARCHAR(255) NOT NULL UNIQUE,
    department  VARCHAR(50)  NOT NULL DEFAULT 'Unassigned',
    salary      INT          NOT NULL DEFAULT 0
);

The CHECK constraint has been supported in PostgreSQL and SQLite for a long time, but MySQL only added support in version 8.0.16. In earlier versions of MySQL, the syntax is accepted without error but the constraint is silently ignored.

-- MySQL 8.0.16 and later, PostgreSQL, SQLite (common syntax)
CREATE TABLE employees (
    salary INT NOT NULL,
    age    INT,
    CONSTRAINT chk_salary CHECK (salary >= 0),
    CONSTRAINT chk_age    CHECK (age IS NULL OR age BETWEEN 18 AND 100)
);

The CONSTRAINT name syntax for naming constraints is also common across databases, but the format of error messages varies by database.

Overview

Constraints are a mechanism for guaranteeing data accuracy at the database level. Using constraints together with application-side validation provides a double layer of protection, significantly reducing the risk of unexpected data entering the system.

Combining NOT NULL and DEFAULT lets you allow a value to be omitted while still prohibiting NULL. For example, score INT NOT NULL DEFAULT 0 automatically sets score to 0 when it is omitted.

For primary keys and foreign keys, see PRIMARY KEY / FOREIGN KEY. For the basics of creating tables, see CREATE TABLE.

If you find any errors or copyright issues, please .