MySQL : 테이블을 생성 할 수 없음 (errno : 150)


156

.sql 파일을 가져 오려고하는데 테이블 생성에 실패합니다.

실패한 쿼리는 다음과 같습니다.

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

동일한 데이터베이스에서 .sql을 내 보냈고 모든 테이블을 삭제하고 가져 오려고하는데 왜 실패합니까?

MySQL : './dbname/data.frm'테이블을 만들 수 없음 (errno : 150)


1
본질적 으로이 오류의 모든 원인에 대해 MySQL에서 errno 150 (및 errno 121 / 기타 외래 키 오류)을 일으키는 원인에 대한 철저한 리소스가 있습니다.
John Smith

21
열이 동일해야합니다 (서명되지 않은 플래그조차도 일치해야 함).
Justin Skiles

3
@JohnSmith ... 어디?
찰스 우드

3
10 가지 가능한 원인을 나열한이 블로그 게시물을 읽는 것이 좋습니다. verysimple.com/2006/10/22/…
Mark Amery

@CharlesWood : " John Smith ... 4 월 6 일 13시 19 분 29 초에 본 것입니다." 이 어리석은 세상이 끝날 때까지 "어디에"의 신비가 드러나지 않을까 염려가 있습니다! :>
trejder

답변:


167

로부터 MySQL을 - FOREIGN KEY 제약 조건 문서 :

삭제 된 테이블을 다시 작성하는 경우 테이블을 참조하는 외래 키 제약 조건을 따르는 정의가 있어야합니다. 올바른 열 이름과 유형이 있어야하며 앞에서 언급 한대로 참조 된 키에 대한 색인이 있어야합니다. 이것들이 만족되지 않으면, MySQL은 오류 1005를 반환하고 오류 메시지에서 오류 150을 참조하는데, 이는 외래 키 제약 조건이 올바르게 형성되지 않았 음을 의미합니다. 마찬가지로 오류 150으로 인해 ALTER TABLE이 실패하면 변경된 테이블에 대해 외래 키 정의가 잘못 형성되었음을 의미합니다.


1
한 테이블의 두 열이 PK 인 다른 테이블의 한 열을 참조 할 수 있습니까?
Eugene

1
@Eugene : 두 열 각각은 다른 테이블의 PK와 외래 키 관계를 가질 수 있습니다. 두 열 모두 단일 외래 키 관계가 아닙니다.
OMG Ponies

1
@OMGPonies!이 질문에 답변 주셔서 감사합니다 .. 내가 찾고 있었다 ... 나는 또한 여기에 질문을 stackoverflow.com/questions/13487010/... 내가 좋은 답변을 가지고 있지만 비록이 준수해야 할 .... Whether its possible to write Nested Query for my problem? .. 나에게도 답변을 부탁드립니다!
Grijesh Chauhan

19
내 오류는 마스터 테이블에 MyISAM과 자식 테이블 InnoDB 엔진이 있다는 것입니다. 현재 create.sql 스크립트는 모든 테이블에 InnoDB를 사용하고 있었지만 첫 스크립트가 MyISAM을 사용하는 아주 오래된 설치가있었습니다.
Whome

2
@Whome-네, 같은 문제가 발생했습니다.
aroth

96

오류 150은 외래 키에 문제가 있음을 의미합니다. 외래 테이블의 키가 정확히 같은 유형이 아닐까요?


15
감사합니다 :) 나를 위해, 데이터 유형은 INT이지만 하나는 서명되지 않은 반면 다른 하나는 그렇지 않습니다
Anh Nguyen

6
스키마 생성기를 사용할 때 BIGINTvs를 자주 INT사용합니다.
Xeoncross

외래 키가 INT 값이 아닌 경우 동일한 문제가 발생했습니다. 외래 키가 참조 할 때 열은 고유해야합니다.
PhatHV

62

실행 SHOW ENGINE INNODB STATUS;LATEST FOREIGN KEY ERROR출력 을 찾아 실제 오류 메시지를 얻을 수 있습니다 .

