MySQL 没有为外键创建索引

MySQL not creating indexes for foreign key

我读到 InnoDB 会自动为外键创建索引。

Does MySQL Workbench automatically create indexes for foreign keys? Does MySQL index foreign key columns automatically? https://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html

但是我的一些外键在table中没有索引。检查 pharmaceutical_id 外键字段。它没有索引。

| pharmaceuticals_pharmaceuticalcode | CREATE TABLE `pharmaceuticals_pharmaceuticalcode` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code_id` int(11) NOT NULL,
  `pharmaceutical_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `pharmaceuticals_pharmaceuticalco_pharmaceutical_id_5ae1e77e_uniq` (`pharmaceutical_id`,`code_id`),
  KEY `pharmaceuticals_phar_code_id_a7de9505_fk_human_api` (`code_id`),
  CONSTRAINT `pharmaceuticals_phar_code_id_a7de9505_fk_human_api` FOREIGN KEY (`code_id`) REFERENCES `human_api_code` (`id`),
  CONSTRAINT `pharmaceuticals_phar_pharmaceutical_id_04c18462_fk_pharmaceu` FOREIGN KEY (`pharmaceutical_id`) REFERENCES `pharmaceuticals_pharmaceutical` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=202770 DEFAULT CHARSET=utf8 COLLATE=utf8_bin |

我在 pharmaceutical_idcode_id 上添加了 unique-together 约束,这可能导致无法为 pharmaceutical_id 创建单独的索引,因为 MySQL 在 B-Tree 样式和唯一在一起键的索引可以用于它。

检查 https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

上的第 6 点限制和条件

InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order. Hidden columns that InnoDB adds to an index are also considered (see Section 14.6.2.1, “Clustered and Secondary Indexes”).

但是,如果上述观点是正确的,那么为什么在下面的 table 模式中存在 member_id 的索引?因为 patients_membercard_b5c3e75b 索引 在 patients_membercard_member_id_661ac31abca894ae_uniq

之后是多余的
| patients_membercard | CREATE TABLE `patients_membercard` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `member_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `patients_membercard_member_id_661ac31abca894ae_uniq` (`member_id`,`name`),
  KEY `patients_membercard_b5c3e75b` (`member_id`),
  CONSTRAINT `patients_member_member_id_459e0d6970a32170_fk_patients_member_id` FOREIGN KEY (`member_id`) REFERENCES `patients_member` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1655520 DEFAULT CHARSET=utf8 COLLATE=utf8_bin |

PS: 以上table, schema 由Django 创建,未对DB 进行任何手动操作

你的外键确实有索引。

MySQL 将 KEYINDEX 这两个词在许多上下文中视为同义词。

What's the difference between using INDEX vs KEY in MySQL?


重新更新问题。

我认为 Django 负责定义额外的 KEY patients_membercard_b5c3e75b (member_id)。它不是自动创建的。也就是说,如果我在没有该 KEY 定义的情况下测试您的 CREATE TABLE 语句,则 FOREIGN KEY 不需要它。 FOREIGN KEY可以使用UNIQUE KEY的左列member_id

我猜创建 Django 的开发人员没有处理这种情况。他们假设每个 FOREIGN KEY 都需要自己的索引,并且他们更愿意确保他们可以控制索引名称。因此,他们在 CREATE TABLE 语句中显式生成索引的定义。