데이터베이스 설계 후 스키마를 이관하거나 새로운 테이블을 생성할 때 ERROR 1215 (HY000): Cannot add foreign key constraint 에러에 직면한 경험이 있을 것이다.
테이블 간 참조 관계를 설정하기 위해 Foreign Key(외래키)를 지정했을 뿐인데, MySQL은 구체적으로 어떤 부분이 잘못되었는지 상세한 이유를 알려주지 않은 채 묵묵부답으로 에러 코드만 던지곤 한다.
다만 대부분의 개발자들은 이 에러가 발생하는 구체적인 조건들을 알지 못한 채 컬럼 이름만 몇 번 바꾸다가 시간을 허비하곤 한다.
이번 글에서는 ERROR 1215가 발생하는 정확한 원인 5가지와 이를 신속하게 추적하고 해결하는 실전 방법까지 완벽하게 정리해서 소개하겠다.

 

ERROR 1215 (HY000)가 발생하는 원리

MySQL에서 외래키 제약조건을 생성하려면 참조하는 부모 테이블의 컬럼과 참조하는 자식 테이블의 컬럼 사이에 엄격한 정합성이 유지되어야 한다.
단순히 데이터 타입의 이름이 같은 수준을 넘어, 메모리 할당 크기, 부호 여부(Signed/Unsigned), 문자집합(Charset)과 콜레이션(Collation), 그리고 인덱스 존재 여부까지 완전히 일치해야 정상적인 외래키 연결이 완료된다.
MySQL 엔진은 이 조건 중 하나라도 위배되면 스키마의 무결성이 깨질 위험이 있다고 판단하여 테이블 생성을 거부하고 ERROR 1215를 반환한다.

 

ERROR 1215를 유발하는 대표 원인 5가지

실무에서 외래키 생성 실패를 일으키는 주요 원인을 정리하면 다음과 같다.

원인 항목문제 상황해결 방법
1. 데이터 타입 불일치INT와 BIGINT, VARCHAR 길이 불일치두 컬럼의 데이터 타입을 완전 동일하게 맞춤
2. Unsigned 속성 불일치부모는 INT UNSIGNED, 자식은 INT (Signed)Unsigned 속성을 양쪽 모두 동일하게 부여
3. 인덱스 누락부모 테이블의 참조 컬럼에 인덱스 없음부모 컬럼에 PRIMARY KEY 또는 INDEX 추가
4. Charset / Collation 불일치부모는 utf8mb4_unicode_ci, 자식은 utf8mb4_general_ci테이블 및 컬럼의 문자집합과 콜레이션 통일
5. 스토리지 엔진 불일치부모는 InnoDB, 자식은 MyISAM외래키를 지원하는 InnoDB 엔진으로 통일

 

실전 예제로 보는 문제 파악과 올바른 DDL 작성

가장 자주 실수하는 두 가지 대표 사례를 통해 잘못된 코드와 올바른 코드를 비교해보겠다.

 

사례 1: Unsigned 속성 및 데이터 타입 불일치

부모 테이블의 PK는 BIGINT UNSIGNED인데 자식 테이블의 FK를 단순 INT로 선언하면 제약조건 생성이 실패한다.

✗ 잘못된 코드(자식 테이블 생성 실패)

CREATE TABLE users (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- ERROR 1215 (HY000): Cannot add foreign key constraint 발생
CREATE TABLE orders (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    product_name VARCHAR(100) NOT NULL,
    CONSTRAINT fk_orders_user_id FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

✓ 올바른 코드(외래키 정합성 일치)

CREATE TABLE orders (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT UNSIGNED NOT NULL,
    product_name VARCHAR(100) NOT NULL,
    CONSTRAINT fk_orders_user_id FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

출력 결과:

Query OK, 0 rows affected (0.02 sec)

 

사례 2: Charset 및 Collation 불일치

테이블 생성 시 문자집합 설정을 생략하거나 서로 다르게 지정하면 텍스트 기반 FK 생성 시 에러가 난다.

✗ 잘못된 코드(문자집합 차이로 인한 실패)

CREATE TABLE categories (
    code VARCHAR(20) PRIMARY KEY,
    name VARCHAR(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ERROR 1215 (HY000) 발생 (Collation 불일치)
CREATE TABLE products (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    category_code VARCHAR(20) NOT NULL,
    CONSTRAINT fk_products_category FOREIGN KEY (category_code) REFERENCES categories(code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

✓ 올바른 코드(Collation 명시적 통일)

CREATE TABLE products (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    category_code VARCHAR(20) NOT NULL,
    CONSTRAINT fk_products_category FOREIGN KEY (category_code) REFERENCES categories(code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

출력 결과:

Query OK, 0 rows affected (0.03 sec)

 

상세 원인을 파악하는 꿀팁: INNODB STATUS 활용

테이블 구조가 복잡해서 눈으로 에러 원인을 찾기 어렵다면, MySQL 명령어로 가장 최근 발생한 외래키 에러의 구체적 원인을 조회할 수 있다.

SHOW ENGINE INNODB STATUS;

출력 결과 항목 중 LATEST FOREIGN KEY ERROR 세션을 확인하면 아래와 같이 정확히 어떤 이유로 거부되었는지 상세 메시지가 출력된다.

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2023-10-25 14:20:00 0x7f8a90123700 Error in foreign key constraint of table my_db/orders:
FOREIGN KEY (user_id) REFERENCES users(id):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns.

 

외래키 작성 시 주의사항과 체크리스트

✗ 데이터 타입만 일치시키고 Unsigned 옵션을 누락하는 경우
✓ 부모가 INT UNSIGNED라면 자식 컬럼도 반드시 INT UNSIGNED로 동일하게 선언한다.

✗ 부모 테이블의 참조 컬럼에 인덱스가 없는 상태로 FK를 생성하는 경우
✓ 부모 테이블 컬럼은 PK이거나 최소한 일반 INDEX가 생성되어 있어야만 외래키로 참조할 수 있다.

✗ ON DELETE SET NULL을 설정하면서 자식 컬럼을 NOT NULL로 선언하는 경우
✓ 삭제 시 NULL로 변경되는 옵션을 쓸 때는 자식 컬럼에 NULL 허용 옵션이 부여되어 있어야 한다.

 

마무리

MySQL ERROR 1215는 데이터베이스 스키마 간의 엄격한 데이터 정합성을 보장하기 위한 보호 장치다.
개발 과정에서의 작은 타입 불일치나 속성 누락을 철저히 점검하는 습관이 견고한 데이터베이스 구조를 만드는 첫걸음이다.
이 글의 체크리스트와 SHOW ENGINE INNODB STATUS 디버깅 기법을 참고해서 DDL을 수정하면, 답답했던 외래키 생성 에러를 즉시 해결할 수 있을 것이다.