Ruby on Rails 7.1은 복합 기본 키(Composite Primary Keys, CPK)에 대한 네이티브 지원을 도입하며 데이터베이스 스키마 설계에 새로운 유연성을 제공합니다. 기존의 단일 컬럼 기본 키가 일상적인 데이터 관리에 효율적인 자전거와 같다면, 복합 기본 키는 복잡한 관계형 데이터를 표현하고 대규모 시스템에서 성능을 최적화하는 데 필수적인 SUV와 같습니다. 본 강연에서는 복합 기본 키의 기본 개념부터 실제 활용 사례, 다중 테넌트 애플리케이션에서의 이점 및 제약 사항, 그리고 Rails 7.1에서 이를 효과적으로 구현하는 방법에 대해 심층적으로 다룹니다.
복합 기본 키는 두 개 이상의 컬럼 조합으로 테이블 행을 고유하게 식별하며, 단일 키로는 표현하기 어려운 복잡한 관계를 정의하는 데 필수적입니다. 가장 대표적인 활용 사례는 다대다 관계를 연결하는 조인 테이블입니다. 예를 들어, 블로그 게시물과 태그의 관계를 나타내는 조인 테이블에서 게시물 ID
와 태그 ID
를 묶어 복합 기본 키로 사용하면 각 고유 연관성을 보장할 수 있습니다. 복합 기본 키의 사용은 데이터베이스 스키마 설계의 필요에 따라 전략적으로 결정되어야 합니다.
특히 Shopify와 같은 다중 테넌트 애플리케이션에서 복합 기본 키는 성능 최적화에 큰 이점을 제공합니다. 기존 단일 ID
방식은 여러 테넌트의 레코드가 디스크에 분산 저장되어 조회 비효율을 야기합니다. 복합 기본 키에 테넌트 키(tenant key)
를 포함하면 동일 테넌트의 데이터가 디스크에 물리적으로 그룹화되어 쿼리 성능이 크게 향상됩니다. Shopify의 실제 사례에서는 쿼리 응답 시간이 5~6배 단축되고 느린 쿼리 수가 80% 감소하는 등 상당한 개선을 보였습니다. 다만, 이는 데이터 삽입 속도가 약 10배 느려지는 트레이드오프를 수반하므로, 조회 빈도가 삽입보다 높은 시스템에 적합합니다. 복합 기본 키에 테넌트 키를 포함하는 것은 향후 테넌트 기반 샤딩 전략으로의 전환을 용이하게 할 수 있습니다.
Rails 7.1의 Active Record는 복합 기본 키를 위한 강력한 네이티브 지원을 제공합니다. create_table
의 primary_key
옵션으로 복합 기본 키를 정의하며, id
메서드는 전체 식별자를 배열로 반환합니다. find
, reload
, update
, delete
등은 복합 기본 키의 모든 구성 요소를 활용합니다. 기존 ID
컬럼과의 충돌 해소를 위해 id_value
속성 별칭이 도입되었고, where
메서드는 튜플 구문(tuple syntax)을 지원합니다. 연관 관계에서는 query_constraints
옵션을 통해 복합 외래 키를 효율적으로 정의합니다. 데이터베이스 스키마 변경이 어려운 경우, query_constraints
를 ‘가상 기본 키’로 활용하여 특정 컬럼(예: 테넌트 키)이 모든 쿼리에 자동으로 포함되도록 할 수 있으며, 이는 다중 테넌트 환경에서 특히 유용합니다.
결론적으로, 복합 기본 키는 Rails 7.1에서 제공하는 강력한 기능으로, 데이터베이스 스키마의 요구 사항과 애플리케이션의 특정 워크로드에 따라 신중하게 사용되어야 합니다. 특히 조인 테이블이나, 쿼리 성능이 삽입 속도보다 중요한 다중 테넌트 애플리케이션에서 그 진가를 발휘합니다. `query_constraints`를 가상 기본 키로 활용하여 데이터 분리 또는 샤딩 준비를 위해 쿼리에 테넌트 키를 포함시키는 유연한 방법으로 사용할 수 있습니다.