출처 : 비슷한 질문에 다른 사용자의 답변


7
이것은 실제로 매우 유용합니다. 정확한 오류를 알려줍니다.
Csongor Fagyal

감사. MySQL Workbench가 이것을 사용하지 않는 것은 부끄러운 일입니다.
scipilot

대박. 이것은 매우 도움이됩니다. 정확한 오류를 알려줍니다. 내 칼럼을 NULLABLE로 만들었지 만 "on delete set null"로 설정했습니다. 정말 고맙습니다.
Abhishek Saini

서버에 대한 권한이있는 경우 :(
Christopher Smit

30

데이터 유형이 정확히 일치해야합니다. varchar 유형을 처리하는 경우 테이블은 동일한 데이터 정렬을 사용해야합니다.


4
조합 비트에 감사드립니다.
arahant

25

나는 올바른 대답은 모두 질문으로 오도한다고 생각합니다.

외래 키로 덤프 파일을 복원하는 경우 복원을 시작하기 전에 실제 대답은 다음과 같습니다.

SET FOREIGN_KEY_CHECKS=0;

당연히 외부 테이블이 존재하기 전에 복원이 일부 제한 조건을 작성하기 때문입니다.


이 작업을 수행해도 효과가 없었지만 여전히 오류가 발생합니다. 어떤 아이디어?
Joseph Astrahan

24

관련 테이블간에 엔진이 다른 경우이 오류 메시지가 표시 될 수 있습니다. 예를 들어, 테이블은 InnoDB를 사용하고 다른 테이블은 MyISAM을 사용합니다. 둘 다 같아야합니다


고마워-이것은 내 문제였다.
scipilot

그게 내 문제 였어 감사합니다
thed0ctor

mysqldump를 사용하여 innodb 테이블의 sql 파일을 작성하고 대신 myisam talbes로 내 보낸 경우에 발생할 수 있습니다.
Amado Martinez

11

오류 번호 150은 외래 키 제약 조건 실패를 의미합니다. 외래 키가 의존하는 테이블 (table keywords) 전에이 테이블을 생성하고있을 것입니다 . 해당 테이블을 먼저 작성하면 제대로 작동합니다.

그렇지 않은 경우 외래 키 문을 제거하고 테이블을 만든 후에 추가하십시오. 특정 제약 조건 실패에 대한보다 의미있는 오류 메시지가 나타납니다.


10

errno 150을 유발할 수있는 몇 가지 사항이 있으므로이 주제를 검색하는 사람들을 위해 다음은 철저한 목록에 가까운 것으로 생각되는 것입니다 (출처 : Errno 150 ).

errno 150 또는 errno 121의 경우 SHOW ENGINE INNODB STATUS에 간단히 입력하면 "LATEST FOREIGN KEY ERROR"라는 섹션이 있습니다. 그 아래에는 매우 유용한 오류 메시지가 표시되며 일반적으로 문제가 무엇인지 즉시 알려줍니다. 이를 실행하려면 SUPER 권한이 필요하므로이를 보유하지 않은 경우 다음 시나리오를 테스트하기 만하면됩니다.

1) 데이터 유형이 일치하지 않음 : 열 유형이 같아야합니다

2) 상위 열이 색인화되지 않음 (또는 잘못된 순서로 색인화 됨)

3) 열 데이터 정렬이 일치하지 않습니다

4) NOT NULL 열에 SET NULL 사용

5) 테이블 데이터 정렬이 일치하지 않음 : 일부 데이터 정렬 버전에서는 열 데이터 정렬이 일치하더라도 문제가 될 수 있습니다.

6) 부모 열이 실제로 부모 테이블에 존재하지 않습니다. 철자 검사 (및 열의 시작 또는 끝에 공백)

7) 열 중 하나의 색인 중 하나가 불완전하거나 열이 너무 길어서 완전한 색인을 작성할 수 없습니다. MySQL을 조정하지 않는 한 최대 단일 열 키 길이는 767 바이트입니다 (varchar (255) UTF 열에 해당).

