MySQL - создайте два индекса, только один отображается в выводе SHOW CREATE TABLE

У меня есть таблица связывания «многие ко многим», и я пытаюсь настроить на ней два внешних ключа. Я запускаю эти два утверждения:

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, или делаю это из командной строки.

Было бы очень признательно за любое раскрытие этой тайны.

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
2
0
2 496
2

Ответы 2

Я просто попробовал, и у меня все работает нормально. Я скопировал и вставил записи 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 5.0.51a на CentOS 5 (клон RedHat Linux). После публикации я запустил ALTER TABLE address_list_memberships ADD INDEX index_address_id (address_id), и это сработало, поэтому индекса действительно не было.

Chris Jester-Young 25.11.2008 04:14

Но MySQL позволяет создавать избыточные индексы для одного и того же столбца (столбцов), поэтому тот факт, что ADD INDEX сработал на этот раз, не обязательно означает, что ключа там раньше не было.

Bill Karwin 25.11.2008 04:55

На самом деле это не имеет значения. У вас все еще есть индекс для 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 сделает это неявно в той версии, которую вы используете.

Другие вопросы по теме