mysql - 未在 CREATE TABLE 语句中创建的索引和约束

标签 mysql sql mariadb

我正在使用 MySQL/MariaDB,我创建了一个员工表:

CREATE TABLE employees(
    id INT AUTO_INCREMENT,
    name VARCHAR(40) NOT NULL,
    description VARCHAR(50) DEFAULT 'No Description',
    random_assignment_id INT UNIQUE, 
    birth_date DATE, 
    salary DECIMAL(5,2),
    supervisor_id INT,
    branch_id INT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT random_assignment_check CHECK (LENGTH(random_assignment_id) = 5),
    INDEX(random_assignment_id, supervisor_id, branch_id),
    PRIMARY KEY(id)
)

然后我确认表已按预期创建:

SHOW CREATE TABLE employees\G;
*************************** 1. row ***************************
       Table: employees
Create Table: CREATE TABLE `employees` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(40) NOT NULL,
  `description` varchar(50) DEFAULT 'No Description',
  `random_assignment_id` int(11) DEFAULT NULL,
  `birth_date` date DEFAULT NULL,
  `salary` decimal(5,2) DEFAULT NULL,
  `supervisor_id` int(11) DEFAULT NULL,
  `branch_id` int(11) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `random_assignment_id` (`random_assignment_id`),
  KEY `random_assignment_id_2` (`random_assignment_id`,`supervisor_id`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

我没有看到列出的 random_assignment_check 约束,我希望它索引 random_assignment_id、supervisor_id 和 branch_id,但它没有:

 DESCRIBE employees;
+----------------------+--------------+------+-----+-------------------+----------------+
| Field                | Type         | Null | Key | Default           | Extra          |
+----------------------+--------------+------+-----+-------------------+----------------+
| id                   | int(11)      | NO   | PRI | NULL              | auto_increment |
| name                 | varchar(40)  | NO   |     | NULL              |                |
| description          | varchar(50)  | YES  |     | No Description    |                |
| random_assignment_id | int(11)      | YES  | UNI | NULL              |                |
| birth_date           | date         | YES  |     | NULL              |                |
| salary               | decimal(5,2) | YES  |     | NULL              |                |
| supervisor_id        | int(11)      | YES  |     | NULL              |                |
| branch_id            | int(11)      | NO   |     | NULL              |                |
| created_at           | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
| updated_at           | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
+----------------------+--------------+------+-----+-------------------+----------------+

key 下没有 MUL 标志。

请注意,我读到 MariaDB 现在支持约束;根据自制程序,我正在使用:

brew info mariadb
mariadb: stable 10.3.12 (bottled)
Drop-in replacement for MySQL

我做错了什么?

最佳答案

MySQL 将KEY 视为INDEX 的同义词。你的索引 INDEX(random_assignment_id, supervisor_id, branch_id) 变成了 KEY random_assignment_id_2 (random_assignment_id,supervisor_id,branch_id)。索引名称由 MySQL 生成,但逻辑上它们是相同的索引。

当我测试您的 CREATE TABLE 语句然后使用 DESC 显示它时,我也没有看到任何 MUL 指示符。这适合 documentation :

If Key is MUL, the column is the first column of a nonunique index in which multiple occurrences of a given value are permitted within the column.

因此在您的输出中,random_assignment_id 的 Key 字段是 UNI,因为它是一个唯一的键,而且是多列键的一部分。

MySQL 不支持 CHECK 约束。它解析它们,然后忽略它们。它们不会与您的表一起存储,随后使用 SHOW CREATE TABLE 也不会显示它们。

根据 https://mariadb.com/kb/en/library/constraint/#check-constraints,MariaDB 在 10.2.1 中实现了 CHECK 约束。 (我不使用 MariaDB,所以我相信他们的文档)。

如果您在 MySQL Community Edition 或 MariaDB 上测试了 CHECK 约束,那么您的问题并不清楚。 CHECK 约束不会保存在 MySQL 上,在 MariaDB 上根据文档似乎没问题,但我从未测试过。

我们都应该停止认为 MariaDB 是 MySQL 的直接替代品。这两种产品已经分化了将近 10 年,不能再假定它们兼容。

关于mysql - 未在 CREATE TABLE 语句中创建的索引和约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54312010/

相关文章:

php - Echofish 错误 500 "CDbConnection failed to open the DB connection"

mysql - Azure Mariadb TX 2.0 连接不起作用

php - 在没有 group_concat 的情况下连接 symfony/doctrine/mysql 中的行

sql - 如何向 MySQL 重复原始 SQL 查询 # 次?

mysql - mysql中的自动求和

php - 如何在 php laravel 内迁移转储数据库 (users.sql)?

mysql - cakephp 一年中每月 COUNT 个项目

sql - 批量更新 Redshift 中的现有行

sql - 运行时错误 '3704' 关闭对象时不允许进行操作。 VBA 中的 SQL 语句

mysql - 查询SQL数据库-一对多查询