MySQL은 외래 키 제약 조건을 만들 수 없습니다.


84

mysql 데이터베이스의 기존 테이블에 대한 외래 키를 만드는 데 문제가 있습니다.

나는 테이블이있다 exp:

+-------------+------------------+------+-----+---------+-------+
| Field       | Type             | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| EID         | varchar(45)      | NO   | PRI | NULL    |       |
| Comment     | text             | YES  |     | NULL    |       |
| Initials    | varchar(255)     | NO   |     | NULL    |       |
| ExpDate     | date             | NO   |     | NULL    |       |
| InsertDate  | date             | NO   |     | NULL    |       |
| inserted_by | int(11) unsigned | YES  | MUL | NULL    |       |
+-------------+------------------+------+-----+---------+-------+

sample_df다음을 사용하여 이것을 참조 하는 새 테이블을 만들고 싶지 않습니다 .

CREATE TABLE sample_df (
df_id mediumint(5) unsigned AUTO_INCREMENT primary key,
sample_type mediumint(5) unsigned NOT NULL,
df_10 BOOLEAN NOT NULL,
df_100 BOOLEAN NOT NULL,
df_1000 BOOLEAN NOT NULL,
df_above_1000 BOOLEAN NOT NULL,
target INT(11) unsigned NOT NULL,
assay MEDIUMINT(5) unsigned zerofill NOT NULL,
insert_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
inserted_by INT(11) unsigned NOT NULL,
initials varchar(255),
experiment VARCHAR(45),
CONSTRAINT FOREIGN KEY (inserted_by) REFERENCES user (iduser),
CONSTRAINT FOREIGN KEY (target) REFERENCES protein (PID),
CONSTRAINT FOREIGN KEY (sample_type) REFERENCES sample_type (ID),
CONSTRAINT FOREIGN KEY (assay) REFERENCES assays (AID),
CONSTRAINT FOREIGN KEY (experiment) REFERENCES exp (EID)
);

하지만 오류가 발생합니다.

ERROR 1215 (HY000): Cannot add foreign key constraint

더 많은 정보를 얻으려면 다음을 수행했습니다.

SHOW ENGINE INNODB STATUS\G

내가 얻은 :

FOREIGN KEY (experiment) REFERENCES exp (EID)
):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.

나에게 열 유형은 둘 다 varchar (45)이기 때문에 일치하는 것 같습니다. (또한 experiment열을 null이 아닌 것으로 설정하려고 시도 했지만 이것이 수정되지 않았습니다) 그래서 문제는 Cannot find an index in the referenced table where the referenced columns appear as the first columns. 그러나 이것이 무엇을 의미하는지 또는 어떻게 확인 / 고정하는지 잘 모르겠습니다. 누구에게 제안이 있습니까? 그리고 무엇을 의미 first columns합니까?


11
대답이나 질문의 ​​어느 곳에서도 문자 집합의 차이로 인해이 오류가 발생할 수 있음을 알 수 없었습니다. 고마워 .. 건배 !!!
proprius

3
또한 열 데이터 정렬을 다시 확인하십시오. 테이블은 utf8mb4 일 수 있지만 열은 다른 데이터 정렬을 가질 수 있습니다!
Watson

제 경우에는 @Watson charset이지만 당신은 나를 생각하게 만드는 것에 대해 내 찬성표를 얻습니다.
user2910265

답변:


153

가능한 원인의 혼합에 이것을 던져서 참조 테이블 열이 동일한 "유형"을 가지지 만 동일한 서명이 없을 때이 문제를 만났습니다.

필자의 경우 참조 된 테이블 열은 TINYINT UNSIGNED이고 참조하는 테이블 열은 TINYINT SIGNED입니다. 두 열을 모두 정렬하면 문제가 해결되었습니다.


1
@ austen-hoogen이 제안한 솔루션으로 내 문제가 해결되었습니다. 그러나 낮은 평판 점수로 인해 그의 솔루션에 대해 투표하고 의견을 제시 할 수 없습니다. 제 경우에는 기본 키가 정수, 자동 증분 및 서명되지 않았습니다. 그러나 외래 키 (참조 테이블 열)는 서명 된 유형입니다. 서명되지 않은 상태로 변경하고 관계를 성공적으로 만들 수 있습니다.
Bal Singh

예, 같은 문제를 겪었습니다. 내 기본 키는 BIGINT (20)이고 다른 테이블에서 참조 된 키는 INT (10) 서명되지 않았습니다. 모두 일치하는지 확인해야합니다. 즉. BIGINT (20), 참조 테이블에서도 BIGINT (20)
Manjunath Reddy

감사합니다! 이 솔루션은 내 문제도 해결했습니다! 내가 가지고 int내가 두 번째 테이블의 외래 키와 BIGINT를 설정하기 위해 기획 된 표에.
Aleksej_Shherbak

36

이 오류는 참조 테이블과 현재 테이블에 동일한 문자 집합이없는 경우에도 발생할 수 있습니다.


3
설정 한 후 문자 집합 으로 latin참조 된 테이블에서 그때 3 시간 후 다시 숨을 시작했다.
Abhishek Kamal

24

http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html 에 따르면

MySQL은 외래 키 확인이 빠르고 테이블 스캔이 필요하지 않도록 외래 키와 참조 된 키에 대한 인덱스가 필요합니다. 참조 테이블에는 외래 키 열이 동일한 순서의 첫 번째 열로 나열되는 인덱스가 있어야합니다.