오류 번호가 121 인 경우 다음과 같은 두 가지 원인이 있습니다.

1) 선택한 구속 조건 이름이 이미 사용되었습니다.

2) 명령문 및 테이블 이름에 대소 문자가 다른 경우 일부 시스템에서. 한 대의 서버에서 다른 대 / 소문자 처리 규칙이있는 다른 서버로 갈 경우이 문제가 발생할 수 있습니다.


테이블이 innodb가 아닌 경우 일부 버전에서는 errno 150이 표시되지만 일부 버전에서는 자동으로 실패합니다.
juacala

감사합니다, 이것은 훌륭했습니다 : | ------------------------ | 최신 외래 키 오류 | ------------------------ | 일부 | 열은 NOT NULL로 정의됩니다.
Sam Critchley

8

때때로 MySQL은 매우 어리석은 일입니다. 외래 키의 원인을 이해할 수 있습니다. 그러나 제 경우에는 전체 데이터베이스를 삭제했지만 여전히 오류가 발생합니다. 왜 그렇습니까? 내 말은, 더 이상 데이터베이스가 없습니다 ... 그리고 사용중인 SQL 사용자가 서버의 다른 DB에 액세스 할 수 없습니다 ... 즉, 서버가 현재 사용자에 대해 "비어있다"고 여전히 얻습니다. 이 오류? 죄송하지만 MySQL이 나에게 거짓말을하고 있다고 생각합니다 ...하지만 그것을 다룰 수 있습니다 :) 그냥 당신의 성가신 문장 주위 에이 두 줄의 SQL을 추가하십시오 :

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

이제 SQL을 실행해야합니다 ... 실제로 외래 키 문제가있는 경우 검사를 다시 활성화 할 수있는 줄에 표시됩니다. 이는 실패합니다 ..하지만 내 서버는 조용합니다 :)


실제로 참조하는 열과 열간에 차이가있는 경우 문제가 발생할 수 있습니다. 예를 들어. 참조 된 열이 varchar (200)이고 참조자가 varchar (50)이라고 가정하면 캐스케이드가 시도 될 때 이상한 동작이 발생할 수 있습니다. 데이터 불일치로 인해 errno 150이 발행되는 문제가 발생하지 않았습니다.
juacala

나는이로 실행 할 때마다 재미있는 통찰력 @juacala : 재미 나에게 만, 나의 접근 방식은 항상 ... 그것을 고정되어 오늘까지 적어도 : D하지만 우리는 결코 정지 학습 오른쪽)
jebbie

이것은 실제로 스크립트 liquibase가 생성되는 데 도움이되었습니다. 스크립트는 MySQL> 5.5에서 완벽하게 실행되었지만 버전 5.1에서는 실패했습니다.
delbertooo

4

위의 답변을 검토하고 약간의 실험을 한 후에 이것은 MySQL의 외래 키 오류를 해결하는 효과적인 방법입니다 (1005-오류 150).

외래 키를 올바르게 만들려면 모든 MySQL에서 요청하는 내용은 다음과 같습니다.

  • 참조 된 모든 키에는 PRIMARY 또는 UNIQUE 인덱스가 있어야합니다.
  • 참조 열은 반드시 참조 열과 동일한 데이터 유형을 가져야합니다.

이러한 요구 사항을 충족하면 모든 것이 잘 될 것입니다.


4

Windows 응용 프로그램을 Linux로 이식했을 때이 오류가 발생했습니다. Windows에서 데이터베이스 테이블 이름은 대소 문자를 구분하지 않으며 Linux에서는 파일 시스템 차이로 인해 대소 문자를 구분합니다. 그래서, 윈도우 테이블 Table1과 동일 table1하고있는 REFERENCES모두 table1Table1작동합니다. Linux에서 데이터베이스 구조를 만들 때 table1대신 응용 프로그램을 사용 Table1하면 오류 # 150이 발생했습니다. Table1참조 에서 올바른 대소 문자 를 만들면 Linux에서도 작동하기 시작했습니다. 따라서 다른 도움이 없다면 REFERENCESLinux에서 테이블 이름에 올바른 대소 문자를 사용해야합니다.


