개요
학생 프로젝트 진행 현황을 관리하는 시스템에서 신규 데이터를 등록할 때 MySQL 오류가 발생했습니다. 애플리케이션 로직에서는 ID가 자동으로 생성될 것으로 예상했지만 실제 스키마는 그 가정과 일치하지 않았습니다.
문제 상황
학생 데이터를 INSERT하는 과정에서 id 컬럼에 기본값이 없다는 오류가 발생하며 등록이 실패했습니다.
Field 'id' doesn't have a default value영향 범위
기존 행을 읽는 화면은 동작했지만 신규 학생·프로젝트 등록 경로가 막혔습니다. 즉 전체 데이터베이스 장애가 아니라 쓰기 경로의 스키마 계약 위반이었습니다.
확인된 사실
- 오류 문자열은 MySQL이
id값을 요구하고 있음을 가리켰습니다. - INSERT 쿼리는 ID 자동 생성을 전제로
id를 전달하지 않았습니다. - 요청의 업무 데이터는 들어왔고 조회 연결도 정상이라 연결 장애 가능성은 낮았습니다.
- 실제 테이블의
id컬럼에는 당시AUTO_INCREMENT가 없었습니다.
가설을 오류 계층별로 나눴습니다
- 요청 계층: 필수 입력이나 값이 빠졌는가
- 쿼리 계층: 컬럼 목록과 바인딩 값이 어긋났는가
- 애플리케이션 계층:
undefined가 전달됐는가 - 스키마 계층: 기본키가 자동 생성되도록 정의됐는가
진단 과정
- 실패한 INSERT의 컬럼 목록을 확인했습니다.
- 요청 본문과 바인딩되는 값을 비교했습니다.
- 조회 쿼리가 동작하는지 확인해 DB 연결 문제를 분리했습니다.
DESCRIBE로 실행 중인 DB의 실제 스키마를 확인했습니다.id의Extra에auto_increment가 없음을 확인했습니다.
DESCRIBE student_project;
-- 확인 기준
-- Key : PRI
-- Extra : auto_increment실제 원인
애플리케이션은 데이터베이스가 숫자 ID를 생성한다고 가정했지만, 당시 실제 테이블은 그 계약을 구현하지 않았습니다. 조회 코드가 정상이라는 사실과 별개로, 쓰기 코드와 배포된 스키마가 서로 다른 상태였습니다.
대안을 비교했습니다
선택한 조치
운영 테이블의 기본키를 수정하고, 애플리케이션은 ID를 직접 만들지 않도록 유지했습니다. 같은 정의를 저장소의 schema.sql과 런타임 테이블 보장 코드에도 반영했습니다.
id INT NOT NULLid INT AUTO_INCREMENT
PRIMARY KEYstudent_project, project_comment, project_view_event 숫자 키가 같은 패턴을 사용합니다.검증 기준
- ID를 제외한 업무 컬럼만으로 INSERT가 성공해야 합니다.
- 생성된 행에 중복되지 않는 숫자 ID가 있어야 합니다.
- 생성 ID로 다시 조회할 수 있어야 합니다.
- 새 DB를 초기화해도 같은 스키마가 만들어져야 합니다.
- 외래키를 사용하는 댓글·조회 이벤트 테이블과 연결돼야 합니다.
결과
- 신규 데이터 등록과 ID 자동 생성이 정상화됐습니다.
- 애플리케이션이 임의의 ID를 계산할 필요가 없어졌습니다.
- 생성 ID를 이후 조회와 하위 테이블의 외래키로 사용할 수 있습니다.
- 공개 저장소의 초기화 스키마에도 같은 정의가 남아 있습니다.
student_project.id INT AUTO_INCREMENT PRIMARY KEY. 운영 DB의 과거 결과 수치는 보존되지 않아 성공 건수를 만들지 않았습니다.재발 방지
- 테이블 생성 SQL을 저장소에서 버전 관리합니다.
- 쓰기 기능 배포 전 실제 DB 스키마와 코드를 함께 확인합니다.
- 신규 환경에서 초기화 후 INSERT 연기 테스트를 수행합니다.
- 스키마 변경이 늘어나면 순서가 있는 마이그레이션으로 전환합니다.
기록 한계와 다음 단계
원본 장애 시점의 DESCRIBE 전체 출력과 운영 INSERT 로그는 보존되지 않았습니다. 따라서 정확한 발생 시각·실패 건수는 공개 기록에 넣지 않았습니다. 다음 단계는 CI에서 빈 MySQL을 올리고 schema.sql 적용과 CRUD 스모크 테스트를 자동화하는 것입니다.
배운 점
데이터베이스 오류를 애플리케이션 코드만 보고 판단해서는 안 됐습니다. 쓰기 로직이 전제하는 키 생성·기본값·제약조건이 실제 배포된 스키마와 일치하는지 런타임에서 확인해야 합니다.