스프링에서 엔티티의 TYPE을 지정할 때 자바 enum을 사용하는 건 사실 개발 편의성이 크다. 코드 차원에서는 안전하게 타입을 보장해주니까 실수도 줄고 가독성도 좋다. 그런데 DB 차원에서는 이야기가 조금 다르다.
MySQL이나 PostgreSQL처럼 ENUM 타입을 지원하는 DBMS도 있지만, MS SQL Server나 Oracle에서는 기본적으로 제공하지 않는다. 그래서 MySQL/PostgreSQL을 쓴다면 “괜찮지 않나?” 하고 쉽게 생각할 수 있다. 하지만 실제로는 고려해야 할 점들이 꽤 있다.
Enum의 속성을 변경하려면..?
MySQL의 ENUM은 컬럼 정의 자체에 값 집합을 포함한다. 즉 새로운 값을 추가하거나 수정하려면 단순히 데이터를 넣는 것이 아니라 ALTER TABLE을 통해 컬럼을 다시 정의해야 한다. 이건 곧 테이블 구조 자체를 변경하는 작업이고, 마이그레이션 절차가 필요하다. 특히 대용량 테이블일 경우 ALTER TABLE을 실행하는 동안 메타데이터 락이 걸리거나 내부적으로 테이블이 재작성되면서, 다른 세션에서 접근이 지연되거나 차단될 수 있고 읽기·쓰기 성능도 떨어질 수 있다. 운영 환경에서는 이런 스키마 변경이 큰 위험 요소가 될 수 있다. 따라서 ENUM은 값이 거의 변하지 않는 경우에만 사용하는 게 적절하다. 변화 가능성이 있는 값은 VARCHAR + CHECK나 코드 테이블로 관리하는 편이 훨씬 안전하다.
Enum의 속성을 삭제한다면..?
삭제할 때는 더 문제가 된다. 예를 들어 user.status ENUM('ACTIVE','SUSPENDED','DORMANT','WITHDRAWN')가 있는데, 이제 WITHDRAWN을 쓰지 않으려고 ENUM 정의에서 제거했다고 하자. 그런데 테이블에 이미 WITHDRAWN 값이 들어간 행이 있다면 어떻게 될까? MySQL은 그 값을 더 이상 해석할 수 없어서 ALTER TABLE 자체가 실패하거나, 심하면 값이 잘못 매핑되거나 깨질 수 있다.
그 이유는 MySQL ENUM이 내부적으로 문자열이 아니라 순번(ordinal)을 저장하기 때문이다. 예를 들어 ACTIVE=0, SUSPENDED=1, DORMANT=2, WITHDRAWN=3 이렇게 매핑돼 있는데, 중간 값이 빠지면 순서가 달라져서 기존 데이터의 값은 더 이상 의미를 갖지 못한다. 결국 DB는 이 값이 무엇인지 알 수 없게 되어 삭제가 불가능한 것이다. 해결하려면 먼저 기존 데이터를 다른 값으로 치환한 뒤에야 테이블 구조를 수정할 수 있다.
이처럼 테이블 구조 변경에도 많은 시간과 자원이 드는데, 값 치환까지 고려하면 훨씬 비효율적이다. 그래서 현실적으로는 정말 바뀔 일이 없는 값(예: 성별) 같은 경우에만 DB ENUM을 사용하고, 나머지는 VARCHAR로 두는 게 낫다. ERD는 실제 개발·운영 과정에서 계속 수정이 일어날 수 있기 때문에, 변경을 유연하게 처리할 수 있는 설계가 더 안전하다.
'CS > DB' 카테고리의 다른 글
| DB 성능 문제, 구조를 나누는 것부터 시작하기 (0) | 2025.12.28 |
|---|---|
| DBCP가 뭐지..? (0) | 2025.12.28 |
| 데이터베이스 성능을 저하시키는 N+1 쿼리 문제란? (0) | 2025.10.03 |
| Transaction 알아보기 (0) | 2025.09.15 |
| DB에서 상속은 어떻게 나타내는가? (0) | 2025.09.14 |
