约束,就是字面意思,指对表中数据的一种约束,能够确保数据的正确性和有效性。
在MySQL中,主要有六种约束:主键约束、外键约束、唯一约束、检查约束、非空约束、默认值约束。

1. 主键约束

1.1. 主键约束的概念

主键是表的一个特殊字段,该字段能唯一标识该表中的每条信息,主键分为单字段主键和多字段联合主键。
一般情况下,都会要求表中设置一个主键。比如,人员信息表中的身份证号是唯一的,可以设置为主键。

  • 主键的限制:
    1. 每个表只能定义一个主键
    2. 主键值必须唯一标识表中的每一行,且不能为NULL,遵循唯一性原则
    3. 一个字段名只能在联合主键字段表中出现一次
    4. 联合主键不能包含不必要的多余字段。即把联合主键的某一字段删除后如果剩下的字段构成的主键仍然满足唯一性原则,那么这个联合主键是不正确的。这是最小化原则。

1.2.主键约束的使用

1.2.1. 设置单字段主键

  • 字段名 数据类型 primary key 默认值
  • 例,创建t1表,字段id设置为主键
1
2
3
4
5
6
7
8
9
10
11
12
mysql> create table t1 (id int(11) primary key, name varchar(32), phone char(11));
Query OK, 0 rows affected (0.19 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(32) | YES | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
  • 也可以先定时字段后指定主键,例:
1
2
3
4
5
6
7
8
9
10
11
12
mysql> create table t1 (id int(11), name varchar(32), phone char(11), primary key (id));
Query OK, 0 rows affected (0.18 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(32) | YES | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

1.2.2. 设置联合主键

  • primary key (字段名1, 字段名2, ……)
  • 例,创建数据表t1,把id、name联合起来作为主键。
1
2
3
4
5
6
7
8
9
10
11
12
mysql> create table t1 (id int(11), name varchar(32), phone char(11), primary key (id, name));
Query OK, 0 rows affected (0.18 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(32) | NO | PRI | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

1.2.3. 在修改表时添加主键约束

  • 主键也可以在修改表时添加,但是设置成主键约束的字段不允许有空值。
  • alter table 数据表名 add primary key(字段名);
  • 例,修改没有主键的t1表,把字段id设置为主键。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

mysql> alter table t1 add primary key(id);
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(32) | YES | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

1.2.4. 删除主键约束

  • alter table 数据表名 drop primary key;
  • 例,删除t1表的主键约束。
1
alter table t1 drop primary key;

1.3. 主键的自增长

1.3.1. 指定自增字段初始值

通过给字段添加auto_increment属性实现主键自增长。

  • 默认情况下,auto_increment的初始值是1,每新增一条记录,字段值自动加1。
  • 一个表中只能有一个字段使用auto_increment约束,且该字段必须有唯一索引,以避免序号重复。
  • auto_increment约束的字段必须具备not null属性。
  • auto_increment约束的字段只能是整数类型。
  • auto_increment约束字段的最大值受该字段的数据类型约束。
  • 例,创建数据表t1,指定表中id字段为主键,且自增长。
1
2
mysql> create table t1(id int(11) primary key auto_increment, name varchar(32), phone char(11));
Query OK, 0 rows affected (0.07 sec)

1.3.2. 指定自增字段初始值

  • 例,创建数据表t1,指定表中id字段为主键,从100开始自增长。
1
2
mysql> create table t1(id int not null auto_increment, name varchar(24) not null, primary key(id)) auto_increment=100;
Query OK, 0 rows affected (0.05 sec)
  • 向t1表插入数据,并查看插入数据的id
1
2
3
4
5
6
7
8
9
10
11
mysql> insert into t1(name) values ("张三");
Query OK, 1 row affected (0.02 sec)

mysql> select * from t1;
+-----+--------+
| id | name |
+-----+--------+
| 100 | 张三 |
+-----+--------+
1 row in set (0.00 sec)


2. 外键约束

2.1. 外键约束的概念

外键约束是表的一个特殊字段,经常与主键约束一起使用。两个具有关联关系的表,关联字段中主键所在的表是主表(父表),外键所在的表是从表(子表)。
外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。

  • 外键的限制:
    1. 主表必须已经存在或者是当前正在创建的表,如果主表是正在创建的表,则主表与从表是同一表,这样的表称为自参照表,这种结构称为自参照完整性。
    2. 关联的主表必须拥有主键。
    3. 主键不能存在空值,但是允许在外键中出现空值。(只要外键的每个非空值出现在指定的主键中,这个外键的内容就是对的)注:没搞懂这一句啥意思
    4. 在主表的表名后面指定的列名或者列名的组合。这个列或者列的组合必须是主表的主键或候选键。
    5. 外键中列的数目必须和主表的主键中列的数目相同。
    6. 外键中列的数据类型必须和主表主键中对应列的数据类型相同。
    7. 主表删除某条记录时,从表与之对应的记录也必须有相应的改变。
    8. 一个表可以有一个或多个外键,外键可以为空值,若不为空值,则每一个外键的值必须等于主表中主键的某个值。

2.2.外键约束的使用

2.2.1. 创建表时设置外键约束

  • 通过foreign key关键字指定外键
  • 例,已有主键为idt1表,然后创建t2表并创建外键约束,把字段t1_id作为外键关联到t1表的主键id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(24) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> create table t2(id int(11) primary key, t1_id int(11), phone varchar(11), constraint fk_t1 foreign key(t1_id) references t1(id));
Query OK, 0 rows affected (0.17 sec)

mysql> desc t2;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| t1_id | int(11) | YES | MUL | NULL | |
| phone | varchar(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

2.2.2. 删除外键约束

  • alter table 表名 drop foreign key 外键约束名;
  • 例,删除t2表的外键约束fk_t1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> alter table t2 drop foreign key fk_t1;
Query OK, 0 rows affected (0.19 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table t2 \G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`t1_id` int(11) DEFAULT NULL,
`phone` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_t1` (`t1_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
  • 重新查看t2的生成语句,foreign key已经被删除。

2.2.3. 修改表时设置外键约束

  • 外键约束也可以在修改表时添加,但是添加外键约束的前提是:从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。
  • 例,已有主键为idt1表,已有t2表,没有设置外键。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(24) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> show create table t2 \G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`t1_id` int(11) DEFAULT NULL,
`phone` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_t1` (`t1_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
  • 设置t2表的键t1_id为外键
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> alter table t2 add constraint fk_t1 foreign key(t1_id) references t1(id);
Query OK, 0 rows affected (0.20 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table t2 \G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`t1_id` int(11) DEFAULT NULL,
`phone` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_t1` (`t1_id`),
CONSTRAINT `fk_t1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
  • 重新查看t2的生成语句,t1_id已经被设置为外键约束。

3. 唯一约束

3.1. 唯一约束的概念

唯一约束是指所有记录中字段的值不能重复出现。
唯一约束与主键约束相似,都可以确保列的唯一性,不同的是,唯一约束在一个表中可有多个,并且设置唯一约束的列允许有空值,但是只能有一个空值。而主键约束在一个表中只能有一列,且不允许有空值。

3.2.唯一约束的使用

3.2.1. 创建表时设置唯一约束

  • 通过unique关键字指定外键,
  • 字段名 数据类型 unique
  • 例,创建数据表t1,指定name唯一。
1
2
3
4
5
6
7
8
9
10
11
12
mysql> create table t1(id int(11) primary key, name varchar(22) unique);
Query OK, 0 rows affected (0.17 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(22) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

3.2.2. 删除唯一约束

  • alter table 表名 drop index 唯一约束名;
  • 例,删除t1表的唯一约束name
1
2
3
4
5
6
7
8
9
10
11
12
mysql> alter table t1 drop index name;
Query OK, 0 rows affected (0.17 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(22) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
  • 重新查看t1表,唯一约束已经被删除。

3.2.3. 修改表时设置唯一约束

  • alter table 表名 add constraint 唯一约束名 unique(字段名);
  • 例,已有主键为idt1表,已有name字段,没有设置唯一约束。设置name为唯一约束。
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> alter table t1 add constraint name unique (name);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(22) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)


4. 检查约束

4.1. 检查约束的概念

检查约束是用来检查数据表中字段值有效性的一种手段。合理的使用可以减少无效数据的输入。

检查约束失效问题: 在MySQL 8.0.16之前,检查约束仅允许使用受限版本的CHECK约束语法,该语法将被解析和忽略。

4.2.检查约束的使用

4.2.1. 创建表时设置检查约束

  • 检查约束使用check关键字,
  • check 表达式
  • 例,创建数据表t1,指定age字段大于0且小于150。
1
2
3
mysql> create table t1 (id int(11) primary key auto_increment, name varchar(25), age int(11), check(age > 0 and age < 100));
Query OK, 0 rows affected (0.07 sec)

4.2.2. 删除检查约束

  • alter table 表名 drop constraint 检查约束名;
  • 例,删除t1表的检查约束age
1
2
3
4
mysql> alter table t1 drop constraint age;
Query OK, 0 rows affected (0.17 sec)
Records: 0 Duplicates: 0 Warnings: 0

4.2.3. 修改表时设置检查约束

  • alter table t1 add constraint 检查约束名 check (检查约束);
  • 例,已有t1表,已有age字段,没有设置检查约束。为age设置检查约束。
1
2
3
mysql> alter table t1 add constraint age check (age > 0 and age < 200);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0

5. 非空约束

5.1. 非空约束的概念

非空约束字段的值不能为空。使用非空约束的字段。在添加数据时必须有指定的值,否则就会报错。

5.2.非空约束的使用

5.2.1. 创建表时设置非空约束

  • 通过not null关键字设置非空约束,
  • 字段名 数据类型 not null;
  • 例,创建数据表t1,指定name不能为空。
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> create table t1 (id int(11) primary key auto_increment, name varchar(25) not null, phone char(11));
Query OK, 0 rows affected (0.07 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(25) | NO | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

5.2.2. 删除非空约束

  • alter table 表名 change column 字段名 字段名 数据类型 null;
  • 例,删除t1表的name的非空约束。
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> alter table t1 change column name name varchar(25) null;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(25) | YES | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
  • 重新查看t1表,非空约束已经被删除。

5.2.3. 修改表时设置非空约束

  • alter table 表名 change column 字段名 字段名 数据类型 not null;
  • 例,已有t1表,已有name字段,没有设置非空约束。设置name的非空约束。
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> alter table t1 change column name name varchar(25) not null;
Query OK, 0 rows affected (0.16 sec)
Records: 0 Duplicates: 0 Warnings: 00

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(25) | NO | | NULL | |
| phone | char(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

6. 默认值约束

6.1. 默认值约束的概念

默认值约束用来指定某列的默认值,在插入一条数据时,如果没有为某个字段赋值,系统就会自动为这个字段插入默认值。

6.2.默认值约束的使用

6.2.1. 创建表时设置默认值约束

  • 通过default关键字设置默认值约束,
  • 字段名 数据类型 default 默认值;
  • 例,创建数据表t1,指定name的默认值为张三
1
2
3
4
5
6
7
8
9
10
11
12
mysql> create table t1 (id int(11) primary key auto_increment, name varchar(25) default '张三', age int(11));
Query OK, 0 rows affected (0.09 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(25) | YES | | 张三 | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

6.2.2. 删除默认值约束

  • alter table 表名 change column 字段名 字段名 数据类型 default null;
  • 例,删除t1表的name的默认值约束。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> alter table t1 change column name name varchar(25) default null;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(25) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

  • 重新查看t1表,默认值约束已经被删除。

6.2.3. 修改表时设置默认值约束

  • alter table 表名 change column 字段名 字段名 数据类型 default 默认值;
  • 例,已有t1表,已有name字段,没有设置默认值约束。设置name的默认值。
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> alter table t1 change column name name varchar(25) default "张三";
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(25) | YES | | 张三 | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)