码迷,mamicode.com
首页 > 数据库 > 详细

MySQL的SQL语句 - 数据定义语句(14)- CREATE TABLE 语句 (8)

时间:2020-12-10 11:09:04      阅读:4      评论:0      收藏:0      [点我收藏+]

标签:内置函数   同名   组件   positive   外键   操作符   default   表达式计算   指示   

CHECK 约束

在 MySQL 8.0.16 之前,CREATE TABLE 只允许以下有限功能版本的表 CHECK 约束语法,它被解析并忽略:

1. CHECK (expr)

从 MySQL 8.0.16 开始,CREATE TABLE 支持表和列 CHECK 约束的核心功能,适用于所有存储引擎。对于表约束和列约束,CREATE TABLE 允许以下 CHECK 约束语法:

1. [CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]

可选项 symbol 指定约束的名称。如果省略,MySQL 将从表名、字面量 chk 和一个序数(1,2,3…)生成一个名称。约束名称的最大长度为64个字符。它们区分大小写,但不区分腔调。

expr 将约束条件指定为布尔表达式,对于表的每一行,该表达式的值必须为 TRUE 或 UNKNOWN (对于 NULL 值)。如果条件的计算结果为 FALSE,则失败并违反了约束。违规的影响取决于所执行的语句,本节稍后将对此进行描述。

可选强制条款指示是否强制约束:

● 如果省略或指定 ENFORCED,则创建并强制约束。

● 如果指定为 NOT ENFORCED,则创建约束但不强制执行。

CHECK 约束指定为表约束或列约束:

● 表约束不出现在列定义中,可以引用任何表列。允许对表定义后面出现的列进行前向引用。

● 列约束出现在列定义中,并且只能引用该列。

考虑这个表的定义:

1. CREATE TABLE t1
2. (
3.   CHECK (c1 <> c2),
4.   c1 INT CHECK (c1 > 10),
5.   c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
6.   c3 INT CHECK (c3 < 100),
7.   CONSTRAINT c1_nonzero CHECK (c1 <> 0),
8.   CHECK (c1 > c3)
9. );

定义包括命名格式和未命名格式的表约束和列约束:

● 第一个约束是表约束:它发生在任何列定义之外,因此它可以(而且确实)引用多个表列。此约束包含对尚未定义的列的前向引用。没有指定约束名称,因此MySQL会生成一个名称。

● 接下来的三个约束是列约束:每个约束都出现在列定义中,因此只能引用被定义的列。其中一个约束被显式地命名。MySQL 为其他两个约束生成名称。

● 最后两个约束是表约束。其中一个是显式命名的。MySQL 为另一个生成名称。

如前所述,MySQL 为没有指定名称的 CHECK 约束生成一个名称。要查看为上表定义生成的名称,请使用 SHOW CREATE TABLE 语句:

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

SQL标准指定所有类型的约束(主键、惟一索引、外键、检查)都属于同一个名称空间。在MySQL中,每个模式(数据库)的每个约束类型都有自己的名称空间。因此,每个模式的 CHECK 约束名称必须是唯一的;同一模式中的两个表不能共享 CHECK 约束名称。(例外:临时表隐藏了同名的非临时表,因此它也可以有相同的 CHECK 约束名称。)

以表名为开头生成的约束名有助于确保模式惟一性,因为表名在模式中也必须是惟一的。

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

● 允许非生成列和生成列,但具有 AUTO_INCREMENT 属性的列和其他表中的列除外。

● 允许使用字面量、确定性内置函数和操作符。对于表中相同的数据,多次调用确定性函数产生相同的结果,而不依赖于所连接的用户。结果不确定且未通过此定义的函数示例: CONNECTION_ID()、CURRENT_USER() 和 NOW()。

● 不允许使用存储函数和用户定义函数。

● 不允许使用存储过程和函数参数。

● 不允许使用变量(系统变量、用户定义变量和存储程序局部变量)。

● 不允许使用子查询。

在 CHECK 约束中使用的列上禁止外键引用操作(ON UPDATE, ON DELETE)。同样,在外键引用操作中使用的列上禁止 CHECK 约束。

CHECK 约束将针对 INSERT、UPDATE、REPLACE、LOAD DATA 和 LOAD XML 语句进行评估,如果约束的评估结果为 FALSE,则会出现错误。如果发生错误,事务性和非事务性存储引擎对已经应用的更改的处理是不同的,还取决于是否处于严格SQL模式中。

CHECK 约束将针对 INSERT IGNORE,UPDATE IGNORE,LOAD DATA ... IGNORE 和 LOAD XML ... IGNORE 语句进行评估 ,如果约束的评估结果为 FALSE,则会出现警告。将跳过任何违规行的插入或更新。

如果约束表达式要计算的数据类型与声明的列类型不同,则会根据通常的 MySQL 类型转换规则对声明的列类型进行隐式强制转换。如果类型转换失败或导致精度丢失,则会发生错误。

注意

约束表达式计算在计算时使用有效的SQL模式。如果表达式的任何组件依赖于SQL模式,则表的使用可能产生不同的结果,除非SQL模式在所有使用期间是相同的。

官方地址:
https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html

MySQL的SQL语句 - 数据定义语句(14)- CREATE TABLE 语句 (8)

标签:内置函数   同名   组件   positive   外键   操作符   default   表达式计算   指示   

原文地址:https://blog.51cto.com/15023289/2560212

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!