MySQL CHECK约束

2024-06-12 13:36
文章标签 mysql 约束 database check

本文主要是介绍MySQL CHECK约束,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在 MySQL 中,直到 MySQL 8.0.16 版本之前,标准 SQL 的 CHECK 约束并未被完全支持。然而,从 MySQL 8.0.16 开始,CHECK 约束在表定义中得到了支持,允许你定义列中必须满足的条件。

使用 CHECK 约束,你可以确保在插入或更新记录时,某列或某组列的值满足特定的条件。

以下是如何在 MySQL 中使用 CHECK 约束

1、MySQL5.7.X CHECK 约束

MySQL5.7.X CHECK 约束是无效的,只做检查CHECK ,不强制CHECK

1.1、测试用例

在这个示例中,我们创建了一个名为 t_check 的表,其中有一个c_age 列。CHECK约束确保c_age 列的值在大于等于18。

select @@version 检查MySQL版本信息

mysql> select @@version;
+------------+
| @@version  |
+------------+
| 5.7.28-log |
+------------+
1 row in set (0.00 sec)mysql> status
--------------
mysql  Ver 14.14 Distrib 5.7.28, for linux-glibc2.12 (x86_64) using  EditLine wrapperConnection id:          2
Current database:       superdb
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.28-log MySQL Community Server (GPL)
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /tmp/mysql.sock
Uptime:                 6 min 59 secThreads: 1  Questions: 18  Slow queries: 0  Opens: 111  Flush tables: 1  Open tables: 26  Queries per second avg: 0.042
--------------
create table t_check
( id int not null primary key,c_name varchar(32),c_age int check(c_age>=18)
);
-- insert 
mysql> insert into t_check values(1,'column_check_001',18);
Query OK, 1 row affected (0.04 sec)mysql> insert into t_check values(2,'column_check_002',17);
Query OK, 1 row affected (0.00 sec)mysql> insert into t_check values(3,'column_check_003',30);
Query OK, 1 row affected (0.00 sec)mysql> commit;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t_check;
+----+------------------+-------+
| id | c_name           | c_age |
+----+------------------+-------+
|  1 | column_check_001 |    18 |
|  2 | column_check_002 |    17 |
|  3 | column_check_003 |    30 |
+----+------------------+-------+
3 rows in set (0.00 sec)

2、MySQL8.X CHECK 约束

MySQL8.0.X check是有效的,做检查CHECK ,强制CHECK

2.1、创建表t_check,插入满足 CHECK 约束的数据

在这个示例中,我们创建了一个名为 t_check 的表,其中有一个c_age 列。CHECK约束确保c_age 列的值在大于等于18。

mysql> create table t_check
-> ( id int not null primary key,
->   c_name varchar(32),
->   c_age int check(c_age>=18)
-> );
Query OK, 0 rows affected (0.15 sec)
mysql> insert into t_check values(1,'column_check_001',18);
Query OK, 1 row affected (0.01 sec)

2.2、尝试插入不满足 CHECK 约束的数据:

mysql> insert into t_check values(2,'column_check_002',17);
ERROR 3819 (HY000): Check constraint 't_check_chk_1' is violated.

2.3、插入满足 CHECK 约束的数据

mysql> insert into t_check values(3,'column_check_003',30);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.02 sec)
mysql> select * from t_check;
+----+------------------+-------+
| id | c_name           | c_age |
+----+------------------+-------+
|  1 | column_check_001 |    18 |
|  3 | column_check_003 |    30 |
+----+------------------+-------+
2 rows in set (0.00 sec)

2.4、给已经创建好的表增加约束

create table t_check2
( id int not null primary key,c_name varchar(32),c_age int
);
alter table t_check2 add constraint check(c_age>=18);insert into t_check2 values(1,'column_check_001',18);
insert into t_check2 values(2,'column_check_002',17);
insert into t_check2 values(3,'column_check_003',30);
commit;
select * from t_check2;

同上用例测试 MySQL8.0 ,check有效检查并强制约束,执行效果如下

mysql> insert into t_check2 values(2,'column_check_002',17);
ERROR 3819 (HY000): Check constraint 't_check2_chk_1' is violated.

3、约束的相关查询及管理

3.1、8.0.X 视图information_schema.CHECK_CONSTRAINTS

SELECT * FROM information_schema.CHECK_CONSTRAINTS ;

mysql> SELECT  * FROM  information_schema.CHECK_CONSTRAINTS ;  
+--------------------+-------------------+-----------------+-----------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CHECK_CLAUSE    |
+--------------------+-------------------+-----------------+-----------------+
| def                | db01              | t_check2_chk_1  | (`c_age` >= 18) |
+--------------------+-------------------+-----------------+-----------------+

select * from information_schema.TABLE_CONSTRAINTS
where CONSTRAINT_SCHEMA=‘superdb’
and TABLE_NAME=‘t_check2’;

