외래 키 참조 작업을 변경하는 방법은 무엇입니까? (행동)


102

ON DELETE CASCADE(부모가 삭제되면 자식 삭제)로 설정된 외래 키가있는 열이 포함 된 테이블을 설정했습니다.

이것을 변경하는 SQL 명령은 무엇입니까 ON DELETE RESTRICT? (하위가있는 경우 부모를 삭제할 수 없음)

답변:


170

이전 질문이지만 도움을받을 수 있도록 답변 추가

2 단계 프로세스 :

A는, 가정 table1외래 키 열 이름 fk_table2_id과, 제약 조건 이름 fk_nametable2키 테이블라고 t2( 내 그림에 아래 같은 것을 ).

   table1 [ fk_table2_id ] --> table2 [t2]

첫 번째 단계 , DROP old CONSTRAINT : ( 참조 )

ALTER TABLE `table1` 
DROP FOREIGN KEY `fk_name`;  

제약 조건이 삭제되고 열이 삭제되지 않습니다.

두 번째 단계 , 새 CONSTRAINT 추가 :

ALTER TABLE `table1`  
ADD CONSTRAINT `fk_name` 
    FOREIGN KEY (`fk_table2_id`) REFERENCES `table2` (`t2`) ON DELETE CASCADE;  

제약 조건 추가, 열이 이미 있습니다.

예:

나는 UserDetails테이블이 테이블을 나타냅니다 Users.

mysql> SHOW CREATE TABLE UserDetails;
:
:
 `User_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`Detail_id`),
  KEY `FK_User_id` (`User_id`),
  CONSTRAINT `FK_User_id` FOREIGN KEY (`User_id`) REFERENCES `Users` (`User_id`)
:
:

첫 번째 단계:

mysql> ALTER TABLE `UserDetails` DROP FOREIGN KEY `FK_User_id`;
Query OK, 1 row affected (0.07 sec)  

두번째 단계:

mysql> ALTER TABLE `UserDetails` ADD CONSTRAINT `FK_User_id` 
    -> FOREIGN KEY (`User_id`) REFERENCES `Users` (`User_id`) ON DELETE CASCADE;
Query OK, 1 row affected (0.02 sec)  

결과:

mysql> SHOW CREATE TABLE UserDetails;
:
:
`User_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`Detail_id`),
  KEY `FK_User_id` (`User_id`),
  CONSTRAINT `FK_User_id` FOREIGN KEY (`User_id`) REFERENCES 
                                       `Users` (`User_id`) ON DELETE CASCADE
:

2
추가하는 제약 조건이 원래 질문에서 요청한대로 ON DELETE RESTRICT이어야하지 않습니까?
Noumenon

Ehm, "on delete cascade"란 무엇이며 왜 필요한가요?
Lealo

3
@Noumenon RESTRICT가 기본값이므로 지정하지 않을 때 얻을 수 있습니다.
edruid

1
@Lealo "on delete cascade"는 상위 테이블 (이 경우 사용자)에서 행을 삭제하면 하위 테이블 (UserDetails)에서 참조하는 모든 행도 삭제됨을 의미합니다.
edruid

1
"통지 제약, 열이 삭제되지 않습니다 삭제"음, 감사,이 변경 실질적으로 유지되는 것을 의미 데이터 만 스키마를 추측 "제약 조건을 추가하면, 열이 이미 있습니다"
조지 Birbilis

21

이름을 변경하려는 경우 하나의 쿼리로이 작업을 수행 할 수 있습니다 .

ALTER TABLE table_name
  DROP FOREIGN KEY `fk_name`,
  ADD CONSTRAINT `fk_name2` FOREIGN KEY (`remote_id`)
    REFERENCES `other_table` (`id`)
    ON DELETE CASCADE;

이는 큰 테이블이있는 경우 다운 타임을 최소화하는 데 유용합니다.


12
ALTER TABLE DROP FOREIGN KEY fk_name;
ALTER TABLE ADD FOREIGN KEY fk_name(fk_cols)
            REFERENCES tbl_name(pk_names) ON DELETE RESTRICT;

2
나 솔루션 찾기 도왔다 ALTER TABLE table_name ADD...ON DELETE RESTRICT
Moak

3
아니요, fk_name은 제약 조건 이름입니다. 제공하는 것은 선택 사항입니다. 잘 모르겠지만 SHOW CREATE TABLE.
pascal

1
ON CASCADE RESTRICT는 아마도 의도하지 않았을 것입니다.
jgreep

5

MySQL은 외래 키를 삭제 한 후 열에 간단한 인덱스를 유지합니다. 따라서 '참조'열을 변경해야하는 경우 3 단계로 변경해야합니다.

  • 원래 FK 드롭
  • 인덱스 삭제 (이전 fk 이름, using drop index절)
  • 새로운 FK 생성

3

하나의 쿼리를 사용하여 모두를 규칙으로 지정할 수 있습니다. ALTER TABLE products DROP FOREIGN KEY oldConstraintName, ADD FOREIGN KEY (product_id, category_id) REFERENCES externalTableName (foreign_key_name, another_one_makes_composite_key) ON DELETE CASCADE ON UPDATE CASCADE


1
(자동 생성 된 이름을 사용하는 것은 아마 MySQL은 항상 독특한 사람을 만들어 추측, 작동 경우) 제한 조건 이름을 변경 한 경우에만 작동합니다
조지 Birbilis

쿼리는 MySQL / MariaDB에서 확실히 작동합니다. 여기서 핵심은 라인 (2)에서 수행되고 그것의 이름으로 된 제약 조건을 삭제하는 것입니다
stamster

1
올인원 쿼리 구문이 MySQL에서 사용 된 경우 명시 적 제약 조건 이름이 작동하지 않았습니다
George Birbilis

3

변경해야 할 FK가 많았 기 때문에 설명을 작성하기 위해 무언가를 썼습니다. 내가 공유 할 생각 :

SELECT

CONCAT('ALTER TABLE `' ,rc.TABLE_NAME,
    '` DROP FOREIGN KEY `' ,rc.CONSTRAINT_NAME,'`;')
, CONCAT('ALTER TABLE `' ,rc.TABLE_NAME,
    '` ADD CONSTRAINT `' ,rc.CONSTRAINT_NAME ,'` FOREIGN KEY (`',kcu.COLUMN_NAME,
    '`) REFERENCES `',kcu.REFERENCED_TABLE_NAME,'` (`',kcu.REFERENCED_COLUMN_NAME,'`) ON DELETE CASCADE;')

FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
    ON kcu.TABLE_SCHEMA = rc.CONSTRAINT_SCHEMA
    AND kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
WHERE DELETE_RULE = 'NO ACTION'
AND rc.CONSTRAINT_SCHEMA = 'foo'

1
제약 조건이 여러 열에있는 경우 작동하지 않습니다. 생성 된 SQL은 각 열에 대해 별도의 제약 조건을 만들 것입니다

나는 그 가능성에 대해 많은 생각을하지 그래서 내 FKS 모두는 하나의 열을했지만, 좋은 생각
DavidSM
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.