2016-09-26 5 views
0

Рассмотрим базу данных из двух простых таблиц: tablea имеет INT id, поле VARCHAR something и ссылки tableb (содержит одно и то же поле, но с добавлением UNIQUE).Производит ли MySQL индексы для ограничений UNIQUE и FOREIGN KEY неявно или я должен их явно создавать?

MySQL Workbench будет генерировать следующий код, если мы используем его для разработки и вперед-инженер этой схемы:

CREATE TABLE IF NOT EXISTS `tableb` (
    `id` INT NOT NULL AUTO_INCREMENT, 
    `something` VARCHAR(45) NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE INDEX `something_UNIQUE` (`something` ASC)) 
ENGINE = InnoDB; 

CREATE TABLE IF NOT EXISTS `tablea` (
    `id` INT NOT NULL, 
    `something` VARCHAR(45) NULL, 
    `tableb_id` INT NOT NULL, 
    PRIMARY KEY (`id`, `tableb_id`), 
    INDEX `fk_tablea_tableb_idx` (`tableb_id` ASC), 
    CONSTRAINT `fk_tablea_tableb` 
    FOREIGN KEY (`tableb_id`) 
    REFERENCES `tableb` (`id`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 

, но мы можем по-видимому достичь того же эффекта (ту же схему таблиц, столбцов и ограничений) с более простой, минималистичный код:

CREATE TABLE IF NOT EXISTS `tableb` (
    `id` INT NOT NULL AUTO_INCREMENT, 
    `something` VARCHAR(45) NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE (`something`) 
) ENGINE = InnoDB; 

CREATE TABLE IF NOT EXISTS `tablea` (
    `id` INT NOT NULL, 
    `something` VARCHAR(45) NULL, 
    `tableb_id` INT NOT NULL, 
    PRIMARY KEY (`id`, `tableb_id`), 
    FOREIGN KEY (`tableb_id`) REFERENCES `tableb`(`id`) 
) ENGINE = InnoDB; 

Действительно ли первая версия лучше (например, быстрее), чем вторая? Не будет ли MySQL создавать индексы, упомянутые в первой версии во втором случае?

+0

Почему, по вашему мнению, MySQL автоматически индексирует столбец? –

+0

для FK уверены в * ссылке *, если необходимо, на основе самого левого. Это можно увидеть после факта с 'show create table myTable'. В * ссылочном * no для FK в качестве попытки «ALTER TABLE» или создания дочернего элемента через «CREATE TABLE» будет просто сбой – Drew

+0

Вам определенно необходимо определить его, например, если вы хотите использовать auto_increment, вы должны определить это тоже. MySQL-движок не читает, что вы думаете, вам нужно определить все параметры. Ура! – JoelBonetR

ответ

0

В вашем последнем фрагменте, как я упоминал в комментариях, и, как говорится в руководстве, вам не нужно явно создавать ключи, связанные с FK, в дочерних таблицах (ссылки). MySQL будет автоматически создавать их для вас, если это необходимо, на основе самого левого (или, в первую очередь, как говорится в руководстве). Один индекс столбца, естественно, самый левый. Для композитов, которые являются многоколоночными ключами, наиболее естественным образом имеет смысл.

Это будет очень очевидным, если вы запустите ваш выше, и выдать

show create table tablea; 

Если вам случится иметь самый левый ключ, определенный уже в детстве, и она может использоваться для отношений FK, двигатель не создаст для вас один.

На странице ручного под названием Using FOREIGN KEY Constraints

В ссылающейся таблице, должен быть индекс, где внешний ключ столбцы перечислены первые столбцы в том же порядке. Такой индекс создается в справочной таблице автоматически, если не существует . Этот индекс может быть отключен позднее, если вы создадите еще один индекс, который можно использовать для принудительного ограничения внешнего ключа. index_name, если задано, используется, как описано ранее.

Кроме того, как я уже говорил в комментариях под вашим вопросом, то ссылки таблицы (родительская), однако, должна иметь необходимые самые левые клавиши в месте для быстрого поиска до всего этого. Этот ключ не должен быть PRIMARY или уникальным ключом. Но он должен быть доступен для большинства композиций. Если один не доступен в родительском до ALTER TABLE или CREATE TABLE ребенка, то операция завершается с

MySQL Ошибка 1215: Не удается добавить ограничение внешнего ключа

В течение нескольких быстрых примеров о том, когда создается новый ключ от вашего имени (или нет) в дочерних таблицах:

  1. Если вы явно создать ключ на col1, и он используется в FK, вспомогательный ключ не создан для вас.

  2. Если вы явно создаете составной ключ на (a, b, c, d), и у вас есть FK on (a, b), то для вас не создается вспомогательный ключ.

  3. Если вы явно создаете составной ключ на (a, b, c, d), и у вас есть FK on (a, c), то для вас создается вспомогательный ключ. Потому что b помещается в явном виде, и требуется новый ключ.

  4. Если вы явно создаете составной ключ на (a, b, c, d), и у вас есть FK on (a, b, c), то для вас не создается вспомогательный ключ. Самый левый в явном, в том же порядке, был более чем достаточен для требований FK.

+0

Можно ли ожидать, что первая версия схемы (сгенерированная MySQL Workbench) будет работать быстрее, чем вторая версия (без использования ключевого слова 'index')? – Ivan

+0

они идентичны для MySQL auto генерирует 'fk_tablea_tableb_idx', если все, что вы вводите, является вторым фрагментом. Что, как я уже сказал, видно, если вы набираете 'show create table tablea' – Drew