226

I need to ALTER my existing database to add a column. Consequently I also want to update the UNIQUE field to encompass that new column. I'm trying to remove the current index but keep getting the error 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
Stewart
  • 18,103
  • 8
  • 49
  • 77
user391986
  • 27,330
  • 37
  • 120
  • 195

12 Answers12

319

You have to drop the foreign key. Foreign keys in MySQL automatically create an index on the table (There was a SO Question on the topic).

ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1 ; 
Community
  • 1
  • 1
Brian Fisher
  • 22,731
  • 15
  • 76
  • 81
  • 19
    You might want to add it back after dropping the index: ALTER TABLE `mytable` ADD CONSTRAINT `mytable_ibfk_1` FOREIGN KEY (`AID`) REFERENCES `mytable_a` (`ID`) ON DELETE CASCADE; – laffuste Feb 11 '14 at 07:49
  • 9
    That's great, but what can I do if my `FOREIGN KEY` constraint was anonymous? – Pehat Jul 08 '16 at 14:48
  • @Pehat check my answer below https://stackoverflow.com/a/54145440/2305119 – thyzz Jan 11 '19 at 11:16
  • 3
    Note: the foreign key might not be as obvious. To find all foreign keys related to a table and column, you can use this query: https://dba.stackexchange.com/questions/102371/mysql-how-to-check-foreign-keys-related-to-a-table – charlax Jun 12 '19 at 14:54
  • I hate that this is the correct answer, but it is. (upvote). Yes, as Iaffuste says, you probably want to re-add the FK after you drop the index (or constraint). – granadaCoder Mar 24 '21 at 15:18
109

Step 1

List foreign key ( NOTE that its different from index name )

SHOW CREATE TABLE  <Table Name>

The result will show you the foreign key name.

Format:

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

Step 2

Drop (Foreign/primary/key) Key

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

Step 3

Drop the index.

Rakmo
  • 1,588
  • 2
  • 17
  • 34
Abhishek Goel
  • 16,893
  • 10
  • 83
  • 64
19

If you mean that you can do this:

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.

But then:

ALTER TABLE mytable
DROP KEY AID ;

gives error.


You can drop the index and create a new one in one ALTER TABLE statement:

ALTER TABLE mytable
DROP KEY AID ,
ADD UNIQUE KEY AID (AID, BID, CID, DID);
ypercubeᵀᴹ
  • 109,746
  • 18
  • 170
  • 231
18

A foreign key always requires an index. Without an index enforcing the constraint would require a full table scan on the referenced table for every inserted or updated key in the referencing table. And that would have an unacceptable performance impact. This has the following 2 consequences:

  • When creating a foreign key, the database checks if an index exists. If not an index will be created. By default, it will have the same name as the constraint.
  • When there is only one index that can be used for the foreign key, it can't be dropped. If you really wan't to drop it, you either have to drop the foreign key constraint or to create another index for it first.
  • 1
    you have the theory that other answers lacked. – Dennis Feb 08 '19 at 22:20
  • 1
    So: If you have a compound unique index (multiple columns in a unique constraint) you cannot remove the unique A-B key unless you have an index for A and B. If you get this error, another table is using the index of column A or B, and you'll have to add those before you can safely remove the A-B unique. – Robin De Schepper May 06 '19 at 09:24
  • @RobinDeSchepper Good remark. And when using compound unique indexes, the order of the fields is not important for the unique index, but it might be important for a foreign key. A unique index on A,B can be used by a foreign key on A, but not by a foreign key on B. – Stefan Mondelaers Jun 07 '19 at 12:59
10

Because you have to have an index on a foreign key field you can just create a simple index on the field 'AID'

CREATE INDEX aid_index ON mytable (AID);

and only then drop the unique index 'AID'

ALTER TABLE mytable DROP INDEX AID;
Eli DM
  • 395
  • 3
  • 8
3

I think this is easy way to drop the index.

set FOREIGN_KEY_CHECKS=0; //disable checks

ALTER TABLE mytable DROP INDEX AID;

set FOREIGN_KEY_CHECKS=1; //enable checks
Dwza
  • 6,358
  • 4
  • 38
  • 66
Ram E Sh
  • 103
  • 1
  • 1
  • 3
    I think you exchanged enabling and disabling the checks. At the top I would expect `FOREIGN_KEY_CHEK=0` and at the end `FOREIGN_KEY_CHEK=1`. – romor Dec 01 '19 at 09:59
  • I edited the answere, switched the on off check and added comments to it. Would vote this serverl time up if I could :D thank you Ram. – Dwza Aug 17 '20 at 13:52
  • Down voted because this doesnt work. I still cant delete the unique index. – Martijn Hiemstra Jun 09 '21 at 10:27
  • This doesn't really work. I'm going to have to delete the foreign key first. – Omar Dulaimi Jun 27 '21 at 10:32
3

drop the index and the foreign_key in the same query like below

ALTER TABLE `your_table_name` DROP FOREIGN KEY `your_index`;
ALTER TABLE `your_table_name` DROP COLUMN `your_foreign_key_id`;
Yann Boyongo
  • 161
  • 1
  • 5
1

In my case I dropped the foreign key and I still could not drop the index. That was because there was yet another table that had a foreign key to this table on the same fields. After I dropped the foreign key on the other table I could drop the indexes on this table.

jav
  • 504
  • 5
  • 14
0

If you are using PhpMyAdmin sometimes it don't show the foreign key to delete.

The error code gives us the name of the foreign key and the table where it was defined, so the code is:

ALTER TABLE your_table DROP FOREIGN KEY foreign_key_name; 
Eli
  • 19
  • 2
0

You can show Relation view in phpMyAdmin and first delete foreign key. After this you can remove index.

dmajka
  • 101
  • 1
  • 3
0

You can easily check it with DBeaver. Example: enter image description here

As you can see there are 3 FKs but only 2 FK indexes. There is no index for FK_benefCompanyNumber_beneficiaries_benefId as UK index provide uniqueness for that FK.

To drop that UK you need to:

  1. DROP FK_benefCompanyNumber_beneficiaries_benefId
  2. DROP UK
  3. CREATE FK_benefCompanyNumber_beneficiaries_benefId
Karol Murawski
  • 169
  • 1
  • 8
0

The current most upvoted answer is not complete.
One needs to remove all the foreign keys whose "source" column is also present in the UNIQUE KEY declaration. So in this case, it is not enough to remove mytable_ibfk_1 for the error to go away, mytable_ibfk_2 and mytable_ibfk_3 must be deleted as well. This is the complete answer:

    ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1;
    ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_2;
    ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_3;
Víctor Gil
  • 608
  • 6
  • 8