Ключи PRIMARY и INDEX для одного столбца FOREIGN в MySQL

Я использовал MySQL Workbench для подготовки макета базы данных и экспортировал его в свою базу данных с помощью phpMyAdmin. При просмотре одной таблицы я получил следующее предупреждение:

Ключи PRIMARY и INDEX не должны быть установлены одновременно для столбца gid.

gid — это внешний индекс, который является первичным ключом другой таблицы, а также частью первичного ключа текущей таблицы. Так что он у меня есть как часть первичного ключа, а Workbench создал индекс для записи внешнего ключа. Так почему же появляется это предупреждение, следует ли его игнорировать или следует переосмыслить структуру базы данных?

Это очень упрощенный пример используемой структуры, которая выдает предупреждение:

CREATE  TABLE IF NOT EXISTS `test_groups` (
  `gid` INT NOT NULL ,
  `gname` VARCHAR(45) NULL ,
  PRIMARY KEY (`gid`) );

CREATE  TABLE IF NOT EXISTS `test_users` (
  `gid` INT NOT NULL ,
  `uid` INT NOT NULL ,
  `name` VARCHAR(45) NULL ,
  PRIMARY KEY (`gid`, `uid`) ,
  INDEX `gid` (`gid` ASC) ,
  CONSTRAINT `gid`
    FOREIGN KEY (`gid` )
    REFERENCES `test_groups` (`gid` )
    ON DELETE CASCADE
    ON UPDATE CASCADE);

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

Но почему MySQL Workbench заставляет меня сохранять этот индекс? Я не могу удалить его вручную, пока есть внешний ключ.


person poke    schedule 20.01.2010    source источник


Ответы (2)


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

person symcbean    schedule 20.01.2010
comment
Так правильно ли, что дополнительный индекс создается для внешнего ключа? И извините, но я не понимаю вторую часть вашего ответа. - person poke; 20.01.2010
comment
Извините - я предположил, что это связано с тем, что поле является как первичным, так и внешним ключом. Да, второй индекс является избыточным, mysql с радостью будет использовать индекс первичного ключа для возврата строк, запрошенных 'gid'. Это будет немного менее эффективно, но вы никогда не сможете измерить разницу. С. - person symcbean; 21.01.2010

Я решил эту проблему сейчас. Похоже, что механизм хранения базы данных по умолчанию был установлен на MyISAM на моем сервере, поэтому, поскольку я не указал его явно, все отношения внешнего ключа просто отбрасывались (хотя, не говоря об этом). После преобразования в InnoDB я больше не получаю предупреждение, поэтому кажется, что все работает как надо.

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

Также в отношении MySQL Workbench это поведение все еще кажется немного ошибочным, и оно уже было сообщил.

person poke    schedule 20.01.2010
comment
Эта ошибка неправильно помечена как дубликат какой-то другой исправленной ошибки. Это текущая релевантная ошибка. - person phazei; 24.02.2011