Rails 다중 데이터베이스 및 테넌시: 2025년 구현 전략

Rails Multi-Databases and Tenancy: How You Can Do It Today

작성자
발행일
2025년 09월 26일

핵심 요약

  • 1 Rails 애플리케이션에서 다중 데이터베이스를 활용하여 민감한 환자 데이터를 격리하고 읽기 복제본을 통해 확장하는 방법을 설명합니다.
  • 2 ActiveRecord::Tenanted 젬을 사용하여 다중 테넌트 아키텍처를 구현하고, 각 테넌트별 데이터베이스를 분리하는 과정을 상세히 다룹니다.
  • 3 ActiveRecord::Tenanted 젬의 현재 버전(0.3.0)에서 다중 테넌트 데이터베이스를 동시에 지원하는 데 따르는 제약사항과 이를 극복하기 위한 아키텍처 조정 방안을 제시합니다.

도입

애플리케이션이 성장함에 따라 데이터 확장성과 격리는 중요한 과제가 됩니다. 특히 의료 기록이나 금융 데이터와 같이 민감한 정보를 다룰 때, 특정 회사나 진료소의 데이터를 다른 데이터와 완전히 분리하는 것이 필수적입니다. 이 글은 Rails 8 환경에서 다중 데이터베이스와 테넌시를 구현하여 이러한 데이터 격리 문제를 해결하는 방법에 대해 심도 있게 탐구합니다. HealthCare Management 시스템을 예시로 들어, 각 진료소(Practice)가 자체적으로 격리된 데이터베이스를 갖도록 하는 접근 방식을 소개합니다.

다중 데이터베이스 구현

  • 데이터베이스 분리: Patient 모델의 민감한 데이터를 patients.sqlite3라는 별도의 데이터베이스로 분리합니다. 이를 위해 PatientsRecord라는 추상 클래스를 생성하고 connects_to database: { writing: :patients }를 사용하여 연결을 설정합니다.
  • 외래 키 제약: 데이터베이스 간 외래 키 제약은 작동하지 않으므로, appointmentspatients 테이블 간의 외래 키를 제거해야 합니다. 이로 인해 참조 무결성(Referential Integrity)이 상실되며, 고아 데이터(orphaned data) 방지는 애플리케이션 레이어에서 관리해야 합니다.
  • 읽기 복제본(Read Replica): 읽기 수요가 높은 테이블을 위해 patients_replica를 추가하여 읽기 전용 접근을 구현할 수 있습니다. connects_to database: { writing: :patients, reading: :patients_replica } 설정을 통해 읽기/쓰기 분할을 활성화하며, config.active_record.database_selector를 사용하여 자동 전환을 설정합니다.

ActiveRecord::Tenanted를 통한 다중 테넌시

  • 젬 도입: ActiveRecord::Tenanted 젬(v0.3.0)을 사용하여 각 테넌트(Practice)별 데이터베이스를 생성하고 관리합니다. config/database.yml에서 tenanted: true를 설정하고, ApplicationRecordtenanted :primary를 지정합니다.
  • 초기 문제점 및 아키텍처 조정: 초기에는 primarypatients 데이터베이스를 모두 테넌트화하려고 시도했으나, ActiveRecord::Tenanted 젬이 단일 연결 클래스에 맞춰 설계되어 있어 충돌이 발생했습니다. 이에 따라 Patient 모델은 ApplicationRecord 아래로 이동하여 primary 테넌트 데이터베이스의 일부가 되었습니다.
  • 최종 아키텍처:
    • GlobalRecord (글로벌 데이터베이스): Practice (테넌트 관리), Session (인증 세션)
    • ApplicationRecord (테넌트 데이터베이스 primary): User, Staff, Appointment, Patient
  • 구현 세부 사항:
    • PracticeSession 관련 외래 키 제약 조건 제거.
    • 로컬 환경에서 서브도메인 해결을 위한 config.action_dispatch.tld_length = 0 설정.
    • 다른 데이터베이스의 참조를 찾기 위한 사용자 정의 메서드(예: Practice#patients, Patient#practice) 추가.
    • Practice 생성 시 ApplicationRecord.create_tenant(slug)를 호출하여 테넌트 데이터베이스 생성.
  • 테넌트 전환: ApplicationRecord.current_tenant = "tenant_name" 명령을 통해 현재 테넌트를 변경하면, 해당 테넌트의 격리된 데이터베이스에서 쿼리가 실행됨을 확인했습니다.

결론

이 글은 Rails에서 다중 데이터베이스와 `ActiveRecord::Tenanted` 젬을 활용한 다중 테넌시 구현의 복잡성과 실용적인 해결책을 제시했습니다. 데이터 격리를 위해 `Patient` 모델을 별도 데이터베이스로 분리하고 읽기 복제본을 활용하는 방법을 살펴보았으며, `ActiveRecord::Tenanted`를 통해 각 테넌트별 데이터베이스를 관리하는 강력한 접근 방식을 소개했습니다. 비록 `ActiveRecord::Tenanted` 젬이 현재 다중 *테넌트 데이터베이스* 구조를 직접 지원하지 않는다는 제약이 있었지만, `GlobalRecord`와 단일 테넌트 `ApplicationRecord`를 결합한 아키텍처를 통해 효과적인 데이터 격리 및 테넌시를 달성할 수 있음을 보여주었습니다. 향후 `ActiveRecord::Tenanted`의 발전과 함께 더 유연한 다중 데이터베이스 테넌시 지원이 기대됩니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

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