이것은 또한 나의 경우였습니다! 대소 문자를 구분하지 않는 (OS X)에서 대소 문자를 구분하는 mysql 버전 (Debian)으로 스크립트 이동
mircealungu

3

테이블의 엔진을 변경하십시오 .innoDB 만 외래 키를 지원합니다


3

PK 테이블이 하나의 CHARSET에 생성 된 다음 다른 CHARSET에 FK 테이블을 생성하면이 오류가 발생할 수 있습니다 ...이 오류가 발생했지만 문자 세트를 PK 문자 세트로 변경 한 후 오류없이 실행되었습니다

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;

3

이 오류는 두 테이블에 참조가있는 경우에 발생할 수 있습니다 (예 : 하나의 테이블은 Student이고 다른 테이블은 Education이며 Education 테이블에 Student 테이블의 외래 키 참조가 필요함). 이 경우 두 테이블의 열 데이터 형식이 같아야합니다. 그렇지 않으면 오류가 발생합니다.


3

대부분의 경우 문제는 ENGINE dIfference 때문입니다. 부모가 InnoDB에 의해 생성되면 참조 된 테이블은 MyISAM에 의해 생성되고 그 반대도 마찬가지입니다.


3

나의 경우에는. 호스팅 서버 변경 설정과 새 테이블이 MyISAM이지만 이전 테이블이 InnoDB이므로 엔진 및 문자 집합에 문제가있었습니다. 그냥 바뀌 었어


내가 만들지 않은 데이터베이스를 변경했기 때문에 이것은 나에게 맞았습니다.
FonzTech

3

일반적으로 외래 키와 기본 키가 일치하지 않으면 오류 : 150이 발생합니다.

외래 키가 동일해야합니다 데이터 형식 은 AS 기본 키를 . 또한 기본 키서명되지 않은 경우 외래 키서명되지 않아야합니다 .


3

나는 같은 문제가 있었다. 테이블의 열 데이터 정렬문자 집합과 관련이 있습니다. 확인 문자 세트데이터 정렬은 두 테이블에 모두 열에 대해 동일해야합니다. 외래 키를 설정하려면. 예-users 테이블의 userID 열을 참조하는 userImage 테이블의 userID 열에 외래 키를 넣은 경우 데이터 정렬 은 테이블의 두 열에 대해 utf8_general_ci 및 문자 세트 utf8 과 같아야합니다 . 일반적으로 테이블을 만들 때 mysql은 서버 설정에서이 두 가지 구성을 가져옵니다.


왜이 포 이스트를 보지 못했습니까!? 근본 원인을 알아내는 데 한 시간을 보냈습니다. 내 경우에는 문자 집합이었습니다. 참조 테이블과 참조 테이블은 동일한 문자 집합을 가져야합니다.
Sujit Joshi

2

기본 키 열과 참조 열의 데이터 유형 및 속성이 동일해야합니다 (부호없는, 이진, 부호없는 0 채우기 등).


2

실제 사례는 MySQL 도구 (내 경우에는 Sequel Pro)를 사용하여 데이터베이스의 이름을 바꾼 곳입니다. 그런 다음 이름이 같은 데이터베이스를 작성했습니다.

이렇게하면 외래 키 제약 조건이 동일한 데이터베이스 이름으로 유지되므로 이름이 바뀐 데이터베이스 (예 : my_db_renamed)는 새로 만든 데이터베이스 (my_db)에 외래 키 제약 조건이있었습니다.

이것이 Sequel Pro의 버그인지 또는 일부 유스 케이스 에이 동작이 필요한지 확실하지 않지만 아침의 가장 좋은 부분은 : /


2

