MySQL Не удается удалить индекс, необходимый для ограничения внешнего ключа

Мне нужно добавить ALTER мою существующую базу данных, чтобы добавить столбец. Следовательно, я также хочу обновить поле UNIQUE, чтобы включить этот новый столбец. Я пытаюсь удалить текущий индекс, но продолжаю получать ошибку MySQL Cannot drop index needed in a foreign key constraint

CREATE TABLE mytable_a (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;

CREATE TABLE mytable_b (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;

CREATE TABLE mytable_c (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;


CREATE TABLE `mytable` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `AID` tinyint(5) NOT NULL,
  `BID` tinyint(5) NOT NULL,
  `CID` tinyint(5) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `AID` (`AID`,`BID`,`CID`),
  KEY `BID` (`BID`),
  KEY `CID` (`CID`),
  CONSTRAINT `mytable_ibfk_1` FOREIGN KEY (`AID`) REFERENCES `mytable_a` (`ID`) ON DELETE CASCADE,
  CONSTRAINT `mytable_ibfk_2` FOREIGN KEY (`BID`) REFERENCES `mytable_b` (`ID`) ON DELETE CASCADE,
  CONSTRAINT `mytable_ibfk_3` FOREIGN KEY (`CID`) REFERENCES `mytable_c` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB;




mysql> ALTER TABLE mytable DROP INDEX AID;
ERROR 1553 (HY000): Cannot drop index 'AID': needed in a foreign key constraint

Ответ 1

Вам нужно отказаться от внешнего ключа. Внешние ключи в MySQL автоматически создают индекс в таблице (в теме был SO вопрос).

ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1 ; 

Ответ 2

Шаг 1

Перечислите внешний ключ (обратите внимание, что он отличается от имени индекса)

SHOW CREATE TABLE  <Table Name>

Результат покажет вам имя внешнего ключа.

Формат:

CONSTRAINT 'FOREIGN_KEY_NAME' FOREIGN KEY ('FOREIGN_KEY_COLUMN') REFERENCES 'FOREIGN_KEY_TABLE' ('id'),

Шаг 2

Drop (внешний/первичный/ключ) ключ

ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign key name>

Шаг 3

Брось индекс.

Ответ 3

Если вы имеете в виду, что вы можете это сделать:

CREATE TABLE mytable_d (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;


ALTER TABLE mytable
ADD COLUMN DID tinyint(5) NOT NULL,
ADD CONSTRAINT mytable_ibfk_4 
      FOREIGN KEY (DID) 
        REFERENCES mytable_d (ID) ON DELETE CASCADE;

 > OK.

Но тогда:

ALTER TABLE mytable
DROP KEY AID ;

дает ошибку.


Вы можете удалить индекс и создать новый в одном выражении ALTER TABLE:

ALTER TABLE mytable
DROP KEY AID ,
ADD UNIQUE KEY AID (AID, BID, CID, DID);

Ответ 4

Поскольку у вас должен быть индекс в поле внешнего ключа, вы можете просто создать простой индекс в поле "AID"

CREATE INDEX aid_index ON mytable (AID);

и только затем отбросить уникальный индекс 'AID'

ALTER TABLE mytable DROP INDEX AID;

Ответ 5

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

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

Ответ 6

Я думаю, что это простой способ отбросить индекс.

set FOREIGN_KEY_CHECKS=1;

ALTER TABLE mytable DROP INDEX AID;

set FOREIGN_KEY_CHECKS=0;