MySQL은 외래 키 제약 조건에서 필요한 인덱스를 삭제할 수 없습니다


156

기존 데이터베이스를 변경하여 열을 추가해야합니다. 결과적으로 새 열을 포함하도록 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

UNIQUE KEY AIDmytable을 가정 ?
Mike Purcell

답변:


228

외래 키를 삭제해야합니다. MySQL의 외래 키는 테이블에 인덱스를 자동으로 생성합니다 ( 주제에 대한 SO 질문 이 있음).

ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1 ; 

12
인덱스를 삭제 한 후 다시 추가 할 수 있습니다. ALTER TABLE mytableADD CONSTRAINT mytable_ibfk_1FOREIGN KEY ( AID) REFERENCES mytable_a( ID) ON DELETE CASCADE;
laffuste

8
훌륭하지만 FOREIGN KEY제약 조건이 익명 인 경우 어떻게해야 합니까?
Pehat

@Pehat 아래 답변을 확인하십시오 stackoverflow.com/a/54145440/2305119
thyzz

1
참고 : 외래 키가 명확하지 않을 수 있습니다. 테이블 및 열과 관련된 모든 외래 키를 찾으려면 다음 쿼리를 사용할 수 있습니다. dba.stackexchange.com/questions/102371/…
charlax

84

1 단계

외래 키 나열 (인덱스 이름과 다른 점)

SHOW CREATE TABLE  <Table Name>

결과에 외래 키 이름이 표시됩니다.

체재:

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

2 단계

드롭 (외국 / 기본 / 키) 키

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

3 단계

색인을 삭제하십시오.


18

당신이 이것을 할 수 있다는 것을 의미한다면 :

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);

8

외래 키 필드에 인덱스가 있어야하므로 'AID'필드에 간단한 인덱스를 만들 수 있습니다.

CREATE INDEX aid_index ON mytable (AID);

그런 다음에 만 고유 색인 'AID'를 삭제하십시오.

ALTER TABLE mytable DROP INDEX AID;

7

외래 키에는 항상 인덱스가 필요합니다. 인덱스를 사용하지 않으면 제약 조건을 적용하면 참조 테이블의 모든 삽입 또는 업데이트 된 키에 대해 참조 테이블에서 전체 테이블 스캔이 필요합니다. 이는 용납 할 수없는 성능 영향을 미칩니다. 다음과 같은 두 가지 결과가 있습니다.

  • 외래 키를 만들 때 데이터베이스는 인덱스가 있는지 확인합니다. 그렇지 않으면 색인이 작성됩니다. 기본적으로 제약 조건과 이름이 같습니다.
  • 외래 키에 사용할 수있는 인덱스가 하나만 있으면 삭제할 수 없습니다. 실제로 삭제하지 않으려면 외래 키 제약 조건을 삭제하거나 다른 인덱스를 먼저 만들어야합니다.

1
당신은 다른 답변이 부족하다는 이론을 가지고 있습니다.
Dennis

1
따라서 : 복합 고유 색인 (고유 제한 조건의 다중 열)이있는 경우 A 및 B에 대한 색인이없는 경우 고유 AB 키를 제거 할 수 없습니다.이 오류가 발생하면 다른 테이블이 열 A 또는 B, AB 고유 항목을 안전하게 제거하기 전에 추가해야합니다.
로빈 드 Schepper

@RobinDeSchepper 좋은 말입니다. 복합 고유 인덱스를 사용할 때 필드 순서는 고유 인덱스에는 중요하지 않지만 외래 키에는 중요 할 수 있습니다. A의 고유 인덱스를, B는 A의 외래 키에 의해 사용될 수 있지만 B.에 외래 키에 의해
스테판 Mondelaers

2

이것이 인덱스를 삭제하는 쉬운 방법이라고 생각합니다.

set FOREIGN_KEY_CHECKS=1;

ALTER TABLE mytable DROP INDEX AID;

set FOREIGN_KEY_CHECKS=0;

2
수표 활성화 및 비활성화를 교환했다고 생각합니다. 상단에 나는 기대 FOREIGN_KEY_CHEK=0하고 끝에 FOREIGN_KEY_CHEK=1.
romor

0

필자의 경우 외래 키를 삭제했지만 여전히 인덱스를 삭제할 수 없습니다. 동일한 필드에이 테이블에 대한 외래 키가있는 또 다른 테이블이 있었기 때문입니다. 다른 테이블에서 외래 키를 삭제 한 후이 테이블에서 인덱스를 삭제할 수 있습니다.


0

외래 키 열을 삭제하려면 (스위치 제약 조건 유지) 외래 키를 먼저 삭제 한 다음 열을 삭제해야합니다. 외래 키를 삭제할 때 모든 이름을 전달할 필요는 없습니다. 외래 키를 전달하면됩니다. 열 이름 :

$table->dropForeign(['currency_id']);
$table->dropColumn('currency_id');

자세한 내용은 :

https://laravel.com/docs/6.x/migrations#foreign-key-constraints

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.