나는 같은 오류가 있었다. 필자의 경우 오류의 원인은 제약 조건에 ON DELETE SET NULL 문이 있었고 정의에 제약 조건을 넣은 필드에 NOT NULL 문이 있었기 때문입니다. 필드에 NULL을 허용하면 문제가 해결되었습니다.


2

텍스트 파일에서 DB를 만드는 동안 이런 종류의 문제에 직면했습니다.

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

방금 위의 줄을 작성 Create.bat하고 bat 파일을 실행했습니다.

내 실수는 내 SQL 파일에서 순서대로 실행됩니다. 기본 키와 외래 키로 테이블을 만들려고했습니다. 실행하는 동안 참조 테이블을 검색하지만 테이블은 없습니다. 따라서 이런 종류의 오류를 반환합니다.

외래 키가있는 테이블을 작성하는 경우 참조 테이블이 있는지 확인하십시오. 또한 참조 테이블 및 필드의 이름을 확인하십시오.


즉, 아직 존재하지 않는 다른 테이블을 가리키는 외래 키가있는 테이블을 만들려고했습니다. 올바른 순서로 테이블을 작성하여 문제점을 해결하십시오.
Vincent

2

비슷한 문제가 있었지만 데이터가있는 기존 테이블에 새 필드를 추가하고 있었고 새 필드가 부모 테이블에서 다른 필드를 참조하고 있었고 NOT NULL의 정의가 있었고 DEFAULT VALUES가 없었기 때문입니다. -작동하지 않는 이유는

  1. 제약 조건을 적용하기 전에 새 필드에서 각 레코드의 부모 테이블 값으로 빈 필드를 자동으로 채워야했습니다. 제약 조건이 적용될 때마다 테이블 데이터의 무결성을 그대로 유지해야합니다. 제약 조건 (외부 키)을 구현했지만 부모 테이블의 값이없는 데이터베이스 레코드가 있었으므로 데이터가 손상되어 MySQL이 제약 조건을 적용하지 않습니다.

데이터베이스를 미리 미리 계획하고 데이터를 삽입하기 전에 제약 조건을 구현 한 경우 정상적인 상황에서는이 특정 시나리오를 피해야합니다.

이 문제를 피하는 가장 쉬운 방법은

  • 데이터베이스 테이블 데이터 저장
  • 테이블 데이터 (및 테이블 아티팩트 (인덱스 등) 자르기)
  • 구속 조건 적용
  • 데이터 가져 오기

나는 이것이 누군가를 돕기를 바랍니다.


1

아마도 이것이 도움이 될까요? 기본 키 열의 정의는 외래 키 열과 정확히 동일해야합니다.


1

모든 테이블이 외래 키를 지원할 수 있는지 확인하십시오-InnoDB 엔진


1

자식 테이블에서 참조하는 PARENT 테이블의 열은 고유해야합니다. 그렇지 않으면 오류 번호 150이 발생합니다.


예를 들어, 특정 컬럼과 테이블 이름 - 아마 비트 당신이에 추가 가치가 더 상세하게 될 것이다
조나단

1

Django mysql 데이터베이스를 단일 테이블로 덤프 할 때 비슷한 문제가 발생했습니다. 데이터베이스를 텍스트 파일로 덤프하고 문제의 테이블을 emacs를 사용하여 파일 끝으로 이동하고 수정 된 sql 덤프 파일을 새 인스턴스로 가져 와서 문제를 해결할 수있었습니다.

HTH 우베


1

변수를 수락하여 문제를 해결했습니다. null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL

1

일련의 MySQL 명령을 실행할 때도 같은 문제가 발생했습니다. 아직 생성되지 않은 다른 테이블을 외래 키를 참조 할 때 테이블을 만드는 동안 광산이 발생합니다. 참조하기 전에 테이블이 존재하는 순서입니다.

해결 방법 : 외래 키가있는 자식 테이블을 만들기 전에 먼저 부모 테이블을 만듭니다.


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