广告
返回顶部
首页 > 资讯 > 数据库 >Mysql中的CHECK约束特性详解
  • 148
分享到

Mysql中的CHECK约束特性详解

摘要

功能说明 在Mysql 8.0.16以前, CREATE TABLE允许从语法层面输入下列CHECK约束,但实际没有效果: CHECK (expr) 在 mysql 8.0.16,CREATE TABLE添加了针对所有存

功能说明

Mysql 8.0.16以前, CREATE TABLE允许从语法层面输入下列CHECK约束,但实际没有效果:

CHECK (expr)

mysql 8.0.16,CREATE TABLE添加了针对所有存储引擎的表和列的CHECK约束的核心特性。CREATE TABLE允许如下针对表或列的约束语法:

[CONSTRaiNT [symbol]] CHECK (expr) [[NOT] ENFORCED]
  • 可选的symbol指定了约束的名称,如果省略,Mysql会自动生成一个类似:${table_name}_check_${seq_num}的约束名称,约束名称是大小写敏感的,且最长可以到64个字符
  • expr设定了一个返回值为boolean类型的约束条件,表达式对所有的数据行评估的结果值为:TRUE或UNKNOWN(对 NULL值),当值为FALSE时,约束就被违反,产生的效果与执行的语句有关
  • 可选的执行子句标识约束是否需要被强制:
    当未指定或指定为: ENFORCED时,约束被创建且生效
    当指定为: NOT ENFORCED时,约束被创建但未生效
  • 一个CHECK约束可以被指定为表约束或列约束
    表约束不会出现在列定义内,可以引用任意多个或一个列,且允许引用后续定义的表列
    列约束出现在列定义内,仅允许引用该列

示例如下:

CREATE TABLE t1
(
 CHECK (c1 <> c2),
 c1 INT CHECK (c1 > 10),
 c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
 c3 INT CHECK (c3 < 100),
 CONSTRAINT c1_nonzero CHECK (c1 <> 0),
 CHECK (c1 > c3)
);

以上示例包含了列约束和表约束,命名和未命名的格式:

  • 第一个约束是一个不包含在任何列定义内的表约束,所以允许引用任意列,且引用了后续定义的列,同时没有给出约束名称,所以MySQL会给该约束生成一个名字
  • 后续的3个约束是包含在列定义内的列约束,所有指定引用所在的列
  • 最后的两个是表约束

如果想查看上述命令所生成的约束名,可以输入以下SHOW CREATE TABLE命令:

mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
   Table: t1
