네이버 검색의 대규모 메트릭 저장소, VictoriaMetrics 운영기 (새 탭에서 열림)
데이터베이스 설계 시 관습적으로 사용하는 '소프트 삭제(Soft Delete)' 방식이 유발하는 구조적 결함과 성능 저하 문제를 심층적으로 분석하고 이를 해결할 수 있는 아키텍처 대안을 제시합니다. 삭제 여부를 나타내는 플래그(Flag) 컬럼을 사용하는 방식은 구현이 간단해 보이지만, 장기적으로는 쿼리의 복잡도를 높이고 데이터 무결성을 위협하는 원인이 됩니다. 따라서 서비스의 규모와 요구사항에 따라 데이터 이관이나 상태 관리를 통한 물리적 삭제를 적절히 혼합하는 전략이 필요합니다. **소프트 삭제가 초래하는 기술적 부채** - **쿼리 복잡도 및 휴먼 에러**: 모든 조회 쿼리에 `WHERE deleted = false`와 같은 조건을 강제해야 하며, 조인(Join) 연산이 늘어날수록 조건을 누락할 위험이 커져 보안 및 비즈니스 로직 오류로 이어집니다. - **유니크 제약 조건(Unique Constraint) 충돌**: 사용자 ID나 이메일처럼 유일성이 보장되어야 하는 컬럼에서, 삭제된 레코드가 테이블에 남아 있으면 동일한 값의 새 데이터를 삽입할 때 인덱스 충돌이 발생합니다. - **인덱스 효율 저하**: 삭제 플래그는 카디널리티(Cardinality)가 매우 낮은 데이터이므로 인덱스를 생성해도 스캔 효율이 떨어지며, 불필요한 데이터가 테이블에 계속 축적되어 전체적인 I/O 성능을 저하시킵니다. **무결성 유지를 위한 아키텍처 대안** - **데이터 이관(History/Archive Table) 방식**: 삭제가 발생할 때 해당 로우를 원본 테이블에서 물리적으로 삭제하는 대신, 트리거나 애플리케이션 로직을 통해 '삭제 전용 테이블'로 옮겨 메인 테이블의 크기를 최적화합니다. - **데이터베이스 뷰(View) 활용**: 애플리케이션 계층에서는 삭제되지 않은 데이터만 필터링된 뷰를 참조하게 함으로써 개발자가 실수로 삭제된 데이터를 조회하는 상황을 원천적으로 차단합니다. - **복합 유니크 인덱스 설계**: 삭제 시점을 기록하는 `deleted_at` 컬럼을 활용하여 `(ID, deleted_at)` 형태의 복합 인덱스를 구성함으로써, 삭제된 데이터와 활성 데이터 간의 제약 조건 충돌을 우회합니다. **실무적인 선택 기준** 단순히 데이터 복구 가능성을 위해 소프트 삭제를 채택하기보다는, 해당 데이터가 비즈니스적으로 '상태가 변경된 것(예: 탈퇴 회원)'인지 아니면 '완전히 폐기된 것'인지를 먼저 구분해야 합니다. 법적 근거에 의한 보관이 목적이라면 별도의 이력 테이블로 분리하는 것이 성능과 유지보수 측면에서 유리하며, 단순한 실수 방지가 목적이라면 트랜잭션 로그나 백업 시스템을 활용하는 물리 삭제 방식을 우선적으로 고려하는 것이 권장됩니다.