MySQL表的约束

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 及以上版本支持的新约束。

相关推荐
SPC的存折15 小时前
openEuler 24.03 MariaDB Galera 集群部署指南(cz)
linux·运维·服务器·数据库·mysql
仲芒15 小时前
[24年单独笔记] MySQL 常用的 DML 命令
数据库·笔记·mysql
SPC的存折15 小时前
MySQL 8.0 分库分表
linux·运维·服务器·数据库·mysql
蓦然乍醒15 小时前
使用 DBeaver 还原 PostgreSQL 备份文件 (.bak) 技术文档
数据库·postgresql
XDHCOM15 小时前
Redis节点故障自动恢复机制详解,如何快速抢救故障节点,确保数据不丢失?
java·数据库·redis
QCzblack16 小时前
BugKu BUUCTF ——Reverse
java·前端·数据库
cyber_两只龙宝16 小时前
【Oracle】Oracle之DQL中WHERE限制条件查询
linux·运维·数据库·云原生·oracle
luis的妙妙屋16 小时前
主流数据库数据类型对比分析
数据库
XDHCOM16 小时前
ORA-00054资源忙故障修复,远程处理Oracle报错解决方案,数据库锁超时NOWAIT指定问题排查
数据库·oracle
q210306337216 小时前
初学Access(具体示例)
数据库