MySQL 이 짜증나는 점중에 하나는 참조키를 추가하다가 에러가 발생할 경우 에러가 난 원인을 정확히 알려주지 않고 "Cannot Add Foreign Key Constraint" 와 같이 대충 알려준다는 점입니다.


이때문에 저 에러가 발생하면 눈이 빠지게 쿼리문을 들여다 봐야 하는데 https://dzone.com/articles/dealing-with-mysql-error-code-1215-cannot-add-foreign-key-constraint 잘 정리된 내용이 있어서 많은 도움이 됐습니다. 


저는 위 링크에 소개된 12가지 사례중에서 3, 4를 많이 접해서 정리해 봅니다.

3) The Local Key, Foreign Table or Column in the Constraint References Have a Typo


테이블이나 컬럼명에 오타가 있을 경우에도 위 에러가 발생하니 DESC 명령이나 DB Client 툴로 스키마를 확인하고 오타를 교정합니다.


4) The Column the Constraint Refers to Is Not of the Same Type or Width as the Foreign Column


참조 키 컬럼과 참조되는 컬럼의 데이타 타입과 길이가 달라서 발생하는 경우로  저는 참조키로 integer type 을 주로 사용하며 양쪽 다 integer 인데 저 에러가 발생해서 한참을 헤맸습니다.


unsigned int vs signed int

원인은 한쪽은 unsigned integer 였고 다른쪽은 signed integer라 발생한 것이었습니다.


MySQL 콘솔에서 DESC tablename; 명령어를 실행하면 unsigned 일 경우는 int 10 unsigned 이고 signed 일 경우 int(11) 로 표시됩니다.

mysql> desc tables1;


+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |




mysql> desc tables2;


+------------------------+------------------+------+-----+---------+----------------+
| Field                  | Type             | Null | Key | Default | Extra          |
+------------------------+------------------+------+-----+---------+----------------+
| id                     | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| category_id            | int(11)          | YES  |     | NULL    |                |
CODE


Big Integer vs integer

이건 제가 자주 사용하는 laravel 이라는 프레임워크와 관련된 문제이긴 한데 1215 관련 에러이므로 정리해 봅니다.

라라벨 프레임워크에서는 DB migration 기능을 제공하는데 laravel 5.8 부터는 자동 생성되는 id 컬럼의 타입이 bigInteger 로 변경되었습니다.

// laravel 5.7 이하
$table->increments('id');

// laravel 5.8
$table->bigIncrements('id');
CODE


이때문에 foreign key 로 사용할 컬럼은 5.8 이상은 unsignedBigInteger 로 생성해야 합니다.

laravel 5.8 이상

$table->unsignedBigInteger('category_id')->nullable();
$table->foreign('category_id')
                ->references('id')
                ->on('categories');
PHP


Ref