모든 글

열거형인가 코드 테이블인가: 변화 주기로 결정하라

안정적인 값은 열거형으로, 자주 바뀌는 데이터는 전용 테이블로 관리해 공통 코드 테이블이 잡동사니 저장소가 되는 일을 막는다.

출처 및 AI 안내: 이 글은 제미니의 개발실무 유튜브를 기반으로 작성되었습니다. gpt-5.6-sol 모델을 사용해 생성·편집했습니다.

“열거형을 쓰지 마라”와 “모든 값을 공통 코드 테이블에 넣어라”는 모두 보편적인 규칙이 되기 어렵다. 값이 얼마나 자주 바뀌는지, 어떤 소프트웨어를 만들고 있는지부터 보는 편이 낫다.

거의 바뀌지 않는 값에는 열거형이 더 명확한 선택일 가능성이 높다. 자주 바뀌는 값에는 테이블이 더 잘 맞을 수 있다. 한 서비스에서 두 방식을 함께 사용해도 된다.

저장 위치만 비교하기보다 변경 경로를 먼저 보자. 열거형은 개발과 검토, 배포를 거쳐 바뀐다. 테이블 값을 실행 중에 바꿀 수 있게 만들면 별도의 운영 권한과 검증, 복구 절차가 필요하다. 해당 값을 누가 소유하고 잘못된 변경을 누가 발견할 것인지까지 정해야 어느 쪽의 비용이 현재 제품에 맞는지 알 수 있다.

안정적인 값에는 열거형이 좋은 기본값이다

열거형은 사용하는 코드 안에 있다. 허용된 값을 찾기 쉽고 모델이 데이터베이스에 덜 결합된다. 테스트에서도 코드 테이블을 먼저 읽거나 캐시 데이터를 준비하지 않고 그 값을 직접 사용할 수 있다.

공통 코드 테이블을 애플리케이션 시작 시 메모리에 올린다고 해도 테스트에서는 코드와 별도로 데이터 집합을 준비해야 한다. 초기화 SQL이나 픽스처가 빠지면 비즈니스 로직과 관계없는 이유로 검증이 깨질 수 있다. 값이 사실상 소스 코드가 소유하는 고정 계약이라면 이런 간접 계층 없이 열거형으로 독립적으로 테스트하는 편이 더 단순하다.

코드를 읽을 때도 직관적이다. 언어, 국가, 통화 식별자처럼 거의 변하지 않고 이미 익숙한 의미를 가진 값은 서비스 개발에서 열거형과 잘 맞는 경우가 많다.

허용된 값이 행위 가까이에 있으므로 분기 로직과 값의 추가가 같은 코드 리뷰에 나타난다는 장점도 있다. 존재하지 않는 값이 DB에 들어가는 상태를 별도로 처리할 필요가 줄고, 개발자는 모델이 받아들이는 집합을 코드에서 바로 확인할 수 있다. 이는 값이 안정적이라는 전제가 있을 때 얻는 직접성이다.

비용도 있다. 열거형을 바꾸면 배포해야 한다. 열거형 이름 자체를 저장했다면 이름을 바꿀 때 이전 이름이 들어 있는 데이터와 호환되지 않을 수 있다. 이런 제약은 중요하지만 테이블이 무조건 더 낫다는 뜻은 아니다. 그 값이 코드가 소유할 만큼 안정적인지 판단하게 해 주는 조건이다.

저장 문자열은 단순한 구현 세부사항으로만 다루기 어렵다. 다른 테이블이나 외부 소비자가 KRW 같은 열거형 이름을 그대로 보관한다면 상수 이름의 변경은 계약 변경이 된다. 열거형을 택할 때는 이름을 오래 유지할 식별자로 볼지, 별도의 안정된 값을 둘지도 함께 결정해야 한다.

실제로 자주 바뀌는 값에는 테이블이 맞을 수 있다

값이 수시로 바뀐다면 데이터로 저장하는 편이 나을 수 있다. 테이블을 사용하면 변경마다 배포하지 않아도 되고, 안정적인 코드는 유지한 채 연결된 이름을 바꿀 수도 있다.

예를 들어 다른 데이터에는 01 같은 안정적인 키를 저장하고 코드 테이블에서 표시 이름을 연결할 수 있다. 사용자가 보는 이름을 바꿔도 참조 키는 유지된다. 값의 추가와 비활성화, 표시 순서 같은 속성을 운영자가 관리해야 한다면 이는 단순한 상수 집합이 아니라 자체 생명주기를 가진 데이터에 가깝다.

