외래키는 규칙이 아니라 운영상의 선택이다
무결성 요구, 장애 대응, 배포 절차, 운영 DB의 주체를 기준으로 외래키와 인덱스, ORM 연관관계를 각각 선택하는 방법입니다.
출처 및 AI 안내: 이 글은 제미니의 개발실무 유튜브를 기반으로 작성되었습니다.
gpt-5.6-sol모델을 사용해 생성·편집했습니다.
외래키 제약을 걸지 말지는 흔히 데이터베이스 원칙이나 성능 문제로 다뤄진다. 내가 외래키를 자주 생략하는 이유는 운영에 가깝다. 장애 중에 꼬인 데이터를 즉시 수정하거나 지워야 할 수 있는데, 제약이 여러 단계로 연결돼 있으면 긴급 조치가 훨씬 어려워진다.
이는 데이터베이스가 보장하는 무결성과 운영상의 자유를 바꾸는 선택이다. 언제나 더 안전하거나 빠르다는 뜻도, 모든 시스템에 맞는 정답이라는 뜻도 아니다.
어떤 시스템을 운영하는지 먼저 본다
운영팀이 직접 원인을 찾고 운영 데이터를 복구하는 라이브 서비스와 고객사에 납품하는 솔루션은 조건이 다르다. 전자에서는 긴급 복구를 위해 일부 관계를 제약 없이 두고 애플리케이션이 규칙을 지키게 할 수 있다. 직접적인 장애 대응이 드물고 무결성이 가장 중요한 납품 시스템이라면 외래키가 더 나은 기본값일 수 있다.
질문은 구체적이어야 한다.
- 불일치 데이터가 생겼을 때 비용은 얼마나 큰가?
- 누가 운영 데이터에 접근하고 복구할 수 있는가?
- 장애 중 직접 데이터 조작이 허용된 복구 수단인가?
- DBA와 스키마 변경 검토 절차가 있는가?
외래키를 건다면 어떤 위험을 막는지 설명해야 한다. 걸지 않는다면 누가 무결성을 지키고 실패를 어떻게 발견하는지 설명해야 한다. 어느 쪽이든 “원래 이렇게 한다”만으로는 부족하다.
인덱스는 별도 결정이다
외래키 제약이 없어도 ID 참조에 인덱스가 필요할 수 있다. 가능한 인덱스를 처음부터 모두 만들지는 않는다. 자주 조회하는 키에는 대체로 인덱스를 추가하지만, 쓰지 않는 인덱스도 저장 공간과 쓰기 비용을 만든다. 현재 데이터 규모와 실제 또는 예상 접근 패턴을 보고 정한다.
운영 스키마가 JPA 어노테이션과 완전히 대칭일 필요도 없다. 유니크 제약처럼 로컬 테스트 DB를 운영 환경과 비슷하게 만드는 데 어노테이션이 도움이 될 수 있다. 하지만 운영 DB를 별도 절차로 바꾸면 두 선언이 어긋날 수 있다. 가끔만 관리되는 문서라면 DB 인수인계를 분명히 분리하는 것보다 더 큰 혼란을 줄 수도 있다.
규모 있는 조직에서는 컬럼과 인덱스 변경을 DBA가 검토하고, 누가 요청하고 적용했는지 증적을 남기기도 한다. 작은 팀은 개발자가 직접 바꿀 수 있다. 무엇을 기준 정보로 삼고 누가 검토할지도 그 운영 모델에 맞춰야 한다.
ORM 연관관계는 비즈니스 기준으로 따로 본다
데이터베이스에 관계가 있다고 JPA 연관관계까지 반드시 필요한 것은 아니다. 나는 생명주기가 분명히 붙어 있다는 확신이 생기기 전에는 ID로 연결하고 비즈니스나 구현 흐름에서 데이터를 조합하는 편이다. 주문과 주문 항목이 늘 함께 움직인다면 연관관계가 자연스러울 수 있다. 반대로 주문 항목 하나를 처리할 때마다 주문 전체를 가져오게 만든다면 평범한 작업이 더 어려워진다.
특히 양방향 탐색은 쉽게 남용된다. 양쪽 테이블에 키가 있다는 이유가 아니라 실제 비즈니스 행위에 두 방향이 모두 필요할 때 추가해야 한다.
외래키, 인덱스, ORM 매핑은 서로 다른 문제를 푼다. 무결성 요구와 접근 패턴, 복구 절차를 기준으로 각각 결정하자. 데이터베이스는 운영 자산이다. 그 규칙은 모델보다 지저분한 현실에서도 시스템을 지키고 복구해야 하는 사람에게 도움이 되어야 한다.