【问题标题】:INFORMATION_SCHEMA.TABLE_CONSTRAINTS missing index that is shown with SHOW INDEX in MySQLINFORMATION_SCHEMA.TABLE_CONSTRAINTS 缺少在 MySQL 中显示为 SHOW INDEX 的索引
【发布时间】:2019-07-17 06:28:14
【问题描述】:

NodeJS ORM Sequelize 使用 INFORMATION_SCHEMA.TABLE_CONSTRAINTS to show constraints 并且我遇到了一个问题,即该查询中未显示约束但确实存在,因此我无法在续集迁移中更改约束。

我不确定这是续集问题还是 MySQL 问题,但让我摸不着头脑的原始 SQL 是:

mysql> use rypedb; SHOW INDEX FROM teacher_information;
Database changed
+---------------------+------------+-----------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+--------
| Table               | Non_unique | Key_name                          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment
+---------------------+------------+-----------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+--------
| teacher_information |          0 | PRIMARY                           |            1 | id          | A         |         143 |     NULL |   NULL |      | BTREE      |
| teacher_information |          1 | teacher_information_teacher_id_fk |            1 | account_id  | A         |         143 |     NULL |   NULL |      | BTREE      |
+---------------------+------------+-----------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+--------
2 rows in set (0.00 sec)

mysql> select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME = 'teacher_information_teacher_id_fk' AND TABLE_SCHEMA = 'rypedb';
Empty set, 2 warnings (0.01 sec)

是否预计INFORMATION_SCHEMA.TABLE_CONSTRAINTS 不应具有SHOW INDEX 查询中显示的索引?它确实显示了其他限制,这是我第一次看到这个问题。

这是我的 create table 语句的输出:

| teacher_information | CREATE TABLE `teacher_information` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `account_id` int(10) unsigned NOT NULL,
  `description` varchar(1024) DEFAULT NULL,
  `image_url` varchar(256) DEFAULT NULL,
  `bio_link` varchar(256) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `teacher_information_teacher_id_fk` (`account_id`)
) ENGINE=InnoDB AUTO_INCREMENT=144 DEFAULT CHARSET=utf8 |

【问题讨论】:

  • 约束的名称并不总是与键的名称相同。试试WHERE table_name = 'teacher_information'
  • 你能显示show create table teacher_information的输出吗?
  • 这看起来就像如果你有一个外键约束你会看到的,但是删除了它。 FK 创建非唯一索引和外键约束,移除 FK 会移除约束但保留索引。
  • 我同意巴马尔的观点。这里的错误似乎是期望外键 constraint 的名称将匹配 index (键)的名称,或者外键约束存在于给定索引。两个(或更多)FK 约束也可以使用相同的索引。没有显示不良状态,除非意图是应该有一个外键约束,例如CONSTRAINT teacher_information_teacher_id_fk FOREIGN KEY (account_id) REFERENCES foo (bar) ON UPDATE CASCADE ON DELETE RESTRICT。即有一个没有外键约束的索引是有效的)。
  • 是的,这看起来像您删除了 account_id 上的 FK 约束,但没有删除索引。

标签: mysql sequelize.js


【解决方案1】:

约束与索引不同。

这是一个表的示例,该表包含一个 PRIMARY KEY、一个辅助 UNIQUE KEY、一个 FOREIGN KEY、一个 CHECK 约束和另一个不是约束的索引。

CREATE TABLE `test`.`bar` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `foo_id` bigint(20) unsigned DEFAULT NULL,
  `unique_int` int(11) DEFAULT NULL,
  `nonunique_int` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_int` (`unique_int`),
  KEY `my_fk` (`foo_id`),
  KEY `nonunique_int` (`nonunique_int`),
  CONSTRAINT `bar_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`),
  CONSTRAINT `my_chk` CHECK ((`nonunique_int` in (1,2,3)))
)

这是 INFORMATION_SCHEMA.TABLE_CONSTRAINTS 中的内容:

select * from table_constraints where table_schema='test' and table_name='bar';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def                | test              | PRIMARY         | test         | bar        | PRIMARY KEY     | YES      |
| def                | test              | unique_int      | test         | bar        | UNIQUE          | YES      |
| def                | test              | bar_ibfk_1      | test         | bar        | FOREIGN KEY     | YES      |
| def                | test              | my_chk          | test         | bar        | CHECK           | YES      |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+

这是同一表的 INFORMATION_SCHEMA.STATISTICS 表中的内容:

select * from statistics where table_schema='test' and table_name='bar';
+---------------+--------------+------------+------------+--------------+---------------+--------------+---------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | NON_UNIQUE | INDEX_SCHEMA | INDEX_NAME    | SEQ_IN_INDEX | COLUMN_NAME   | COLLATION | CARDINALITY | SUB_PART | PACKED | NULLABLE | INDEX_TYPE | COMMENT | INDEX_COMMENT | IS_VISIBLE | EXPRESSION |
+---------------+--------------+------------+------------+--------------+---------------+--------------+---------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+------------+
| def           | test         | bar        |          1 | test         | my_fk         |            1 | foo_id        | A         |           0 |     NULL |   NULL | YES      | BTREE      |         |               | YES        | NULL       |
| def           | test         | bar        |          1 | test         | nonunique_int |            1 | nonunique_int | A         |           0 |     NULL |   NULL | YES      | BTREE      |         |               | YES        | NULL       |
| def           | test         | bar        |          0 | test         | PRIMARY       |            1 | id            | A         |           0 |     NULL |   NULL |          | BTREE      |         |               | YES        | NULL       |
| def           | test         | bar        |          0 | test         | unique_int    |            1 | unique_int    | A         |           0 |     NULL |   NULL | YES      | BTREE      |         |               | YES        | NULL       |
+---------------+--------------+------------+------------+--------------+---------------+--------------+---------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+------------+

这表明 PRIMARY KEY 和 UNIQUE KEY 和 FOREIGN KEY 确实隐式创建索引,但是:

  • CHECK 不创建索引
  • KEY 不创建约束

【讨论】:

  • 在 MySQL 8.0 CHECK 应该创建一个约束。
  • +10 强调 CONSTRAINT 与 INDEX (KEY) 不同
  • @Barmar,是的,我在 8.0.16 上进行了测试,CHECK 约束确实在 TABLE_CONSTRAINTS 表中创建了一行。约束名称是 my_chk 并且存在。
猜你喜欢
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多