범위가 정해진 서비스보다 범용 솔루션이나 플랫폼에서 이런 필요가 더 클 수 있다. 소프트웨어의 목적에 따라 트레이드오프가 달라진다. 중요한 것은 모든 분류를 DB에 두라는 규칙이 아니라 값이 정말 가변적이기 때문에 테이블을 고르는 일이다.

테이블은 거리도 만든다. 애플리케이션은 DB에서 값을 읽고, 필요하면 캐시하며, 테스트에서도 데이터를 준비해야 한다. 제품에 실제로 필요한 유연성을 얻는다면 이 비용을 지불할 수 있다.

그와 함께 행 누락과 중복, 잘못된 그룹 연결처럼 코드 안의 열거형에는 없던 상태도 생긴다. 캐시를 쓴다면 DB 변경이 언제 반영되는지와 오래된 값을 어떻게 무효화할지도 다뤄야 한다. 어차피 개발자만 값을 바꾸고 변화도 드물다면 테이블의 유연성은 이 운영 비용을 정당화하지 못할 수 있다.

테이블을 쓴다는 말과 공통 테이블을 쓴다는 말을 구분한다

공통 코드 테이블은 보통 그룹 코드, 코드, 이름 같은 형태로 시작한다. 그 뒤에는 국가 코드, 매출 코드, 업체 코드, 상품 카테고리와 코드처럼 보이는 모든 것이 모이기 쉽다.

처음의 세 열로 표현되지 않는 요구가 생기면 범용 테이블은 예외 열과 분기 규칙을 끌어안는다. 어떤 분류에는 계층이 필요하고, 다른 분류에는 순서나 추가 속성, 별도 검증이 필요할 수 있다. 서로 다른 개념이 같은 생명주기를 갖지 않는데도 “코드”라는 이유만으로 한곳에 모이면 변경 이유와 소유자가 흐려진다.

문제는 행의 개수만이 아니다. common이라는 이름은 각 개념이 바뀌는 이유를 숨긴다. 서로 다른 비즈니스 로직이 하나의 분명한 주인이 없는 테이블 주변으로 모이기 시작한다.

어떤 개념을 테이블로 관리해야 한다면 그 개념의 이름을 가진 테이블이 더 이해하기 쉬운 경우가 많다. 상품 카테고리는 범용 공통 코드의 한 그룹이 아니라 별도의 상품 카테고리 테이블로 둘 수 있다. 다른 분류도 같은 방식으로 나눌 수 있다.

전용 테이블은 그 개념에 필요한 필드와 제약을 직접 표현한다. 상품 카테고리의 계층이나 제공자 설정의 활성 조건을 공통 스키마의 특수 규칙으로 숨기지 않아도 된다. 공유 코드 기능이 실제로 유용한 시스템도 있지만, 테이블을 선택했다는 사실만으로 관계없는 개념까지 하나의 공통 상자에 넣을 이유는 없다.

두 방식을 의도적으로 섞는다

실용적인 판단은 두 질문에서 시작할 수 있다.

  1. 이 값의 집합이 배포가 문제가 될 만큼 자주 바뀌는가?
  2. 테이블이 필요하다면 공통 테이블의 다른 값들과 정말 하나의 개념을 공유하는가?

여기에 몇 가지를 더 확인하면 변경 비용이 선명해진다.

  • 값을 바꿀 권한은 개발자에게 있는가, 운영자에게 있는가?
  • 저장 식별자가 다른 시스템과의 계약으로도 쓰이는가?
  • 값에 순서, 활성 상태, 계층이나 별도 속성이 필요한가?
  • DB 조회와 캐시, 테스트 준비가 실제 유연성을 사는가?
  • 전용 테이블 대신 공통 테이블을 써야 할 구체적인 이유가 있는가?

안정적인 값은 열거형으로 두고, 자주 바뀌는 값은 구체적인 전용 테이블로 만들 수 있다. 서비스와 범용 플랫폼의 답은 다를 수 있고 제품이 변하면 선택도 달라질 수 있다.

혼합은 기준이 없다는 의미가 아니다. 값마다 변경 주체와 호환성, 운영 방식을 확인한 결과가 다른 것이다. 한때 안정적이던 값이 독립적으로 관리되기 시작하면 테이블로 옮길 수 있고, 반대로 데이터로 뒀지만 실제로 전혀 변하지 않는다면 선택을 다시 검토할 수 있다.

목적은 한쪽 방식을 지키는 것이 아니다. 안정된 의미는 코드 가까이에 두고, 실제로 가변적인 데이터는 바꿀 수 있는 곳에 두며, common이라는 이름이 관계없는 개념의 경계를 지우지 않게 하자.