기존 테이블에 외래 키 추가


324

"katalog"라는 테이블에 외래 키를 추가하고 싶습니다.

ALTER TABLE katalog 
ADD CONSTRAINT `fk_katalog_sprache` 
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

이 작업을 시도하면 다음 오류 메시지가 나타납니다.

Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)

INNODB 상태 오류 :

120405 14:02:57 mytable 테이블의 외래 키 제약 조건에서 오류가 발생했습니다.

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL

이 쿼리를 사용하면 작동하지만 잘못된 "삭제시"작업이 발생합니다.

ALTER TABLE `katalog` 
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )

두 테이블 모두 InnoDB이고 두 필드 모두 "INT (11) not null"입니다. MySQL 5.1.61을 사용하고 있습니다. MacBook Pro에서 MySQL Workbench (최신)로이 ALTER Query를 실행하려고합니다.

테이블 작성 명령문 :

CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
 ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$

CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
 `Bezeichnung` varchar(45) NOT NULL,
 PRIMARY KEY (`ID`),
 UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

1
의 출력을 게시하지 않았기 때문에 SHOW CREATE TABLE질문 만 할 수 있지만 열 이름은 실제로 ID입니까, 대문자입니까?
NB

글쎄, 지금은 더 쉽게 발견 할 수 katalog있습니다 int(11) unsigned. sprache이없는 usigned, 따라서 두 개의 열이 동일하지, 부분.
NB

두 기본 필드 모두 동일한 데이터 유형이어야합니까?
frgtv10 April

2
이것은 디자인의 문제입니다. 먼저 auto_increment나쁜 두 개의 열을 참조하고 있습니다 . 또한 MySQL 매뉴얼은 다음과 같이 말합니다 Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.. 따라서, 유사한 데이터 유형과 동일한 부호입니다.
NB

2
두 개의 auto_increment 필드를 참조하지 않습니다. katalog.Sprache (자동 아님)-> sprache.ID (자동)
frgtv10

답변:


560

기존 테이블 (사용자)에 외래 키 (grade_id)를 추가하려면 다음 단계를 수행하십시오.

ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

12
이유는 이해하고 기억하는 데 도움이됩니다. 서명되지 않은 필드에 외래 키를 추가 할 수 없기 때문입니다. 맞습니까?
PixMach

8
@PixMach, 대답은 아니오입니다. 정수를 외래 키로 부호를 가질 수 있습니다. NB가 질문에 언급했듯이 필드의 유형과 부호가 일치해야합니다. 따라서 검색 테이블의 기본 키가 UNSIGNED이면 외래 키 필드도 UNSIGNED 여야합니다. 기본 키 필드가 SIGNED이면 외래 키 필드도 서명해야합니다. 한 테이블의 열이 SHOW CREATE TABLE에서 정의 된대로, 다른 테이블에서 동일한 정의를 가져야합니다.
Ben Keene

1
이 작업은 단일 쿼리로 수행 할 수도 있습니다 (실패 등의 경우 더 좋을 수 있음)
Stijn de Witt

6
"SET FOREIGN_KEY_CHECKS = 0;"을 실행해야했습니다. ADD CONSTRAINT 명령을 실행하기 전에 SQL에서 "자식 행을 추가하거나 업데이트 할 수 없습니다. 외래 키 제약 조건이 실패합니다"라는 메시지가 표시됩니다.
Erin Geyer

2
하지 그냥 "SET의 FOREIGN_KEY_CHECKS = 0;"실행 "외래 키 제약 조건 실패"오류가 발생하면 수정해야하는 잘못된 데이터가 있거나 그렇지 않으면 더 큰 문제가 발생할 수 있습니다.
MazeChaZer 2016 년

72

이 쿼리를 간단히 사용하면 시나리오에 따라 시도해 보았으며 제대로 작동합니다.

ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);

25

간단한 단계 ...

ALTER TABLE t_name1 ADD FOREIGN KEY (column_name) REFERENCES t_name2(column_name)

15

이 링크를 확인하십시오. 그것은 errno 150에 도움이되었습니다 : http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

내 머리 위에 두 가지가 떠오른다.

  • 외래 키 인덱스가 전체 데이터베이스에서 고유 한 이름입니까 (목록의 # 3)?
  • 업데이트시 테이블 PK를 NULL로 설정하려고합니까 (목록의 # 5)?

나는 문제가 업데이트시 NULL로 설정되어 있다고 추측하고있다.

편집 : 원래 게시물에 대한 의견을 놓쳤습니다. 부호없는 / 부호없는 int 열은 귀하의 사례를 해결할 수 있습니다. 내 링크가 미래의 누군가를 도울 수 있기를 바랍니다.


13
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

그러나 테이블에는 다음이 있습니다.

CREATE TABLE `katalog` (
`Sprache` int(11) NOT NULL,

그것은 어차피 이 NOT NULL로 정의되어 있기 때문에 NULL로 컬럼 Sprache을 설정합니다.


5

MySQL은 다음 쿼리를 실행합니다 :

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

건배!


5

어떻게 고치는 지 Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

  1. 테이블을 변경하고 인덱스를 추가하십시오.

    ALTER TABLE users ADD INDEX index_name (index_column)
  2. 이제 구속 조건을 추가하십시오

    ALTER TABLE foreign_key_table
    ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
    REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
    ON UPDATE CASCADE;

색인을 추가하지 않으면 작동하지 않습니다.

약 6 시간 동안 싸우고 나서 나는 이것이 영혼을 구하기를 희망하는 해결책을 생각해 냈습니다.


4

ALTER TABLE을 사용하여 테이블에 외래 키 제약 조건을 추가 할 때는 필요한 인덱스를 먼저 만들어야합니다.

  1. 인덱스 생성
  2. 테이블 변경

둘 다에 대한 색인을 만들었습니다. 실행하려고하면 이전과 동일한 오류 메시지가 나타납니다. "업데이트시 삭제"부분을 거부하면 작동하지만 잘못된 "삭제시"조치가 발생합니다.;)
frgtv10

@ frgtv10은 테이블 데이터가 "삭제시"와 충돌 할 가능성이 높습니다.
Maksym Polshcha

3

한 번의 쿼리로 모두 시도

  ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
      ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

0

이것은 기본적으로 테이블이 두 개의 다른 문자 세트에 있기 때문에 발생합니다. 예를 들어 charset = utf-8에서 작성된 하나의 테이블과 CHARSET = latin1에 다른 테이블이 작성되므로 이러한 테이블에 foriegn 키를 추가 할 수 있습니다. 두 테이블에서 동일한 문자 집합을 사용하면 foriegn 키를 추가 할 수 있습니다. 오류 1005 foriegn 키 제약 조건이 잘못 형성되면이 문제를 해결할 수 있습니다.


0

나는 같은 문제를 겪었다. 필자의 경우 테이블에 이미 데이터가 있고이 테이블에 참조 테이블에없는 키가 있습니다. 그래서 제약 조건을 무시하고 모든 것이 작동하는이 행을 삭제해야했습니다.


0

1 단계 :이 스크립트 실행

SET FOREIGN_KEY_CHECKS=0;

2 단계 : 열 추가

ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL

3 단계 : 추가 된 열에 외래 키 추가

ALTER TABLE mileage_unit
ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);

4 단계 :이 스크립트 실행

SET FOREIGN_KEY_CHECKS=1;

-1
 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)

예:-

ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)

1
다른 사람들이 배울 수 있도록 코드에 설명을 추가하십시오
Nico Haase
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.