【问题标题】:MySQL not creating indexes for foreign keyMySQL没有为外键创建索引
【发布时间】:2020-04-16 20:01:03
【问题描述】:

我读到 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

但是我的一些外键在表中没有索引。检查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 方式管理这些索引,并且unique-together 键的索引可以是用于它。

检查https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html上的第6个限制点和条件

InnoDB 允许外键引用任何索引列或列组。但是,在引用的表中,必须有一个索引,其中引用的列是相同顺序的第一列。 InnoDB 添加到索引的隐藏列也会被考虑(参见第 14.6.2.1 节,“聚集索引和二级索引”)。

但是如果上述观点是正确的,那么为什么在下表模式中有一个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:上表,schema由Django创建,未对DB进行手动操作。

【问题讨论】:

    标签: mysql django django-orm


    【解决方案1】:

    你的外键确实有索引。

    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 语句中显式地生成索引的定义。

    【讨论】:

    • 是的,在 MySQL 中 key 和 Index 是一样的。但我的问题是第一个表中的索引较少,或者第二个表中有一个额外的索引。我已经更新了问题
    猜你喜欢
    • 2018-10-14
    • 2021-11-18
    • 2010-12-07
    • 2011-08-22
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多