DB Smell로 읽는 데이터베이스 설계의 위험 신호
다목적 컬럼과 테이블, 중복 데이터, 거대 테이블처럼 유지보수성과 성능을 해치는 DB Smell을 식별하고 개선하는 방법
2026-08-14 · 최초 발행 2025-08-10
스키마가 보내는 위험 신호
데이터베이스 설계는 애플리케이션의 성능과 유지보수성에 직접 영향을 준다. 코드에 Code Smell이 있듯, 데이터베이스에도 나중의 변경과 운영을 어렵게 만드는 DB Smell이 있다. 이는 설계에 잠재된 문제를 알리는 징후이며, 일찍 찾아 고치면 장기적인 부담을 줄일 수 있다.
서로 다른 데이터를 한 컬럼에 넣을 때
다목적 컬럼은 하나의 컬럼에 서로 다른 유형의 데이터를 담는 안티패턴이다. 금융 시스템에서 transaction_details 컬럼에 카드 결제, 계좌 이체, ATM 인출처럼 성격이 다른 거래 정보를 JSON 형태로 함께 저장하는 경우가 이에 해당한다.
이 구조는 데이터 일관성을 떨어뜨리고 쿼리를 복잡하게 만든다. 인덱싱 효율도 낮아질 수 있으며 데이터 품질을 관리하기도 어려워진다. 관련 데이터를 별도 테이블로 분리하고, 구체적인 데이터 타입과 정규화된 구조를 적용하는 편이 낫다.
여러 엔티티를 떠안은 테이블
다목적 테이블은 하나의 테이블이 여러 종류의 엔티티 데이터를 함께 저장하는 패턴이다. 예를 들어 users 테이블 하나에 개인 고객, 기업 고객, 관리자, 직원까지 모두 넣는 상황이다.
서로 다른 엔티티의 규칙을 하나의 구조에 적용하면 데이터 무결성을 지키기 어렵고, 비즈니스 규칙과 쿼리도 복잡해진다. 성능과 유지보수에도 부담이 쌓인다. 엔티티별 테이블을 설계하거나 슈퍼타입-서브타입 관계를 모델링해 테이블과 관계를 분리할 수 있다.
같은 정보를 여러 곳에서 관리하는 구조
정규화되지 않은 데이터베이스에서는 동일한 데이터가 여러 위치에 중복 저장될 수 있다. 고객 정보가 주문, 배송, 결제 테이블에 각각 들어 있어 주소가 바뀔 때마다 모든 테이블을 수정해야 하는 경우가 대표적이다.
중복은 저장 공간을 낭비할 뿐 아니라 데이터 불일치와 업데이트 이상(Anomaly)을 만든다. 결과적으로 데이터 무결성도 훼손된다. 정규화와 외래 키를 적용해 중복을 제거하고, 필요한 테이블이 고객 데이터를 참조하도록 관계를 구성하는 방식이 적합하다.
넓어지기만 한 테이블의 부담
테이블에 컬럼이 과도하게 많아지는 것도 경계할 신호다. 제품 정보 테이블에 100개 이상의 속성을 모두 컬럼으로 만들고, 대부분의 행에서 많은 NULL 값이 생기는 구조가 한 사례다.
이런 테이블은 쿼리 성능과 메모리 사용량에 부담을 주며 유지보수도 어려워진다. 수직 분할(Vertical Partitioning)로 핵심 정보와 상세 정보를 나누고, 관련 속성 그룹을 별도 테이블로 분리할 수 있다. 속성의 성격에 따라 EAV(Entity-Attribute-Value) 모델도 검토 대상이 된다.
행이 쌓인 테이블을 다루는 방법
단일 테이블에 수억, 수십억 개의 행이 쌓이면 인덱스 효율이 떨어지고 백업과 복구도 어려워진다. 로그 테이블이 계속 증가해 수십억 행을 보유하면서 간단한 쿼리에도 수 분이 걸리는 상황을 생각할 수 있다.
쿼리 성능 저하와 테이블 잠금 이슈를 피하려면 데이터의 분리 방식을 검토해야 한다. 테이블 파티셔닝(Partitioning), 샤딩(Sharding), 아카이빙 전략, 시계열 데이터베이스가 선택지가 될 수 있다.
컬럼 값에 숨어 있는 비즈니스 규칙
스마트 컬럼은 비즈니스 로직을 데이터베이스 컬럼 값에 인코딩하는 방식이다. status 컬럼의 P12에서 P가 진행중을, 12가 특정 단계를 뜻하도록 만든 경우가 이에 해당한다.
이 방식은 값을 읽는 사람에게 별도 해석 규칙을 요구한다. 확장도 제한되고 애플리케이션 코드와 로직이 중복될 수 있다. 의미를 명시적인 컬럼으로 나누고 코드 테이블을 도입하거나, 이해하기 쉬운 값을 사용하는 방향을 고려할 수 있다. 비즈니스 로직은 애플리케이션 계층으로 옮기는 편이 관리하기 쉽다.
바꾸지 못하는 구조가 만드는 부채
기존 데이터베이스 구조를 바꾸기 어렵다는 이유로 문제가 있는 설계를 계속 유지하는 경우도 DB Smell이다. 레거시 테이블을 고치면 다수의 애플리케이션에 영향이 갈 수 있다는 우려 때문에 임시 방편만 반복하는 상황이 그렇다.
그 결과 기술 부채와 시스템 복잡성이 늘고, 문제를 해결하는 비용도 높아진다. 점진적인 변경 전략을 세우고 마이그레이션 자동화 도구와 데이터베이스 리팩토링 패턴을 활용하면 전환의 위험을 줄일 수 있다. 변경 검증을 위한 테스트 자동화도 필요하다.
발견한 냄새를 개선하는 운영 방식
스키마 리뷰, 성능 모니터링 도구, 쿼리 패턴 분석을 정기적으로 수행하면 문제를 이른 시점에 찾을 수 있다. 개선할 때는 비즈니스 영향도를 분석하고 단계적 리팩토링 계획을 세운 뒤, 소규모 변경부터 진행한다.
데이터베이스 변경 테스트와 마이그레이션 스크립트 검증을 자동화하고 성능 테스트도 포함해야 한다. 정규화 원칙을 이해해 적용하되, 역정규화는 성능 요구사항에 따라 전략적으로 선택한다. 데이터 모델링 표준을 마련하는 일도 같은 맥락에 있다.
모든 DB Smell이 언제나 문제를 뜻하는 것은 아니다. 특정 상황에서는 의도적으로 이런 패턴을 선택할 수도 있다. 다만 선택의 영향과 트레이드오프를 이해한 상태에서 정기적인 리뷰와 지속적인 개선을 이어가야, 현재 요구사항뿐 아니라 이후의 변화와 확장도 수용할 수 있다.