Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add description about check constraint #14227

Merged
merged 18 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 72 additions & 11 deletions constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,81 @@ Query OK, 1 row affected (0.03 sec)

## `CHECK` 约束

TiDB 会解析并忽略 `CHECK` 约束。该行为与 MySQL 5.7 的相兼容
`CHECK` 约束用于限制表中某个字段的值必须满足指定条件。当为表添加 `CHECK` 约束后,在插入或者更新表的数据时,TiDB 会检查约束条件是否满足,如果不满足,则会报错

示例如下
TiDB 中 `CHECK` 约束的语法如下,与 MySQL 中一致

```sql
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(60) NOT NULL,
UNIQUE KEY (username),
CONSTRAINT min_username_length CHECK (CHARACTER_LENGTH(username) >=4)
);
INSERT INTO users (username) VALUES ('a');
SELECT * FROM users;
[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]
```

语法说明:

- `[]` 中的内容表示可选项。
- `CONSTRAINT [symbol]` 表示 `CHECK` 约束的名称。
- `CHECK (expr)` 表示约束条件,其中 `expr` 需要为一个布尔表达式。对于表中的每一行,该表达式的计算结果必须为 `TRUE`、`FALSE` 或 `UNKNOWN` (对于 `NULL` 值) 中的一个。对于某行数据,如果该表达式计算结果为 `FALSE`,则表示违反约束条件。
- `[NOT] ENFORCED` 表示是否执行约束,可以用于启用或者禁用 `CHECK` 约束。

### 添加 `CHECK` 约束

在 TiDB 中,你可以在 [`CREATE TABLE`](/sql-statements/sql-statement-create-table.md) 或者 [`ALTER TABLE`](/sql-statements/sql-statement-modify-column.md) 语句中为表添加 `CHECK` 约束。

- 在 `CREATE TABLE` 语句中添加 `CHECK` 约束的示例:

```sql
CREATE TABLE t(a INT CHECK(a > 10) NOT ENFORCED, b INT, c INT, CONSTRAINT c1 CHECK (b > c));
```

- 在 `ALTER TABLE` 语句中添加 `CHECK` 约束的示例:

```sql
ALTER TABLE t ADD CONSTRAINT CHECK (1 < c);
```

在添加或者启用 `CHECK` 约束时,TiDB 会对表中的存量数据进行校验。如果存在违反约束的数据,添加 `CHECK` 约束操作将失败并且报错。

在添加 `CHECK` 约束时,可以指定约束名,也可以不指定约束名。如果不指定约束名,那么 TiDB 会自动生成一个格式为 `<tableName>_chk_<1, 2, 3...>` 的约束名。

### 查看 `CHECK` 约束

你可以通过 [`SHOW CREATE TABLE`](/sql-statements/sql-statement-show-create-table.md) 查看表中的约束信息。例如:

```sql
SHOW CREATE TABLE t;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
CONSTRAINT `c1` CHECK ((`b` > `c`)),
CONSTRAINT `t_chk_1` CHECK ((`a` > 10)) /*!80016 NOT ENFORCED */,
CONSTRAINT `t_chk_2` CHECK ((1 < `c`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
```

### 删除 `CHECK` 约束

删除 `CHECK` 约束时,你需要指定需要删除的约束名。例如:

```sql
ALTER TABLE t DROP CONSTRAINT t_chk_1;
```

### 启用或禁用 `CHECK` 约束

在为表[添加 `CHECK` 约束](#添加-check-约束)的时候,可以指定当插入或者更新数据时 TiDB 是否执行约束检查。

- 如果指定了 `NOT ENFORCED`,当插入或者更新数据时,TiDB 不会检查约束条件。
- 如果未指定 `NOT ENFORCED` 或者指定了 `ENFORCED`,当插入或者更新数据的时候,TiDB 会检查约束条件。

除了在添加约束时候指定 `[NOT] ENFORCED`,你还可以在 `ALTER TABLE` 语句中启用或者禁用 `CHECK` 约束。例如:

```sql
ALTER TABLE t ALTER CONSTRAINT c1 NOT ENFORCED;
```

## 唯一约束
Expand Down
1 change: 0 additions & 1 deletion sql-statements/sql-statement-create-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ mysql> DESC t1;
* `COMMENT` 属性不支持 `WITH PARSER` 选项。
* TiDB 在单个表中默认支持 1017 列,最大可支持 4096 列。InnoDB 中相应的数量限制为 1017 列,MySQL 中的硬限制为 4096 列。详情参阅 [TiDB 使用限制](/tidb-limitations.md)
* 当前仅支持 Range、Hash 和 Range Columns(单列)类型的分区表,详情参阅[分区表](/partitioned-table.md)
* TiDB 会解析并忽略 `CHECK` 约束,与 MySQL 5.7 相兼容。详情参阅 [`CHECK` 约束](/constraints.md#check-约束)

## 另请参阅

Expand Down