Guava Table을 활용한 다차원 데이터 구조 설계

일반적으로 Guava의 Table 인터페이스는 두 개의 키(행과 열)를 사용해 값을 매핑하는 2차원 데이터 구조로 이해할 수 있다. 하지만 실제 업무 로직에서 우리는 종종 세 번째, 혹은 그 이상의 차원이 필요한 경우가 있다. 예를 들어, 시간, 지역, 카테고리, 지표 등 여러 축으로 데이터를 조회해야 할 때다.

Guava는 기본적으로 3차원 이상의 Table을 제공하지 않지만, 기존의 Table과 자바 컬렉션을 조합함으로써 다차원 데이터 모델을 효과적으로 시뮬레이션할 수 있다.

1. 중첩된 Table을 통한 3차원 데이터 표현

가장 직관적인 방법은 Table<R, C, V>의 값(V) 자리에 또 다른 Table을 배치하는 것이다. 이를 통해 "행-열-층" 구조와 유사한 3차원 접근이 가능하다.

예를 들어, 날짜별, 지역별, 지표별(매출, 이익 등) 통계 데이터를 관리하고자 할 때 다음과 같은 구조를 고려할 수 있다:

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.junit.jupiter.api.Test;

import java.util.Map;

public class ThreeDimensionalDataTest {

    @Test
    public void createThreeDimensionalStructure() {
        // 외부 Table: 날짜 → 지역 → (내부 Table)
        Table<String, String, Table<String, Integer>> timeRegionMetrics = HashBasedTable.create();

        // North 지역 데이터 구성
        Table<String, Integer> northMetrics = HashBasedTable.create();
        northMetrics.put("Revenue", 950);
        northMetrics.put("Margin", 180);

        // South 지역 데이터 구성
        Table<String, Integer> southMetrics = HashBasedTable.create();
        southMetrics.put("Revenue", 1100);
        southMetrics.put("Margin", 250);

        // 다중 차원에 데이터 삽입
        timeRegionMetrics.put("2024-11-20", "North", northMetrics);
        timeRegionMetrics.put("2024-11-20", "South", southMetrics);

        // 특정 지표 조회: 2024-11-20, North 지역의 수익
        Table<String, Integer> targetData = timeRegionMetrics.get("2024-11-20", "North");
        Integer revenue = targetData.get("Revenue");
        System.out.println("Revenue in North on 2024-11-20: " + revenue); // 출력: 950

        Integer margin = targetData.get("Margin");
        System.out.println("Profit Margin in North: " + margin); // 출력: 180
    }
}

이 방식은 논리적으로 세 번의 키를 거쳐 최종 값을 도달하게 되며, 사실상 3차원 배열과 유사한 사용성을 제공한다.

2. 다중 차원 순회 및 필터링

복잡한 데이터셋에서는 전체를 순회하거나 조건에 맞는 부분집합을 추출하는 작업이 빈번하다. 중첩된 Table 구조에서도 rowKeySet(), columnKeySet(), cellSet() 등을 활용해 깊이 있는 탐색이 가능하다.

@Test
public void traverseMultiDimensionalData() {
    Table<String, String, Table<String, Integer>> dataset = HashBasedTable.create();

    Table<String, Integer> eastQ4 = HashBasedTable.create();
    eastQ4.put("Sales", 3000);
    eastQ4.put("Cost", 2200);

    Table<String, Integer> westQ4 = HashBasedTable.create();
    westQ4.put("Sales", 2800);
    westQ4.put("Cost", 2000);

    dataset.put("Q4", "East", eastQ4);
    dataset.put("Q4", "West", westQ4);

    // 모든 차원 순회
    for (String period : dataset.rowKeySet()) {
        System.out.println("Period: " + period);
        for (String region : dataset.columnKeySet()) {
            System.out.println("  Region: " + region);
            Table<String, Integer> metrics = dataset.get(period, region);
            for (Map.Entry<String, Integer> metric : metrics.entrySet()) {
                System.out.println("    " + metric.getKey() + ": " + metric.getValue());
            }
        }
    }
}

이러한 반복문 패턴은 대시보드 데이터 로딩, 보고서 생성 등大批량 데이터 처리 시 유용하다.

3. Map과 결합한 4차원 이상 확장

더 많은 차원이 필요할 경우, Table 자체를 맵의 값으로 중첩하면 된다. 예를 들어 연도, 분기, 지역, 지표로 구성된 4차원 데이터는 다음과 같이 표현할 수 있다.

@Test
public void fourDimensionalWithMap() {
    // 연도 → (분기 → (지역 → 지표))
    Map<String, Table<String, String, Table<String, Integer>>> multiYearData = new java.util.HashMap<>();

    // 2024년 Q3 데이터 생성
    Table<String, String, Table<String, Integer>> q3Data = HashBasedTable.create();
    Table<String, Integer> centralMetrics = HashBasedTable.create();
    centralMetrics.put("UnitsSold", 450);
    centralMetrics.put("Returns", 23);
    q3Data.put("Q3", "Central", centralMetrics);

    // 2024년 데이터 저장
    multiYearData.put("2024", q3Data);

    // 2024년 Q3 Central 지역의 판매 수량 조회
    Table<String, Integer> result = multiYearData.get("2024").get("Q3", "Central");
    Integer units = result.get("UnitsSold");
    System.out.println("Units Sold in Central during Q3 2024: " + units); // 출력: 450
}

이처럼 MapTable을 계층적으로 조합하면 제약 없이 N차원 데이터 모델을 구현할 수 있으며, 특히 재무 분석, BI 리포팅, IoT 센서 데이터 처리와 같은 도메인에서 유연한 데이터 관리가 가능해진다.

정리

Guava의 Table은 본질적으로 2차원이지만, 중첩과 합성 기법을 통해 3차원 이상의 데이터 표현이 현실적으로 가능하다. 핵심은 각 단계에서 의미 있는 키를 부여하고, 접근 로직을 명확히 설계하는 것이다. 이러한 패턴은 코드의 가독성과 유지보수성을 높이며, 복잡한 비즈니스 요구사항에도 대응할 수 있는 견고한 기반을 제공한다.

태그: Guava Table 다차원 데이터 Java 컬렉션 중첩 구조

6월 18일 23:53에 게시됨