바이템포럴 데이터 모델로 Rails 애플리케이션에서 이력 관리 구현 및 운영

履歴 on Rails : Bitemporal Data Modelで実現する履歴管理 / hypermkt - Kaigi on Rails 2025

작성자
Kaigi on Rails
발행일
2025년 11월 25일

핵심 요약

  • 1 바이템포럴 데이터 모델은 유효 기간과 시스템 기간 두 가지 시간 축을 통해 현실과 시스템의 이력을 정확하게 기록하고 특정 시점의 상태를 재현할 수 있습니다.
  • 2 Ruby on Rails 환경에서는 `active_record_bitemporal` Gem을 활용하여 복잡한 바이템포럴 데이터 모델을 Active Record 친화적으로 구현하고 관리할 수 있습니다.
  • 3 바이템포럴 모델 운영 시 데이터 조사 및 사양 복잡성 등의 도전 과제가 발생하며, 시각화 도구와 스프레드시트, 그리고 날짜 타입 변경 등의 전략으로 이를 해결할 수 있습니다.

도입

본 발표는 클라우드 기반 인사 노무 소프트웨어인 스마트HR에서 이력 관리 기능을 개발하고 운영하며 얻은 경험과 지식을 공유합니다. 이력 관리는 '언제 무엇이 어떻게 바뀌었는지 나중에 추적하는 시스템'으로 정의되며, 기존의 버전형이나 유효 기간형 모델이 가진 한계를 극복하고 인사 정보의 복잡한 요구사항을 충족시키기 위해 바이템포럴 데이터 모델의 필요성을 제기합니다.

이력 관리의 기본 및 기존 모델의 한계

  • 이력 관리 정의: 언제 무엇이 어떻게 바뀌었는지 나중에 추적하는 시스템.

  • 기존 시스템 이력 관리 방식:
    • 버전형: 변경 시마다 새로운 레코드를 등록하는 방식. 과거 이력 추적에는 용이하나, 최신 버전을 식별하기 위한 조건이 항상 필요하며 레코드 수가 증가합니다.
    • 유효 기간형 (Unitemporal): 정보가 언제부터 언제까지 유효했는지를 기록하는 방식. 특정 시점의 상태 재현에는 유리하나, 시스템에 정보가 등록된 시점에 대한 정보가 없어 사후에 등록된 이력을 파악하기 어렵습니다.
  • 인사 소프트웨어의 요구사항: 직원을 기점으로 한 정보의 추이(부서 변경, 주소 변경 등)를 파악하고, 특정 시점의 상태를 정확하게 알아야 하며, 늦게 파악된 사실도 올바른 날짜로 반영할 수 있어야 합니다.

바이템포럴 데이터 모델의 이해

  • 개념: 유효 기간(Valid-time, 현실에서 사실이 유효했던 기간)과 시스템 기간(Transaction-time, 시스템에 정보가 존재했던 기간)이라는 두 가지 시간 축을 동시에 관리하는 데이터 모델입니다. 이를 통해 현실의 사건과 시스템의 인식 모두를 정확하게 기록할 수 있습니다.

  • 테이블 구조: 일반적으로 유효 시작일/종료일, 시스템 시작일/종료일, 그리고 동일 이력을 그룹화하기 위한 이력 ID 컬럼을 포함합니다.

  • 데이터 조작: 데이터 변경 시, 기존 레코드의 시스템 종료일을 업데이트하여 논리적으로 종료하고, 변경된 내용과 이전 내용에 해당하는 새로운 레코드를 추가하는 방식으로 이력을 유지합니다. 이는 일반적인 DB의 UPDATE와 달리 이력을 남기면서 추가하는 동작입니다.

  • 최신 정보 조회: 현재 시점을 기준으로 유효 기간과 시스템 기간 모두 유효한 레코드를 조회하여 정확한 최신 정보를 얻을 수 있습니다.

바이템포럴 모델의 장단점

  • 장점: 특정 시점의 상태를 정확하게 재현할 수 있으며, 사후에 파악된 사실도 올바른 날짜로 반영할 수 있습니다. 또한, 이력을 삭제하지 않고 모두 보존하므로 감사 및 조사에 매우 유리합니다.

  • 단점: SQL 쿼리가 복잡해지고, 데이터 변경 시 레코드 수가 증가하여 테이블 크기가 커집니다.

Ruby on Rails에서의 바이템포럴 구현: active_record_bitemporal Gem

  • 기능: Active Record에서 바이템포럴 데이터 모델을 자연스럽게 다룰 수 있도록 돕는 Gem입니다.

  • 특징:
    • 컬럼 추가 및 모델에 include하는 방식으로 쉽게 도입할 수 있습니다.
    • find, update 등 익숙한 Active Record 메서드와의 호환성을 제공합니다.
    • 이력을 조작하고 접근하기 위한 다양한 메서드를 제공하여 복잡한 바이템포럴 모델을 개발자가 최소한으로 의식하며 다룰 수 있도록 추상화합니다.
  • 사용 예시: createupdate 메서드 사용 시, Gem이 내부적으로 복잡한 SQL(논리적 삭제 및 새 레코드 삽입)을 처리합니다. Employee.all과 같이 조회 시에는 Gem이 자동으로 현재 시점을 기준으로 유효한 최신 레코드를 필터링하며, valid_at 메서드를 통해 특정 과거 시점의 이력 데이터를 쉽게 조회할 수 있습니다.

바이템포럴 운영 시 도전 과제 및 해결 방안

  • 데이터 조사 어려움: 복잡한 이력 데이터 구조로 인해 문제 발생 시 원인 파악에 시간이 오래 걸립니다.
    • 해결: active_record_bitemporal Gem이 제공하는 visualize 메서드를 활용하여 유효 기간과 시스템 기간의 2축으로 이력 형태를 시각화합니다. 또한, Google 스프레드시트를 이용한 ‘이력 그리기’를 통해 데이터 변화를 시각적으로 이해하고 엔지니어, PM, 서포트 간의 커뮤니케이션 도구로 활용합니다.
  • 이력 사양 복잡성: 유효 기간을 초 단위 timestamp로 관리하여 동일 날짜의 변경도 시간 차이로 인해 별개의 이력으로 처리되어 불필요하게 복잡해지는 문제가 있었습니다.
    • 해결: 유효 기간의 날짜 관리 단위를 timestamp에서 date 타입으로 변경하여 동일 날짜의 변경을 묶음으로 처리함으로써 표시를 간소화하고 개발자의 혼란을 줄여 개발 생산성 향상에 기여했습니다.
  • 불필요한 모델 적용: 과거 결정으로 인해 바이템포럴 모델이 불필요한 모델에까지 적용된 경우가 있습니다. 데이터 이관의 어려움으로 아직 해결하지 못했지만, 향후 개선을 검토 중입니다.

결론

바이템포럴 데이터 모델은 특정 시점의 상태를 정확하게 재현하고 이력을 효과적으로 관리하는 데 매우 강력한 솔루션입니다. Ruby on Rails 환경에서는 `active_record_bitemporal` Gem을 통해 이러한 복잡한 모델을 비교적 쉽게 구현하고 활용할 수 있습니다. 그러나 도입에는 학습 비용이 따르고, 한 번 도입하면 되돌리기 어렵다는 점을 고려하여, 실제 필요성 및 적용 범위를 신중하게 검토하는 것이 중요합니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!