У меня есть таблица связывания «многие ко многим», и я пытаюсь настроить на ней два внешних ключа. Я запускаю эти два утверждения:
ALTER TABLE address_list_memberships
ADD CONSTRAINT fk_address_list_memberships_address_id
FOREIGN KEY index_address_id (address_id)
REFERENCES addresses (id);
ALTER TABLE address_list_memberships
ADD CONSTRAINT fk_address_list_memberships_list_id
FOREIGN KEY index_list_id (list_id)
REFERENCES lists (id);
Я ожидал, что, запустив SHOW CREATE TABLE address_list_memberships, я увижу следующее:
[...]
KEY `index_address_id` (`address_id`),
KEY `index_list_id` (`list_id`),
CONSTRAINT `fk_address_list_memberships_list_id` FOREIGN KEY (`list_id`)
REFERENCES `lists` (`id`),
CONSTRAINT `fk_address_list_memberships_address_id` FOREIGN KEY (`address_id`)
REFERENCES `addresses` (`id`)
Но вместо этого я получаю следующее:
[...]
KEY `index_list_id` (`list_id`),
CONSTRAINT `fk_address_list_memberships_list_id` FOREIGN KEY (`list_id`)
REFERENCES `lists` (`id`),
CONSTRAINT `fk_address_list_memberships_address_id` FOREIGN KEY (`address_id`)
REFERENCES `addresses` (`id`)
Похоже, что там только один индекс. Кажется, противоречит Документы MySQL, который говорит, что MySQL автоматически создает индекс для ссылочного столбца всякий раз, когда вы создаете внешний ключ.
Я заметил, что этот единственный индекс создается каждый раз, когда я создаю два FK в таблице, использую ли я инструмент с графическим интерфейсом, такой как CocoaMySQL или SQLyog, или делаю это из командной строки.
Было бы очень признательно за любое раскрытие этой тайны.






Я просто попробовал, и у меня все работает нормально. Я скопировал и вставил записи ALTER, которые вы написали, и вот что я получил:
mysql> show create table address_list_memberships;
CREATE TABLE `address_list_memberships` (
`address_id` bigint(20) unsigned NOT NULL,
`list_id` bigint(20) unsigned NOT NULL,
KEY `index_address_id` (`address_id`),
KEY `index_list_id` (`list_id`),
CONSTRAINT `fk_address_list_memberships_list_id`
FOREIGN KEY (`list_id`) REFERENCES `lists` (`id`),
CONSTRAINT `fk_address_list_memberships_address_id`
FOREIGN KEY (`address_id`) REFERENCES `addresses` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Я использую MySQL 5.0.51a в Mac OS X.
редактировать: Попробуйте выполнить следующий запрос, чтобы получить все индексы MySQL думает, существующие в вашей таблице:
SELECT * FROM information_schema.key_column_usage
WHERE table_schema = 'test' AND table_name = 'address_list_memberships'\G
(Я использовал «тестовую» базу данных для своего теста; вы должны заменить эту строку именем схемы, в которой определена ваша таблица.)
Но MySQL позволяет создавать избыточные индексы для одного и того же столбца (столбцов), поэтому тот факт, что ADD INDEX сработал на этот раз, не обязательно означает, что ключа там раньше не было.
На самом деле это не имеет значения. У вас все еще есть индекс для list_id. MySQL требует, чтобы любое ограничение внешнего ключа также имело индекс для ссылочных полей. Поскольку и index_list_id, и fk_address_list_memberships_list_id построены на list_id, MySQL, вероятно, видит это и использует index_list_id в качестве индекса, переименовывая его в fk_address_list_memberships_list_id. Вы даже можете пропустить объявление индекса, поскольку MySQL сделает это неявно в той версии, которую вы используете.
Интересно, почему это сработало для вас, а не для меня. Я использую MySQL 5.0.51a на CentOS 5 (клон RedHat Linux). После публикации я запустил
ALTER TABLE address_list_memberships ADD INDEX index_address_id (address_id), и это сработало, поэтому индекса действительно не было.