InnoDB는 외부 키가 인덱스 열 또는 열 그룹을 참조하도록 허용합니다. 그러나 참조 된 테이블에는 참조 된 열이 동일한 순서의 첫 번째 열로 나열되는 인덱스가 있어야합니다.

따라서 참조 된 테이블에 인덱스가 존재하고 여러 컬럼으로 구성되어 있고 원하는 컬럼이 첫 번째가 아닌 경우 오류가 발생합니다.

오류의 원인은 다음 규칙을 위반했기 때문입니다.

외래 키와 참조 된 키의 해당 열은 유사한 데이터 유형을 가져야합니다. 정수 유형의 크기와 부호는 동일해야합니다. 문자열 유형의 길이가 같을 필요는 없습니다. 2 진이 아닌 (문자) 문자열 열의 경우 문자 세트와 데이터 정렬이 동일해야합니다.


19

@Anton에서 언급했듯이 이것은 데이터 유형이 다르기 때문일 수 있습니다. 제 경우에는 기본 키 BIGINT (20)이 있고 INT (10)로 foreight 키를 설정하려고했습니다.


2
감사합니다! INT (11)과 함께 INT (11)을 INT (11)과 함께 사용했지만 하나는 기본 키이므로 서명되지 않은 반면 다른 하나는 서명 된 비슷한 문제입니다!
마이클 스캇 커스버트

@MichaelScottCuthbert Same
Germa Vinsmoke


6

내 것은 참조 된 테이블과 생성 될 테이블 간의 데이터 정렬 문제 였기 때문에 참조하는 키의 데이터 정렬 유형을 명시 적으로 설정해야했습니다.

  • 먼저 데이터 정렬 유형을 가져 오기 위해 참조 된 테이블에서 쿼리를 실행했습니다.
show table STATUS like '<table_name_here>';
  • 그런 다음 데이터 정렬 유형을 복사하고 생성 쿼리에서 employee_id의 데이터 정렬 유형을 명시 적으로 지정했습니다. 제 경우에는 utf8_general_ci 였습니다.
CREATE TABLE dbo.sample_db
(
  id INT PRIMARY KEY AUTO_INCREMENT,
  event_id INT SIGNED NOT NULL,
  employee_id varchar(45) COLLATE utf8_general_ci NOT NULL,
  event_date_time DATETIME,
  CONSTRAINT sample_db_event_event_id_fk FOREIGN KEY (event_id) REFERENCES event (event_id),
  CONSTRAINT sample_db_employee_employee_id_fk FOREIGN KEY (employee_id) REFERENCES employee (employee_id)
);

2

기본 키 의 정확한 순서도 사이에 추가 열없이 일치해야합니다.

순서가 실제로 일치 하는 기본 키 설정이 있었지만 문제는 기본 키에 참조 테이블의 외래 키의 일부가 아닌 추가 열이 있다는 것입니다.

예) 표 2, 열 (a, b, c)-> 표 1, 열 (a, b, d, c)-THIS FAILS

동일한 순서로 정렬 될뿐만 아니라 중간에 추가 열이 없도록 기본 키 열의 순서를 변경해야했습니다.

예) 표 2, 열 (a, b, c)-> 표 1, 열 (a, b, c, d)-이 성공


2

어떤 경우에는 참조 된 필드를 기본 키로 정의하는 것 외에도 고유하게 만들어야했습니다.

그러나 나는 그것을 고유하다고 정의하지 않는 것이 모든 경우에 문제를 일으키지 않는다는 것을 발견했습니다. 그래도 시나리오를 파악할 수 없었습니다. 아마도 nullable 정의와 관련이 있습니다.


FK 소개 또는 설명서를 읽었습니까? FK는 UNIQUE를 참조합니다. PK는 UNIQUE NOT NULL을 의미합니다.
philipxy

2

제 경우 에는 id에 정수 를 사용하여 생성되었으며 참조 테이블은 기본적으로 bigint를 사용하여 외래 키를 생성했습니다 .

이로 인해 마이그레이션이 실패했지만 필드가 실제로 DB에서 생성 되었기 때문에 Rails 앱에서 큰 악몽을 일으켰으므로 DB에는 표시되었지만 Rails 앱의 스키마에는 표시되지 않았습니다.


1

동일한 제약 조건에서 동일한 열을 두 번 이상 참조하면이 Cannot find an index in the referenced table오류가 발생하지만 큰 테이블에서 발견하기 어려울 수 있습니다. 제약 조건을 분할하면 예상대로 작동합니다.


1

이 오류도 발생했습니다. 나에게 해당되는 답변이 없습니다. 필자의 경우 GUI는 기본 고유 식별자가 "unassigned"인 테이블을 자동으로 생성합니다. 외래 키를 만들려고 할 때 실패하고 똑같은 오류가 발생합니다. 내 기본 키를 할당해야합니다.

SQL 자체를 그렇게 작성하면 id int unique auto_increment이 문제가 없지만 어떤 이유로 내 GUI가 대신 이것을 수행합니다 id int unassigned unique auto_increment.

이것이 다른 사람에게 도움이되기를 바랍니다.


1

나에게 그것은 DB의 문자 집합과 데이터 정렬이었습니다. 나는 utf8_unicode_ci로 변경하고 작동합니다.


1
현재 문자셋 / 콜 레이션을 확인하는 방법에 대한 예를 포함 할 수 있습니까?
thelr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.