itsource

MySQL 외부 키를 사용하여 테이블을 만드는 중 오류 없음: 150

mycopycode 2022. 9. 17. 10:00
반응형

MySQL 외부 키를 사용하여 테이블을 만드는 중 오류 없음: 150

2개의 외부 키를 사용하여 MySQL에서 테이블을 작성하려고 합니다.이러한 키는 다른 2개의 테이블의 프라이머리 키를 참조합니다만, 에러 150 에러가 표시되어 테이블이 작성되지 않습니다.

3개의 테이블 모두에 대한 SQL은 다음과 같습니다.

CREATE TABLE role_groups (
  `role_group_id` int(11) NOT NULL `AUTO_INCREMENT`,
  `name` varchar(20),
  `description` varchar(200),
  PRIMARY KEY (`role_group_id`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `roles` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50),
  `description` varchar(200),
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB;

create table role_map (
  `role_map_id` int not null `auto_increment`,
  `role_id` int not null,
  `role_group_id` int not null,
  primary key(`role_map_id`),
  foreign key(`role_id`) references roles(`role_id`),
  foreign key(`role_group_id`) references role_groups(`role_group_id`)
) engine=InnoDB;

어떤 도움이라도 주시면 감사하겠습니다.

★★★★★★★★★★★★★에서도 같은 문제가 있었습니다.ALTER TABLE ADD FOREIGN KEY.

1시간 후, 에러 150이 발생하지 않게 하려면 , 다음의 조건을 만족할 필요가 있는 것을 알았습니다.

  1. 부모 테이블을 참조할 외부 키를 정의하기 전에 부모 테이블이 존재해야 합니다.테이블을 올바른 순서로 정의해야 합니다.먼저 부모 테이블, 다음으로 자녀 테이블입니다. FK한 후 두 번째 한 후 을 첫 .ALTER TABLE

  2. 외부 키 즉 외부 키 제약 조건을 .ENGINE=InnoDB다른 스토리지 엔진은 외부 키 정의를 자동으로 무시하므로 오류나 경고를 반환하지 않지만 FK 제약 조건은 저장되지 않습니다.

  3. 부모 테이블에서 참조되는 열은 키의 맨 왼쪽 열이어야 합니다.부모 키가 다음과 같은 경우에 최적입니다.PRIMARY KEY ★★★★★★★★★★★★★★★★★」UNIQUE KEY.

  4. FK 정의는 PK 정의와 동일한 순서로 PK 열을 참조해야 합니다.를 들어 FK가 FK일 경우REFERENCES Parent(a,b,c)부모의 를 "PK"의 는 안 .(a,c,b).

  5. 상위 테이블의 PK 열은 하위 테이블의 FK 열과 동일한 데이터 유형이어야 합니다.를 들어 의 [PK]이 [PK]인 UNSIGNED, 「」를 정의해 UNSIGNED[아이테이블] 아이테이블입니다.

    예외: 문자열 길이가 다를 수 있습니다.를 들어, 「」라고 하는 것은,VARCHAR(10)할 수 있다VARCHAR(20)또는 그 반대도 마찬가지입니다.

  6. 문자열 형식의 FK 열은 대응하는 PK 열과 동일한 문자 집합 및 조회를 가져야 합니다.

  7. 하위 테이블에 데이터가 이미 있는 경우 FK 열의 모든 값이 상위 테이블 PK 열의 값과 일치해야 합니다.다음과 같은 쿼리를 사용하여 이를 확인합니다.

    SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
    WHERE Parent.PK IS NULL;
    

    일치하지 않는 값이 0개 반환되어야 합니다.이 쿼리는 일반적인 예이므로 테이블 이름과 열 이름을 대체해야 합니다.

  8. [ ]도 [도 [Child]테이블은 할 수 없습니다.TEMPORARYtable.syslog를 클릭합니다.

  9. [ ]도 [도 [Child]테이블은 할 수 없습니다.PARTITIONEDtable.syslog를 클릭합니다.

  10. 「FK」를해 FK를 선언했을 .ON DELETE SET NULLFK NULL입니다.

  11. 외부 키의 제약 조건 이름을 선언하는 경우 제약 조건이 정의된 테이블뿐만 아니라 스키마 전체에서 제약 조건 이름이 고유해야 합니다.두 테이블은 동일한 이름의 자체 제약 조건을 가질 수 없습니다.

  12. 새로운 FK를 작성하려고 하는 것과 같은 필드를 가리키는 다른 테이블에 다른 FK가 있으며, 이러한 FK의 형식이 잘못된 경우(즉, 다른 대조) 먼저 일관성을 유지해야 합니다.은 과거의 것일 수 있습니다.SET FOREIGN_KEY_CHECKS = 0;실수로 정의된 일관되지 않은 관계와 함께 사용되었습니다.이러한 FK의 문제를 특정하는 방법에 대해서는, 다음의 @andrewdotn의 회답을 참조해 주세요.

이게 도움이 됐으면 좋겠다.

MySQL의 일반 "errno 150" 메시지는 "외부제약 조건이 올바르게 형성되지 않았음을 의미합니다."이 페이지를 읽고 있는 경우는, 일반적인 「errno: 150」의 에러 메세지는 도움이 되지 않습니다.단,

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

예를 들어, 외부 키 제약 조건을 작성하려고 합니다.

CREATE TABLE t1
(id INTEGER);

CREATE TABLE t2
(t1_id INTEGER,
 CONSTRAINT FOREIGN KEY (t1_id) REFERENCES t1 (id));

가 가 발생하다Can't create table 'test.t2' (errno: 150)그것은 그것이 외국어 키 문제라는 것 외에는 아무에게도 도움이 되지 않는다. 도망쳐라SHOW ENGINE INNODB STATUS;이렇게 써있겠죠.

------------------------
LATEST FOREIGN KEY ERROR
------------------------
130811 23:36:38 Error in foreign key constraint of table test/t2:
FOREIGN KEY (t1_id) REFERENCES t1 (id)):
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.

인덱스를 찾을 수 없다는 것이 문제라고 합니다. SHOW INDEX FROM t1테이블에 대한 인덱스가 전혀 없음을 나타냅니다.t1프라이머리 키를 정의하는 것으로, 예를 들면t1외부 키 제약이 정상적으로 작성됩니다.

구속조건으로 링크하려는 두 필드의 속성이 완전히 동일한지 확인하십시오.

ID 열에 있는 '서명되지 않은' 속성이 눈에 띄기도 합니다.

ALTER TABLE `dbname`.`tablename` CHANGE `fieldname` `fieldname` int(10) UNSIGNED NULL;

이 스크립트를 실행할 때 데이터베이스의 현재 상태는 어떻습니까?완전히 비어있나요?데이터베이스를 처음부터 작성할 때는 SQL이 정상적으로 실행되지만 일반적으로 errno 150은 외부 키의 일부인 테이블을 삭제하고 다시 작성하는 것과 관련이 있습니다.100% 최신 데이터베이스로 작업하지 않는 것 같아요.

SQL 파일을 "소스"할 때 오류가 발생하면 "소스" 명령어 직후 MySQL 프롬프트에서 "SHOW ENGINE INNODB STATUS" 명령을 실행하여 보다 자세한 오류 정보를 볼 수 있습니다.

수동 엔트리를 체크할 수도 있습니다.

삭제한 테이블을 다시 작성할 경우 해당 테이블을 참조하는 외부 키 제약 조건에 적합한 정의가 있어야 합니다.앞서 설명한 바와 같이 올바른 열 이름과 유형을 가져야 하며 참조된 키에 인덱스가 있어야 합니다.이것이 충족되지 않으면 MySQL은 오류 번호 1005를 반환하고 오류 메시지에서 오류 150을 참조합니다.MySQL이 CREATE TABLE 문에서 오류 번호 1005를 보고하고 오류 메시지가 오류 150을 나타내는 경우 외부 키 제약 조건이 올바르게 형성되지 않았기 때문에 테이블을 생성하지 못했습니다.

- MySQL 5.1 레퍼런스 매뉴얼.

같은 문제를 안고 이 스레드를 보고 있는 사용자의 경우:

이런 오류가 발생하는 데는 여러 가지 이유가 있습니다.MySQL에서의 외부 키 오류의 원인과 해결 방법에 대한 자세한 목록은 다음 링크를 참조하십시오.

MySQL 외부 키 오류 및 오류 번호 150

Google을 통해 SO 항목을 찾은 다른 사용자:"NOT NULL"로 정의된 외부 키(to be) 열에서 SET NULL 액션을 수행하지 마십시오.엔진 INNODB 상태를 확인할 때까지 큰 좌절감을 주었습니다.

물론 그렇지 않지만 나는 이 실수가 꽤 흔하고 눈에 띄지 않는다는 것을 알았다.의 타겟FOREIGN KEY할 수 없다PRIMARY KEY도움이 되는 답변은 다음과 같습니다.

외부 키는 항상 다른 테이블의 Primary KEY True 필드를 가리켜야 합니다.

CREATE TABLE users(
   id INT AUTO_INCREMENT PRIMARY KEY,
   username VARCHAR(40));

CREATE TABLE userroles(
   id INT AUTO_INCREMENT PRIMARY KEY,
   user_id INT NOT NULL,
   FOREIGN KEY(user_id) REFERENCES users(id));

@andrewdotn이 지적한 것처럼 가장 좋은 방법은 자세한 오류를 확인하는 것입니다.SHOW ENGINE INNODB STATUS;에러 코드 뿐만이 아닙니다.

그 이유 중 하나는 같은 이름의 인덱스가 이미 존재하거나 다른 테이블에 있는 것일 수 있습니다.이러한 충돌을 피하기 위해 인덱스 이름 앞에 테이블 이름을 접두사로 붙이는 것이 좋습니다.idx_userId사용하다idx_userActionMapping_userId.

우선 확인 부탁드립니다.

  1. InnoDB 테이블을 사용하고 있습니다.
  2. FORENAL KEY 필드의 유형 및 길이(!)는 소스 필드와 동일합니다.

저도 같은 문제가 있어서 해결했어요.한 필드에는 부호 없는 INT가 있고 다른 필드에는 정수만 있습니다.

유용한 힌트, 사용SHOW WARNINGS;시험해 본 후에CREATEquery 에러가 표시되며 보다 자세한 경고가 표시됩니다.

    ---------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                                                                                                                 |
+---------+------+--------------------------------------------------------------------------                          --------------------------------------------------------------------------------------------                          ---------------+
| Warning |  150 | Create table 'fakeDatabase/exampleTable' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.
|
| Error   | 1005 | Can't create table 'exampleTable' (errno:150)                                                                                                                                                                           |
+---------+------+--------------------------------------------------------------------------                          --------------------------------------------------------------------------------------------                          ---------------+

이 경우 테이블을 다시 만들어야 합니다!

일반적으로 이 문제는 파일을 기존 데이터베이스로 소싱하려고 할 때 발생합니다.먼저 모든 테이블(또는 DB 자체)을 삭제합니다.그런 다음 파일 소스:SET foreign_key_checks = 0;처음에 그리고SET foreign_key_checks = 1;마지막에.

이게 실패하는 또 다른 이유를 찾았어요대소문자를 구분하는 테이블 이름.

이 테이블 정의의 경우

CREATE TABLE user (
  userId int PRIMARY KEY AUTO_INCREMENT,
  username varchar(30) NOT NULL
) ENGINE=InnoDB;

이 테이블 정의는 기능합니다.

CREATE TABLE product (
  id int PRIMARY KEY AUTO_INCREMENT,
  userId int,
  FOREIGN KEY fkProductUser1(userId) REFERENCES **u**ser(userId)
) ENGINE=InnoDB;

반면에 이번 것은 실패한다

CREATE TABLE product (
  id int PRIMARY KEY AUTO_INCREMENT,
  userId int,
  FOREIGN KEY fkProductUser1(userId) REFERENCES User(userId)
) ENGINE=InnoDB;

Windows에서 작동했지만 Unix에서 실패했다는 사실을 깨닫는 데 몇 시간이 걸렸습니다.그게 다른 사람에게 도움이 됐으면 좋겠어요.

Mac OS용 MySQL Workbench 6.3.

문제: DB 다이어그램에서 Forward Engineering을 실행하려고 할 때 테이블 X의 오류 번호150이 성공, 21개 중 20개가 실패.테이블 X의 FK가 삭제된 경우 오류는 이전에 실패하지 않았던 다른 테이블로 이동했습니다.

모든 테이블 엔진을 my로 변경.ISAM 그리고 그것은 잘 작동했다.

enter image description here

또한 실수로 잘못된 데이터베이스를 조작하고 있지 않은지 확인할 필요가 있습니다.외부 테이블이 존재하지 않는 경우 이 오류가 발생합니다.MySQL이 왜 이렇게 난해한가요?

외부 키가 부모에서 고유한 것으로 나열되지 않았는지 확인하십시오.저도 같은 문제가 있어서 독특하지 않다고 구분해서 해결했어요.

제 경우, 외국어 키 필드인 필드의 이름이 너무 길었기 때문입니다. foreign key (some_other_table_with_long_name_id)좀 더 짧게 해봐.이 경우 오류 메시지가 약간 오해를 일으킬 수 있습니다.

또한 @John이 앞서 언급했듯이 필드 정의는 동일해야 합니다(주의).unsigned서브타입).

(측면 메모가 너무 커서 코멘트를 할 수 없습니다.)

할 필요가 없다.AUTO_INCREMENTid를 맵핑테이블에서 삭제합니다.

를 변경하다PRIMARY KEY로.(role_id, role_group_id)(어느 순서로든)이렇게 하면 액세스 속도가 빨라집니다.

아마 양쪽 방향을 매핑하고 싶기 때문에,INDEX두 개의 열을 반대 순서로 배열합니다.(만들 필요는 없습니다).UNIQUE.)

