MySQL表的约束
在MySQL中,约束(Constraints)用于确保数据库表中数据的完整性 和一致性,是限制表中数据的类型、格式以及有效值的规则。通过约束,可以确保数据库的完整性,防止不合法的数据进入数据库。
1. 与约束有关的列属性(Column Attributes)
1.1 列描述(COMMENT)
列描述没有实际含义,专门用来描述字段,相当于注释,用来给程序员或 DBA 了解该字段的含义。
mysql
create table products (
id int comment "产品ID"
);
注意,查看 COMMENT 不能使用 desc
,而是要使用 show create table tb_name\G
的方式查看。
mysql
mysql> desc products;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| id | int | YES | | NULL | |
+-------+------+------+-----+---------+-------+
1 row in set (0.01 sec)
mysql> show create table products\G;
*************************** 1. row ***************************
Table: products
Create Table: CREATE TABLE `products` (
`id` int DEFAULT NULL COMMENT '产品ID'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
1.2 zerofill
zerofill 会对整型空余的部分使用 0
进行填充,来达到显示上的美观效果,实际对数值本身并没有影响。
mysql
create table products (
id int(10) zerofill #表示显示10位,不足的部分用0填充
);
向表中插入一个 123456 123456 123456 的数据:
mysql
mysql> insert products value(123456);
Query OK, 1 row affected (0.00 sec)
mysql> select * from products;
+------------+
| id |
+------------+
| 0000123456 |
+------------+
1 row in set (0.00 sec)
1.3 自增长(AUTO_INCREMENT)
自增长(AUTO_INCREMENT)是 MySQL 提供的一种属性(Attribute) ,用于自动为某一列生成唯一的递增值 。它通常与主键(PRIMARY KEY)一起使用,以确保每一行都有一个唯一的标识符。
在插入数据时,当自增长对应的字段没有给值时,MySQL 会自动赋予该值当前字段中已经有的最大值 + 1 +1 +1 ,来得到一个新的不同的值。
mysql
create table users (
id int auto_increment primary key,
name varchar(50)
);
注意,自增长要求:
-
任何一个字段要设置为自增长,前提是该字段本身必须是一个索引(key 一栏有值)。
-
自增长字段必须是整数。
-
一张表最多只能有一个自增长。
示例:
mysql
mysql> insert into users value(0,'张三');
Query OK, 1 row affected (0.01 sec)
mysql> insert into users(name) value('李四');
Query OK, 1 row affected (0.00 sec)
mysql> insert into users(name) value('王五');
Query OK, 1 row affected (0.01 sec)
mysql> select * from users;
+----+--------+
| id | name |
+----+--------+
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
+----+--------+
3 rows in set (0.00 sec)
2. 非空约束(NOT NULL)
MySQL 在插入数据时,默认不输入某个字段,该行的该字段就为空(default null)。而在创建或更改字段时,可用设置该字段不能为空(NOT NULL),让用户在插入数据时必须为该字段确定一个值。
mysql
create table products (
name varchar(100) not NULL
);
注意,在创建字段时,如果不设置非空约束,MySQL 会自动设置该自动的默认值为空。但设置非空约束后,MySQL 就不会自动为该字段设置默认值。理论上,默认值和非空约束可以同时设置在一个字段上,但通常情况下使用较少。
3. 默认值约束(DEFAULT)
MySQL 在插入数据时,如果未指定某一列的值,默认情况下会将该列的值设置为 NULL。但在创建或更改表时,可以通过设置默认值约束(DEFAULT)来指定某一列的默认值。当插入数据未指定该列的值时,MySQL 会自动填充默认值。
mysql
create table orders (
order_date DATE default CURRENT_DATE
);
注意,只有设置了 default 的列,才可以在插入值时对列进行省略。
4. 主键约束(PRIMARY KEY)
在创建或更改表时,可以通过设置主键约束(PRIMARY KEY)来确保某一列(或列组合)的值必须唯一,且不能为空。主键用于唯一标识表中的每一行数据。
mysql
create table users (
id INT primary key,
name varchar(50)
);
注意,主键约束通常用于标识表中的唯一记录,因此每个表只能有一个主键。 但一个主键可用约束多列 ,这样的主键,则称为复合主键。
mysql
create table users (
id INT,
name varchar(50),
primary key(id,name) #id和name为复合主键
);
5. 唯一键约束(UNIQUE)
在创建或更改表时,可以通过设置唯一键约束(UNIQUE)来确保某一列(或列组合)的值在表中唯一。唯一约束允许空值(NULL),且允许有多个 NULL 值。唯一约束通常用于确保某一列的值不重复,例如邮箱地址或电话号码。
mysql
create table employees (
email varchar(100) unique,
phone varchar(20) unique
);
注意,主键与唯一键的区别在于:
- 主键在表中唯一,但唯一键在同一张表中可以设置多个。
- 主键不允许存在为 NULL 的值,唯一键允许 NULL 值,且允许存在多个。
6. 外键约束(FOREIGN KEY)
在创建或更改表时,可以通过设置外键约束(FOREIGN KEY)确保某一列的值必须存在于另一个表的主键或唯一键中,外键用于建立表与表之间的关联关系 。外键约束在从表中建立,定义外键后,从表中的外键列必须包含主表中已存在的值,或者(如果允许)为 NULL 。主表和从表的外键约束映射可以一对多、多对一(多对多需要使用中间表)。默认情况下,如果从表中仍有引用的记录,主表的被引用行不能删除。
示例
主表:
mysql
create table class (
id INT primary key comment "班级号",
name varchar(10) comment "班级名"
);
从表:
mysql
create table student (
id INT primary key comment "学号",
name varchar(10) comment "学生名",
class_id int,
foreign key (class_id) references class(id)
);
允许正常插入数据:
因为 2401 班和 2402 班存在,学生能够插入:
mysql
mysql> insert into class value(2401,'一班'),(2402,'二班');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into student value(2024001,'张三',2401),(2024002,'李四',2402);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
不能插入主表不存在对应的数据:
因为 2403 班不存在,学生不能够插入:
mysql
mysql> insert into student value(2024003,'王五',2403);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mytest`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
允许插入从表对应数据为 NULL 的数据:
有外键约束的两个表对应的字段,从表可以用 NULL 表示暂时没有确定要对应到主表对应字段的哪个值:
mysql
mysql> insert into student value(2024003,'王五',null);
Query OK, 1 row affected (0.00 sec)
7. 检查约束(CHECK)
在创建或更改表时,可以通过设置检查约束(CHECK)来确保某一列的值满足特定条件。检查约束用于限制列的取值范围。
mysql
create table students (
age INT check (age >= 18)
);
注意,检查约束(CHECK)是 MySQL 8.0.16 及以上版本支持的新约束。