mysql> select  * from  information_schema.TABLE_CONSTRAINTS-> where CONSTRAINT_SCHEMA='superdb'-> and TABLE_NAME='t_check2';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def                | superdb           | PRIMARY         | superdb      | t_check2   | PRIMARY KEY     | YES      |
| def                | superdb           | t_check2_chk_1  | superdb      | t_check2   | CHECK           | YES      |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
2 rows in set (0.00 sec)

3.2、查看表的主键约束信息

select * from information_schema.KEY_COLUMN_USAGE kcu
where CONSTRAINT_SCHEMA=‘superdb’
and TABLE_NAME=‘t_check’;

mysql> select * from information_schema.KEY_COLUMN_USAGE kcu-> where  CONSTRAINT_SCHEMA='superdb'-> and  TABLE_NAME='t_check';
+--------------------+-------------------+-----------------+---------------+--------------+------------+-------------+------------------+-------------------------------+-------------------------+-----------------------+------------------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | ORDINAL_POSITION | POSITION_IN_UNIQUE_CONSTRAINT | REFERENCED_TABLE_SCHEMA | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+--------------------+-------------------+-----------------+---------------+--------------+------------+-------------+------------------+-------------------------------+-------------------------+-----------------------+------------------------+
| def                | superdb           | PRIMARY         | def           | superdb      | t_check    | id          |                1 |                          NULL | NULL                    | NULL                  | NULL                   |
+--------------------+-------------------+-----------------+---------------+--------------+------------+-------------+------------------+-------------------------------+-------------------------+---

3.3、查看表的外键约束信息

select * from information_schema.REFERENTIAL_CONSTRAINTS rc
where CONSTRAINT_SCHEMA=‘superdb’
and TABLE_NAME=‘t_check’;

mysql> select  * from  information_schema.REFERENTIAL_CONSTRAINTS rc-> where CONSTRAINT_SCHEMA='superdb'-> and  TABLE_NAME='t_check';
Empty set (0.00 sec)
-- 因没有外键约束,查出为空

4、 删除 CHECK 约束:

要删除一个 CHECK 约束,你需要知道它的名字(如果在创建时指定了的话)。但如果你没有指定名字,你可能需要删除整个表并重新创建它,或者使用其他方法(如触发器)来模拟 CHECK 约束的行为。

mysql> alter table t_check2 drop constraint t_check2_chk_1;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

再次插入之前不满足条件的数据,则执行成功

mysql> insert into t_check2 values(2,'column_check_002',17);
Query OK, 1 row affected (0.00 sec)mysql> commit;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t_check2;
+----+------------------+-------+
| id | c_name           | c_age |
+----+------------------+-------+
|  1 | column_check_001 |    18 |
|  2 | column_check_002 |    17 |
|  3 | column_check_003 |    30 |
+----+------------------+-------+
3 rows in set (0.00 sec)

5、在多个列上使用 CHECK 约束:

你也可以在多个列上使用 CHECK 约束,例如:

CREATE TABLE t_students (  id INT AUTO_INCREMENT PRIMARY KEY,  age INT,  grade CHAR(1),  CHECK (age >= 0 AND age <= 100),  CHECK (grade IN ('A', 'B', 'C', 'D', 'F'))  
);

在这个示例中,我们添加了一个额外的 CHECK 约束来确保 grade 列的值是 ‘A’、‘B’、‘C’、‘D’ 或 ‘F’ 中的一个。

这篇关于MySQL CHECK约束的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1054366

相关文章

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

MySQL的ALTER TABLE命令的使用解读

《MySQL的ALTERTABLE命令的使用解读》:本文主要介绍MySQL的ALTERTABLE命令的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、查看所建表的编China编程码格式2、修改表的编码格式3、修改列队数据类型4、添加列5、修改列的位置5.1、把列

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

解决mysql插入数据锁等待超时报错:Lock wait timeout exceeded;try restarting transaction

《解决mysql插入数据锁等待超时报错:Lockwaittimeoutexceeded;tryrestartingtransaction》:本文主要介绍解决mysql插入数据锁等待超时报... 目录报错信息解决办法1、数据库中执行如下sql2、再到 INNODB_TRX 事务表中查看总结报错信息Lock

MySQL启动报错:InnoDB表空间丢失问题及解决方法

《MySQL启动报错:InnoDB表空间丢失问题及解决方法》在启动MySQL时,遇到了InnoDB:Tablespace5975wasnotfound,该错误表明MySQL在启动过程中无法找到指定的s... 目录mysql 启动报错:InnoDB 表空间丢失问题及解决方法错误分析解决方案1. 启用 inno

MySQL 安装配置超完整教程

《MySQL安装配置超完整教程》MySQL是一款广泛使用的开源关系型数据库管理系统(RDBMS),由瑞典MySQLAB公司开发,目前属于Oracle公司旗下产品,:本文主要介绍MySQL安装配置... 目录一、mysql 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1

MySQL 添加索引5种方式示例详解(实用sql代码)

《MySQL添加索引5种方式示例详解(实用sql代码)》在MySQL数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中,下面给大家分享MySQL添加索引5种方式示例详解(实用sql代码),... 在mysql数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中。索引可以在创建表时定义,也可