기타 힌트 : http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

외부 키 제약 조건이 다음 조건에 기반하는 경우varchartype을 지정하면 대상 열에 의해 제공되는 목록 외에 고유한 제약 조건이 있어야 합니다.

테이블을 작성하기 전에 아래 행을 실행합니다.SET FORNE_KEY_CHECKS = 0;

FORNE_KEY_CHECKS 옵션은 InnoDB 테이블의 외부 키 제약 조건을 확인할지 여부를 지정합니다.

-- 외부 키 제약 조건을 체크하도록 지정합니다(기본값).

SET FOREIGN_KEY_CHECKS = 1;

 

-- 외부 키 제약조건 확인 안 함

SET FORNE_KEY_CHECKS = 0;

사용 시기: 참조 제약 조건을 일시적으로 비활성화(FORNE_KEY_CHECKS를 0으로 설정)하면 테이블을 다시 만들고 데이터를 부모-자녀 순서로 로드해야 할 때 유용합니다.

같은 문제가 발생했지만 부모 테이블이 없는 것을 확인합니다.따라서 하위 마이그레이션 앞에 있는 상위 마이그레이션을 편집하기만 하면 됩니다.그냥 해.

언급URL : https://stackoverflow.com/questions/1457305/mysql-creating-tables-with-foreign-keys-giving-errno-150

반응형