
# 约束（Constraint）
SQL约束用于规定表中的数据规则。如果一个用户试图在表中插入违反约束的数据，会抛出错误。约束分为以下几类：
- 非空约束
- 唯一约束
- 主键约束
- 检查约束
#### 非空约束（NOT NULL）
- 含有非空约束的字段不能包含NULL值。
- 只能创建字段级非空约束。
- 在同一个表中可以定义多个非空约束。
```
--创建表添加非空约束示例。
gaussdb=# CREATE TABLE tbl_person1(
    id int not null,
    name varchar(50)
);
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
--插入不符合约束的数据，触发约束报错。
gaussdb=# INSERT INTO tbl_person1 (id,name) VALUES (NULL,'Bob');
ERROR:  dn_6001_6002_6003: The null value in column "id" violates the not-null constraint.
DETAIL:  Failing row contains (null, Bob).
--删除表。
gaussdb=# DROP TABLE tbl_person1;
DROP TABLE
```
#### 唯一约束（UNIQUE）
- 唯一约束的字段中不能包含重复值。
- 在同一个表中可以定义多个唯一约束。
- 在定义唯一约束后，数据库会自动为约束的字段添加一个唯一索引。
- 对同一个字段可以同时定义非空约束和唯一约束，如果字段只定义了唯一约束而没有定义非空约束，那么该字段可以包含多个NULL值。
```
--创建表添加字段级唯一约束示例。
gaussdb=# CREATE TABLE tbl_person2(
    id int UNIQUE, 
    name varchar(50)
);
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "tbl_person2_id_key" for table "tbl_person2"
CREATE TABLE
--创建表添加表级唯一约束示例。
gaussdb=# CREATE TABLE tbl_person3(
    id int,
    name varchar(50),
    CONSTRAINT uq_person3_id UNIQUE(id)
);
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "uq_person3_id" for table "tbl_person3"
CREATE TABLE
--插入重复的值触发唯一约束报错。
gaussdb=# INSERT INTO tbl_person2 VALUES (1,'Bob');
INSERT 0 1
gaussdb=# INSERT INTO tbl_person2 VALUES (1,'Bob');
ERROR:  dn_6004_6005_6006: Duplicate key value violates unique constraint "tbl_person2_id_key".
DETAIL:  Key (id)=(1) already exists.
--重复的NULL值不触发唯一约束。
gaussdb=# INSERT INTO tbl_person2 VALUES (null,'Bob');
INSERT 0 1
gaussdb=# INSERT INTO tbl_person2 VALUES (null,'Bob');
INSERT 0 1
--删除。
gaussdb=# DROP TABLE tbl_person2,tbl_person3;
DROP TABLE
```
#### 主键约束（PRIMARY KEY）
- 主键约束的字段不能包含重复值和NULL值。
- 可以为一个或者多个字段定义主键约束。
- 创建主键约束后，数据库会自动为该字段创建一个唯一索引和非空约束。
- 一个表中只能定义一个主键约束。
```
--创建表添加字段级主键约束示例。
gaussdb=# CREATE TABLE tbl_person4(
    id int PRIMARY KEY,
    name varchar(50)
);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "tbl_person4_pkey" for table "tbl_person4"
CREATE TABLE
--创建表添加表级主键约束示例。
gaussdb=# CREATE TABLE tbl_person5(
    id int,
    name varchar(50),
    CONSTRAINT pk_person5_id PRIMARY KEY(id)
);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pk_person5_id" for table "tbl_person5"
CREATE TABLE
--删除表。
gaussdb=# DROP TABLE tbl_person4,tbl_person5;
DROP TABLE
```
#### 检查约束（CHECK）
- 检查约束的的表达式必须引用表中的一个或多个字段，并且表达式的计算结果必须是一个布尔值，在表达式中不能包含子查询。
- 检查约束可以定义为字段级或者表级。
- 对同一个字段可以同时定义检查约束和非空约束。
- 对同一个字段可以同时定义多个检查约束。
- 同一个表中可以定义多个检查约束。
```
--创建表添加检查约束示例。
gaussdb=# CREATE TABLE tbl_person6(
    id int PRIMARY KEY,
    name varchar(50) NOT NULL,
    age int CHECK(age > 0 AND age < 200) NOT NULL
);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "tbl_person6_pkey" for table "tbl_person6"
CREATE TABLE
--插入不符合约束的数据，触发约束报错。
gaussdb=# INSERT INTO tbl_person6 VALUES (1,'Bob',500);
ERROR:  dn_6004_6005_6006: New row in relation "tbl_person6" violates check constraint "tbl_person6_age_check".
DETAIL:  N/A
--删除表。
gaussdb=# DROP TABLE tbl_person6;
DROP TABLE
```