Create Table: CREATE TABLE `t1` (
 `c1` int(11) DEFAULT NULL,
 `c2` int(11) DEFAULT NULL,
 `c3` int(11) DEFAULT NULL,
 CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)),
 CONSTRAINT `c2_positive` CHECK ((`c2` > 0)),
 CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)),
 CONSTRAINT `t1_chk_2` CHECK ((`c1` > 10)),
 CONSTRAINT `t1_chk_3` CHECK ((`c3` < 100)),
 CONSTRAINT `t1_chk_4` CHECK ((`c1` > `c3`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

SQL规范要求:所有约束(包括:PRIMARY KEY, UNIQUE,FOREIGN KEY, CHECK)属于同一个命名空间(NAMESPACE),在MySQL实现中,所有的约束类型在每个schema (database)内有自己的命名空间。所以,CHECK约束的名称在SCHEMA内必须唯一,也就是说不允许有两张表使用同一个CHECK约束名称。(例外:一个临时表可能使用与非临时表一样的约束名称)

CHECK的条件表达式必须遵守以下规则,如果包含不允许的结构,将会触发错误:

  • 非生成列和生成列允许被添加到表达式,但包含AUTO_INCREMENT属性的列和其他表的列不允许被加入
  • 字面量和确定性(deterministic)的内置函数以及操作符允许被添加到表达式,确定性的含义是:同样的数据不同用户的多次调用的结果是一致的,非确定性的函数包括:CONNECTioN_ID(),CURRENT_USER(),NOW()
  • 存储函数和用户自定义函数不被允许
  • 存储过程不被允许
  • 变量:系统变量、用户自定义变量和存储过程的本地变量均不被允许使用
  • 子查询不应许被使用
  • 外键参考动作,如:ON UPDATE, ON DELETE被禁止在包含CHECK约束的列使用,相应的,CHECK约束也被禁止在使用外键参考动作的列使用
  • CHECK约束在插入、更新、替换(REPLACE)和LOAD DATA/XML语句的时候被评估,如果评估结果是FALSE将触发错误,如果错误发生,已经提交的数据的处理与对应存储引擎是否支持事务有关,也依赖严格SQL模式是否生效
  • 如果约束表达式所需的数据类型与声明的列类型不一致,数据将参考MySQL的类型转换规则被隐式的转换
约束表达式在不同的SQL模式下,可能返回不同的结果

另外,在INFORMATION_SCHEMA的CHECK_CONSTRAINTS表中存放着所有表中定义的CHECK约束的信息。

建议使用CHECK约束的场景

复杂业务场景下的约束,从架构角度看,允许有不同的实现方式:

放在数据库表中,通过约束实现,但不支持子查询

放在数据库中,通过触发器(TRIGGER)实现

放在应用程序的逻辑中,在提前数据库前检查

一般性的,选择不同方式的原则如下:

如果CHECK约束可以实现,且约束比较稳定,一般用CHECK约束实现,比如:年龄不允许为负数,不允许>150等,比如:

CREATE TABLE Departments (
  ID int NOT NULL,
  PID int NOT NULL,
  Name varchar(255) NOT NULL Default '',
  CHECK (ID>=1)
);
-- add check separately
ALTER TABLE Departments
ADD CONSTRAINT CHK_PID CHECK (ID>=1 AND PID >=0);
-- remove check
ALTER TABLE Departments
DROP CHECK CHK_PID;

如果属于数据库逻辑,比如:审计,外键可以使用触发器

CREATE TABLE IF NOT EXISTS `department` (
 `id` int NOT NULL AUTO_INCREMENT,
 `pid` int COMMENT 'parent id',
 `name` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
 ) ENGINE = InnoDB;


CREATE TRIGGER pid_insert_check
BEFORE INSERT ON department
FOR EACH ROW
BEGIN
 IF (NEW.pid <> 0 AND NEW.pid NOT IN (select id from department)) THEN
  signal sqlstate '45000'
  set message_text = 'department parent id has to be chosen from id';
 END IF;
END


CREATE TRIGGER pid_delete_check
BEFORE DELETE ON department
FOR EACH ROW
BEGIN
 IF (OLD.id < 0 OR OLD.id IN (select pid from department)) THEN
  signal sqlstate '45000'
  set message_text = 'department parent id has to be chosen from id';
 END IF;
END

如果属于业务逻辑,建议放在应用层处理,方便开发者:理解和维护,但是:也需要通过强化业务管理,避免特权用户偶发操作引起对数据完整性的破坏

到此这篇关于Mysql中的CHECK约束特性详解的文章就介绍到这了,更多相关Mysql中CHECK约束内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

您可能感兴趣的文档:

--结束END--

本文标题: Mysql中的CHECK约束特性详解

本文链接: https://www.lsjlt.com/news/33530.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql中的CHECK约束特性详解
    功能说明 在mysql 8.0.16以前, CREATE TABLE允许从语法层面输入下列CHECK约束,但实际没有效果: CHECK (expr) 在 MySQL 8.0.16,CREATE TABLE添加了针对所有存...
    99+
    2022-08-08
    mysql check约束 MySQL检查约束 mysql设置check约束 mysqlcheck约束怎么写
  • MySQL学习之完整性约束详解
    数据完整性指的是数据的一致性和正确性。完整性约束是指数据库的内容必须随时遵守的规则。若定义了数据完整性约束,mysql会负责数据的完整性,每次更新数据时,MySQL都会测试新的数据内容是否符合相关的完整性约束条件,只有符...
    99+
    2022-08-11
    MySQL 完整性约束 MySQL 约束
  • MySQL数据库表中的约束详解
    目录mysql表中的约束(constraint)约束分类非空约束唯一性约束复合约束主键约束自增列-AUTO_INCREMENT外键约束FOREIGN KEY约束CHECK约束DEFAULT约束MySQL表中的约束(con...
    99+
    2023-03-02
    MySQL表中的约束 MySQL数据库约束 MySQL约束的使用
  • MySQL六种约束的示例详解
    目录什么是约束外键约束什么是约束 作用于表上的规则,限制存储在表中的数据 约束分类: 约束描述关键字非空约束该字段数据不能为nullNOT NULL唯一约束该字段数据唯一不重复UNIQUE主键约束一行数据的唯一标识(非空...
    99+
    2023-02-21
    MySQL六种约束 MySQL约束
  • Mysql表的约束超详细讲解
    目录约束的概念空属性默认值列描述zerofill主键自增长唯一键外键约束的概念 约束:通过限制用户操作的方式,来达到维护数据本身安全,完整性的一套方案。 为什么要有约束? Mysql...
    99+
    2022-11-13
  • MySQL数据库中的外键约束详解
    外键是关系数据库中一种重要的数据完整性约束,它用于建立表与表之间的关联关系。外键约束指定了一个表的列或一组列必须存在于另一个表的主键...
    99+
    2023-09-22
    MySQL
  • MySQL 8.0新特性 — 检查性约束的使用简介
    前言 在MySQL 8.0版本中,引入了一个非常有用的新特性 — 检查性约束,它可以提高对非法或不合理数据写入的控制能力;接下来我们就来详细了解一下。 检查性约束 创建、删除与查看 (1)可以在建表时,创建检查...
    99+
    2022-05-31
    MySQL 8.0新特性 MySQL 检查性约束
  • MySQL数据库的约束限制详解
    目录一、介绍二、操作添加删除外键联级操作一、介绍 数据库的约束是对表中数据进行的一种限制,为了保证数据的正确性、有效性、完整性。 无论是在添加数据还是在删除数据的时候,都能提供帮助。...
    99+
    2022-11-13
    MySQL数据库 MySQL约束
  • MySQL中常见的六个约束类型详解
    目录前言1. not null2. unique3. default4. primary key自增主键auto_increment5. foreign key6. check总结前...
    99+
    2022-11-12
  • SQL Server中的约束(constraints)详解
    目录一、约束的分类二、约束命名三、主键约束1、在创建表的时候创建主键约束。2、在已存在的表上创建主键约束3、复合主键的创建四、外键约束4.1、创建表的时候创建外键4.2、在已存在的表...
    99+
    2022-11-13
  • SQL Server中的约束(constraints)详解
    SQL Server中的约束是一种用于限制表中数据的规则。它们可以应用于列级别或表级别,并确保数据库中的数据遵循特定的规则和完整性要...
    99+
    2023-08-16
    SQL Server
  • MySQL总结(七)数据库表的约束-详解
    数据库表的约束 1. 数据库约束的概述 1.1 约束的作用: 对表中的数据进行限制,保证数据的正确性、有效性和完整性。一个表如果添加了约束,不正确的数据将无法插入到表中。约束在创建表的时候添加比较合适。 1.2 约束种类: 约束...
    99+
    2017-04-03
    MySQL总结(七)数据库表的约束-详解
  • C#泛型约束中的引用详解
    本篇内容介绍了“C#泛型约束中的引用详解”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!C# 泛型约束中的引用/值类型约束使用 C# 泛型,编...
    99+
    2023-06-17
  • MySQL六种约束的示例详解(全网最全)
    目录一、概述二、约束演示三、外键约束1、 什么是外键约束2、 不使用外键有什么影响3、 添加外键的语法4、 删除/更新行为5、 演示删除/更新行为四、主键id到底用自增好还是uuid好五、实际开发尽量少用外键一、概述 概...
    99+
    2022-07-26
    MySQL约束类型 MySQL 约束
  • MySQL中唯一性约束与NULL的示例分析
    这篇文章给大家分享的是有关MySQL中唯一性约束与NULL的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言之前做的一个需求,简化描述下就是接受其他组的 MQ 的消息,...
    99+
    2022-10-18
  • 【从删库到跑路】详细讲解MySQL的函数和约束作用
    🎊专栏【MySQL】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 文章目录 🍔...
    99+
    2023-08-16
    mysql 数学建模 python
  • 如何解决MySQL报错:唯一键约束中的重复记录
    当MySQL报错唯一键约束中的重复记录时,可以采取以下几种方法来解决问题:1. 删除重复记录:通过执行DELETE语句来删除...
    99+
    2023-10-12
    MySQL
  • MySQL InnoDB引擎的缓存特性详解
    目录1. 背景2. 存储器性能差异3. Buffer Pool4. Free链表5. Flush链表6. LRU链表7. 其它1. 背景 对于各种用户数据、索引数据等各种数据都是需要持久化存储到磁盘,然后以“...
    99+
    2022-09-13
  • MySQL InnoDB引擎的缓存特性详解
    目录1. 背景2. 存储器性能差异3. Buffer Pool4. Free链表5. Flush链表6. LRU链表7. 其它1. 背景 对于各种用户数据、索引数据等各种数据都是需要...
    99+
    2022-11-13
  • 详解Vue3 中的watchEffect 特性
    watchEffect 是 Vue3 中提供的一个新特性,用于监听响应式数据的变化,并在数据发生变化时执行指定的回调函数。 与 Vue2 中的 watch 不同,watchEffec...
    99+
    2023-05-18
    Vue3 watchEffect Vue3 watchEffect特征
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作