sourcetip

MySQL 외부 키 오류 1005 errno 150 기본 키를 외부 키로 지정

fileupload 2023. 9. 5. 20:42
반응형

MySQL 외부 키 오류 1005 errno 150 기본 키를 외부 키로 지정

저는 MySQL Workbench로 작은 데이터베이스를 만들고 있습니다.저는 "이모빌리"라고 불리는 메인 테이블을 가지고 있는데, 기본 키는 네 개의 열(코무네, 비아, 시빅코, 이모빌리)로 구성되어 있습니다.

또한 기본 키가 동일한 세 개의 다른 테이블(Comune, Via, Civico, Unmobile)도 있지만 이러한 필드는 테이블 이모빌리도 참조합니다.

첫 번째 질문: 외부 키이기도 한 기본 키를 만들 수 있습니까?

두 번째 질문:변경 내용을 내보내려고 하면 다음과 같이 표시됩니다.

Executing SQL script in server

# ERROR: Error 1005: Can't create table 'dbimmobili.condoni' (errno: 150)

CREATE  TABLE IF NOT EXISTS `dbimmobili`.`Condoni` (

  `ComuneImmobile` VARCHAR(50) NOT NULL ,
  `ViaImmobile` VARCHAR(50) NOT NULL ,
  `CivicoImmobile` VARCHAR(5) NOT NULL ,
  `InternoImmobile` VARCHAR(3) NOT NULL ,
  `ProtocolloNumero` VARCHAR(15) NULL ,
  `DataRichiestaSanatoria` DATE NULL ,
  `DataSanatoria` DATE NULL ,
  `SullePartiEsclusive` TINYINT(1) NULL ,
  `SullePartiComuni` TINYINT(1) NULL ,
  `OblazioneInEuro` DOUBLE NULL ,
  `TecnicoOblazione` VARCHAR(45) NULL ,
  `TelefonoTecnico` VARCHAR(15) NULL ,
  INDEX `ComuneImmobile` (`ComuneImmobile` ASC) ,
  INDEX `ViaImmobile` (`ViaImmobile` ASC) ,
  INDEX `CivicoImmobile` (`CivicoImmobile` ASC) ,
  INDEX `InternoImmobile` (`InternoImmobile` ASC) ,

  PRIMARY KEY (`ComuneImmobile`, `ViaImmobile`, `CivicoImmobile`, `InternoImmobile`) ,

  CONSTRAINT `ComuneImmobile`
    FOREIGN KEY (`ComuneImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`ComuneImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `ViaImmobile`
    FOREIGN KEY (`ViaImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`ViaImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `CivicoImmobile`
    FOREIGN KEY (`CivicoImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`CivicoImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `InternoImmobile`
    FOREIGN KEY (`InternoImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`InternoImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE = InnoDB

엔진 상태 표시:

테이블 dbimobili/valutazionimercato의 외부 키 제약 조건에 오류가 있습니다.

참조된 열이 첫 번째 열로 표시되거나 테이블과 참조된 테이블의 열 유형이 제약 조건과 일치하지 않는 참조된 테이블에서 인덱스를 찾을 수 없습니다.>= InnoDB-4.1.12로 생성된 테이블에서 ENUM 및 SET의 내부 저장소 유형이 변경되었으며, 이전 테이블의 해당 열은 새 테이블의 해당 열에서 참조할 수 없습니다.

내가 어디서 잘못하고 있나요?

외부 키 제약 조건을 만들 때 MySQL은 참조 테이블과 참조 테이블 모두에서 사용 가능한 인덱스를 필요로 합니다.참조 테이블의 인덱스는 자동으로 생성되지만 참조 테이블의 인덱스는 수동으로 생성되어야 합니다(소스).당신의 것이 없어진 것 같습니다.

테스트 사례:

CREATE TABLE tbl_a (
    id int PRIMARY KEY,
    some_other_id int,
    value int
) ENGINE=INNODB;
Query OK, 0 rows affected (0.10 sec)

CREATE TABLE tbl_b (
    id int PRIMARY KEY,
    a_id int,
    FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
ERROR 1005 (HY000): Can't create table 'e.tbl_b' (errno: 150)

하지만 만약 우리가 색인을 추가한다면.some_other_id:

CREATE INDEX ix_some_id ON tbl_a (some_other_id);
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

CREATE TABLE tbl_b (
    id int PRIMARY KEY,
    a_id int,
    FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.06 sec)

참조된 필드가 참조된 테이블의 기본 키이고 기본 키가 자동으로 인덱싱되기 때문에 대부분의 상황에서는 문제가 되지 않는 경우가 많습니다.

외부 키의 유형이 이 표에 있는 필드와 정확히 동일한지 다시 확인합니다.예를 들어 둘 다 정수(10) 또는 Varchar(8)여야 하며 문자 수도 마찬가지입니다.

이 게시물이 오래된 게시물이라는 것을 알고 있지만 구글에서 높은 순위를 차지하고 있기 때문에 제 문제에 대해 알아낸 내용을 추가합니다.테이블 유형(예: MyISAM 및 InnoDB)이 혼합된 경우에도 이 오류가 발생합니다.이 경우 InnoDB가 기본 테이블 유형이지만 하나의 테이블은 전체 텍스트 검색이 필요하여 MyISAM으로 마이그레이션되었습니다.이 경우 MyISAM 테이블을 참조하는 InnoDB 테이블에 외부 키를 생성할 수 없습니다.

키가 CHAR/VARCHAR 또는 그런 유형의 키인 경우 다른 데이터 정렬 문제가 발생할 수 있습니다.문자 집합이 동일한지 확인합니다.

저는 이 오류를 가지고 있었고 저의 경우 오류의 원인을 찾았습니다.이 오래된 게시물이 구글에서 꽤 높은 순위를 차지하고 있기 때문에 저는 여전히 이 오래된 게시물에 답하고 있습니다.

링크하려는 두 열의 변수가 모두 정수였지만 int 중 하나가 'unsigned'로 체크되었습니다.제 오류를 수정한 확인을 취소하는 것뿐입니다.

같은 오류가 발생했습니다.저는 메인 테이블에 기본 키를 BIGINT UNSIGNED로 생성하고 두 번째 테이블에 외부 키로 선언하는 솔루션을 발견했습니다.

두 번째 표에서 외래 키를 BIGINT UNSIGHED로 선언했을 때 모든 것이 정상적으로 작동했으며 인덱스를 만들 필요도 없었습니다.

그래서 기본 키와 외부 키 사이의 데이터 유형 불일치였습니다 :)

저도 똑같은 문제가 있었지만, 제 문제에 대한 해결책은 전혀 달랐습니다.데이터베이스 어딘가에 같은 이름의 외래 키가 있었습니다.그것이 1005 오류의 원인이 되었습니다.

내 외래 키를 그 상황에 좀 더 구체적인 것으로 이름을 바꾼 것이 문제를 해결했습니다.

  1. 두 테이블 모두 동일한 엔진 유형을 사용하고 있는지 확인합니다.
  2. 색인화할 필드의 유형과 길이가 동일한지 확인합니다.

나의 경우, 오류는 다음과 같습니다.referencing은 테블은이입니다.MyISAM에 면에반에.referring테이블은InnoDB.

Converted의 테이블 MyISAM to InnoDB저를 위해 문제를 해결해 줍니다.

ALTER TABLE table_name ENGINE=InnoDB;

저는 아직 스티브의 제안에 찬성할 만한 평판을 얻지 못했지만, 그것이 제 문제를 해결했습니다.

저의 경우, 서로 다른 데이터베이스 엔진을 사용하여 생성된 두 개의 테이블이 Innodb이고 다른 MyISAM이기 때문에 이 오류가 발생했습니다.

ALTER TABLE t ENGINE = MYSAM을 사용하여 데이터베이스 유형을 변경할 수 있습니다.

@http://dev.mysql.com/doc/refman/5.1/en/storage-engine-setting.html 참조

테이블을 작성할 때는 CHARSET 및 COLATE 파라미터에 주의하십시오.외국인문제와 관련하여 다음과 같은 것이 있습니다.

CREATE TABLE yourTableName (
....
....
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

저의 경우 외국인 키 참조를 사용하여 테이블을 만들 수 없습니다.먼저 거의 아무 말도 하지 않는 오류 코드 1005를 받았습니다.그런 다음 COLLATE를 추가하고 마지막으로 CHARSET에 대한 불만을 표시하는 오류 메시지를 추가했습니다.

Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'

그 수정 후에 저의 문제는 해결되었습니다.

특정 사례는 아니지만 테이블의 전체 기본 키가 아닌 일부 필드를 참조하려고 할 경우 이 오류가 발생할 수 있습니다.분명히 이것은 허용되지 않습니다.

잘 형성된 것처럼 보이는 FK/PK 관계에 이 오류가 있는 사람이 있고 시각적 도구를 사용한 경우, 문제가 되는 fk 열을 삭제하고 도구에 다시 추가해 보십시오.문제를 해결하는 연결을 다시 그릴 때까지 이 오류가 계속 발생했습니다.

기본 키에 대한 열이 2개인 경우 복합 기본 키를 구성하므로 참조 중인 테이블에도 동일한 데이터 유형의 열이 2개 있는지 확인해야 합니다.

하위 테이블의 일반 인덱스 필드를 상위 테이블의 기본 키와 일치시키려고 했습니다. 기본적으로 Sequet Pro와 같은 일부 MySQL 프런트엔드 GUI는 기본 키를 서명되지 않은 키로 설정하므로 하위 테이블 필드에도 서명되지 않은 필드가 있는지 확인해야 합니다.둘 다 서명했는지 확인합니다.

첫 번째 질문: 외부 키이기도 한 기본 키를 만들 수 있습니까?

네. 사실 MySQL 워크벤치에서는 외부 키에 기본 키만 사용하는 습관이 있습니다.질문에 명시된 err:150과 같이 수신되는 임의 오류를 정말로 줄입니다.

오류: 오류 1005: 'dbimobili.condoni' 테이블을 만들 수 없습니다(오류 번호: 150).

이것은 인덱스와 관련이 있습니다. 특히 MySQL 워크벤치가 인덱스를 해석하고 사용하는 방법과 관련이 있습니다.모델에서 많은 부분(예: 외부 키, 인덱스, 색상)을 모두 동일한 전방 엔지니어링 작업에서 변경하는 경우, 특히 다른끝에 이미 데이터베이스가 있는 경우에는 매우 혼란스럽습니다.예를 들어, 외부 키를 삭제한 후 자동으로 삭제되는 인덱스는 자동으로 생성되지 않는다고 생각합니다.

여기 당신이 받은 오류를 수정하기 위해 제가 한 일이 있습니다.참고로 번거로운 것 같지만 다른 방법을 사용한 시간과 비교하면 그렇지 않습니다.

룩업 테이블에서 모든 외부 키를 기본 키로 만듭니다(1 대 다 중 하나).

제 경우에는 pk로 id를 tbl_users의 username, tbl_companys의 username AND company, tbl_company_contacts의 username AND company로 변경해야 합니다.여러 사용자가 여러 회사 연락처를 입력할 수 있는 앱으로, 다른 사용자 연락처를 중복하여 숨길 수 있습니다.

기본 키가 아닌 모든 다이어그램 관계 및 모든 테이블 인덱스를 삭제합니다.

이렇게 하면 MySQL 워크벤치의 버그로 인해 실제로 발생하는 대부분의 인덱스 문제를 해결할 수 있습니다.

처음부터 끝까지 이 작업을 수행하는 경우, mysql 워크벤치가 기존 인덱스에 대해 혼동하지 않고 모델에 부족하지 않도록 스키마를 서버에 놓습니다(인덱스 단독이 아니라 bby 인덱스와 외부 키 관계가 문제입니다).

이를 통해 DB, 서버 및 Myslog 워크벤치가 수행해야 하는 많은 결정 사항을 줄일 수 있습니다.어떤 것을 어떻게 앞으로 발전시킬 것인가에 대한 이러한 결정은 복잡하고 지능적이지만 불완전합니다.

(일반적으로 단계적인 프로세스 없이 너무 빨리 설계한 후) 이를 원점으로 되돌립니다.저는 아직 테이블을 다 가지고 있지만, 이 단계에서는 깨끗합니다.이제 당신은:

첫째, (관계가 없는) 테이블이 예상대로 작동하는지 확인하기 위해 엔지니어를 전진시킵니다.

맨 위 테이블에서 시작하여 기본 키까지 관계 체인을 따릅니다(나는 tbl_users to tbl_companys).각 관계가 끝난 후에는 항상 엔지니어를 앞으로 보내 실행 여부를 확인한 다음 모델을 저장하고 닫은 다음 모델을 역설계하여 필요한지 확인합니다.이렇게 하면 오래된 삭제된 외부 키에서 사용하는 잔여 인덱스(2-3회 발생)와 같은 문제가 발생할 때 문제를 신속하게 분리할 수 있습니다.

그리고 태다, 네가 있어야 할 곳으로 돌아가.

MySQL은 특히 외부 키 및 트리거와 관련하여 까다롭기로 악명 높습니다.저는 지금 그러한 데이터베이스를 미세 조정하는 중에 이 문제에 부딪혔습니다.이는 자명하거나 직관적이지 않으므로 다음과 같습니다.

관계에서 참조하려는 두 열의 데이터 유형이 동일한지 확인하는 것 외에도 참조 중인 테이블의 열이 인덱스인지 확인해야 합니다.MySQL Workbench를 사용하는 경우, "열" 바로 옆에 있는 "색인" 탭을 선택하고 외부 키가 참조하는 열이 색인인지 확인합니다.그렇지 않은 경우, 해당 항목을 만들고 의미 있는 이름을 지정한 후 "INDEX" 유형을 지정합니다.

좋은 방법은 관계와 관련된 테이블을 정리하여 이전 시도에서 원하지 않거나 필요하지 않은 인덱스를 만들지 않도록 하는 것입니다.

도움이 되었기를 바랍니다, 일부 MySQL 오류가 추적을 어렵게 하고 있습니다.

언급URL : https://stackoverflow.com/questions/4063141/mysql-foreign-key-error-1005-errno-150-primary-key-as-foreign-key

반응형