ActiveRecord는 .group
, .sum
, .joins
와 같은 집계 메서드를 제공하지만, 복잡한 보고서 쿼리에는 충분하지 않습니다. 이러한 경우, 임시 뷰처럼 데이터를 한 형태에서 다른 형태로 변환할 수 있는 CTE를 활용한 원시 SQL이 강력한 대안이 됩니다. 예를 들어, 메시지 팀별 열람률 보고서를 구축하는 과정에서 message_readership
, message_team_metrics
, team_readership
과 같은 CTE를 사용하여 데이터를 단계적으로 변환하고, 최종 결과를 TeamReadership
과 같은 Dry::Struct
객체로 매핑하여 타입 안정성을 확보할 수 있습니다. 이는 복잡한 SQL 쿼리에서 반환되는 모호한 해시 컬렉션을 다루는 것보다 훨씬 용이합니다.
더 나아가, 전체 대시보드를 구축하는 복잡한 시나리오에서는 전반적인 지표, 메시지별 지표, 팀별 지표 등 세 가지 수준의 메트릭을 단일 SQL 쿼리로 처리할 수 있습니다. 이를 위해 스테이징 CTE와 대시보드 CTE를 두 단계로 나누어 변환을 수행하며, Postgres의 JSON 함수를 사용하여 이 모든 지표를 하나의 JSON 문서로 반환합니다. 이 JSON 문서는 OverallMetric
, MessageMetric
, TeamMetric
과 같은 중첩된 Dry::Struct
객체로 쉽게 Hydrate되어 뷰 레이어에서 활용될 수 있습니다. 이 방식은 데이터의 구조화와 접근성을 크게 향상시킵니다.
또한, 기존 ActiveRecord 스코프를 SQL 쿼리에 주입하여 비즈니스 로직의 중복을 피하고 코드 재사용성을 높일 수 있습니다. 복잡한 SQL 쿼리의 성능 최적화를 위해서는 EXPLAIN
을 활용하여 병목 현상을 파악하고, 초기 필터링 적용, CTE 간 필터 중복, 그리고 CTE를 임시 테이블과 인덱스로 전환하는 전략을 사용할 수 있습니다.
원시 SQL의 사용은 Redshift, BigQuery, SnowFlake와 같은 데이터 웨어하우스에서 페타바이트 규모의 데이터를 활용하여 보고서와 대시보드를 생성할 수 있는 가능성을 열어줍니다. dry-struct
의 가장 큰 장점 중 하나는 데이터 형태를 데이터 소스로부터 분리한다는 것입니다. 이는 라이브 SQL 쿼리, 수동으로 작성된 YAML/JSON, 또는 Faker
기반의 제너레이터 등 다양한 소스에서 Dry::Struct
를 Hydrate할 수 있게 하여, 실제 데이터 접근 없이도 대시보드를 설계하고 테스트할 수 있는 강력한 유연성을 제공합니다. 이는 개발, 스테이징, 데모 환경에서 유용하며, 유닛 테스트 작성 시 데이터베이스를 Mocking할 필요 없이 테스트 값으로 Struct를 인스턴스화할 수 있게 합니다.