마이그레이션 가이드: MVD에서 배열로
마이그레이션 가이드: MVD에서 배열로
Druid가 지원하는 SQL 호환 배열 타입과 multi-value dimension(MVD)의 차이, 그리고 MVD를 배열로 마이그레이션하는 방법을 소개해요. 배열과 MVD의 비교표와 쿼리·수집 예시를 다뤄요.
출처: 문서
본문
Druid는 이제 SQL 호환 배열 을 지원해요. 가능하면 언제나 multi-value dimension(MVD)보다 배열을 사용하는 것을 권장해요. 새 프로젝트와 여러 데이터 타입을 다루는 복잡한 사용 사례에서는 배열을 사용해요. MVD는 개별 요소를 일반 문자열처럼 직접 연산하는 특정 사용 사례에 사용해요. 행 내 값의 순서를 포함해 값의 전체 배열을 다루는 연산이라면, MVD보다 배열을 사용해요.
배열과 MVD 비교
다음 표는 배열과 MVD의 일반적인 동작을 비교해요. 배열과 MVD의 특정 쿼리 차이에 대해서는 Querying arrays and MVDs 문서를 참고해요.
| | Array | MVD |
| 데이터 타입 | VARCHAR, BIGINT, DOUBLE 타입 지원 (ARRAY
배열과 MVD 쿼리
SQL 쿼리에서 Druid는 배열을 MVD와 다르게 연산해요. 배열 컬럼의 값은 단일 배열 엔티티(SQL ARRAY)로 취급되는 반면, MVD 컬럼의 값은 개별 문자열(SQL VARCHAR)로 취급돼요. 이 동작은 같은 MVD 내의 여러 문자열 값이 여전히 MVD 컬럼에 단일 필드로 저장된다는 사실에도 적용돼요.
예를 들어 같은 값 ['a', 'b', 'c'] 를 배열 컬럼과 MVD 컬럼에 수집했다고 가정해요. 쿼리에서 어떤 값을 ['a', 'b', 'c'] 와 비교해 결과를 필터링하고 싶어요.
- 배열 컬럼의 경우, Druid는 동등 필터가 전체 배열과 일치할 때만 해당 행을 반환해요. 예: WHERE "array_column" = ARRAY['a', 'b', 'c'] .
- MVD 컬럼의 경우, Druid는 동등 필터가 MVD의 어떤 값과라도 일치하면 해당 행을 반환해요. 예를 들어 다음 필터 중 어느 것이든 쿼리에 해당 행을 반환해요: WHERE "mvd_column" = 'a' , WHERE "mvd_column" = 'b' , WHERE "mvd_column" = 'c' .
필터링이나 그룹화를 포함하는 쿼리를 작성할 때 배열과 MVD의 이 차이를 주의하세요.
쿼리가 필터와 그룹화를 모두 적용하면, MVD는 필터와 일치하지 않는 것처럼 보이는 행을 반환할 수 있어요. 그룹화가 Druid가 필터를 적용한 후에 발생하기 때문이에요. 예시는 Filter and group by array elements 문서를 참고해요.
예시
다음 예시들은 배열과 MVD 간의 몇 가지 유사한 쿼리를 보여줘요. 더 많은 정보와 예시는 Querying arrays 및 Querying multi-value dimensions 문서를 참고해요.
배열 요소로 필터링
배열 또는 MVD에서 특정 값을 가진 행을 필터링해요.
배열
SELECT label, tagsFROM "array_example"WHERE ARRAY_CONTAINS(tags, 't3')
MVD
SELECT label, tagsFROM "mvd_example"WHERE tags = 't3'
하나 이상의 요소로 필터링
배열 또는 MVD가 하나 이상의 요소를 포함하는 행을 필터링해요. ARRAY_OVERLAP 은 겹치는 요소 중 어느 것이든 확인하지만, 이전 예시의 ARRAY_CONTAINS 는 모든 요소가 포함되는지 확인한다는 점에 주의하세요.
배열
SELECT *FROM "array_example"WHERE ARRAY_OVERLAP(tags, ARRAY['t1', 't7'])
MVD
SELECT *FROM "mvd_example"WHERE tags = 't1' OR tags = 't7'
배열 동등성으로 필터링
배열 또는 MVD가 참조 배열과 동등한 행을 필터링해요.
배열
SELECT *FROM "array_example"WHERE tags = ARRAY['t1', 't2', 't3']
MVD
SELECT *FROM "mvd_example"WHERE MV_TO_ARRAY(tags) = ARRAY['t1', 't2', 't3']
배열로 결과 그룹화
배열 또는 MVD로 결과를 그룹화해요.
배열
SELECT label, tagsFROM "array_example"GROUP BY 1, 2
MVD
SELECT label, MV_TO_ARRAY(tags)FROM "mvd_example"GROUP BY 1, 2
배열 요소로 그룹화
개별 배열 또는 MVD 요소로 결과를 그룹화해요.
배열
SELECT label, stringsFROM "array_example" CROSS JOIN UNNEST(tags) as u(strings)GROUP BY 1, 2
MVD
SELECT label, tagsFROM "mvd_example"GROUP BY 1, 2
배열 요소로 필터링하고 그룹화
특정 값을 가진 행을 필터링한 다음 배열 또는 MVD의 요소로 그룹화해요. 이 예시는 필터링 결과가 배열과 MVD 사이에서 일치할 수 있지만, MVD는 값을 암시적으로 unnest하므로 GROUP BY 를 함께 적용하면 결과가 달라진다는 점을 보여줘요.
예를 들어 Filter by an array element 의 쿼리들을 고려해 보세요. 두 쿼리 모두 다음 행을 반환해요:
{"label":"row1","tags":["t1","t2","t3"]}{"label":"row2","tags":["t3","t4","t5"]}
그러나 두 쿼리 모두에 GROUP BY 1, 2 를 추가하면 출력이 달라져요. 두 쿼리는 이제:
-- ArraySELECT label, tagsFROM "array_example"WHERE ARRAY_CONTAINS(tags, 't3')GROUP BY 1, 2-- MVDSELECT label, tagsFROM "mvd_example"WHERE tags = 't3'GROUP BY 1, 2
배열 쿼리는 다음을 반환해요:
{"label":"row1","tags":["t1","t2","t3"]}{"label":"row2","tags":["t3","t4","t5"]}
MVD 쿼리는 다음을 반환해요:
{"label":"row1","tags":"t1"}{"label":"row1","tags":"t2"}{"label":"row1","tags":"t3"}{"label":"row2","tags":"t3"}{"label":"row2","tags":"t4"}{"label":"row2","tags":"t5"}
MVD 결과는 tags 가 t3 와 같지 않은 추가 행 네 개가 있는 것처럼 보여요. 그러나 이 행들은 Druid가 MVD에 대한 동등성을 평가하는 방식에 따라 필터와 일치해요.
MVD에 대한 동등한 쿼리를 위해서는 MV_FILTER_ONLY 함수를 사용해요:
SELECT label, MV_FILTER_ONLY(tags, ARRAY['t3'])FROM "mvd_example"WHERE tags = 't3'GROUP BY 1, 2
배열 수집 방법
모범 사례로, 데이터를 MVD가 아닌 배열로 저장해요.
다음과 같이 Druid에서 배열을 수집할 수 있어요:
- native 배치 및 스트리밍 수집의 경우 dimensionsSpec 에서 dimension을 구성해요. dimensionsSpec 내에서 "useSchemaDiscovery": true 를 설정하고, dimensions 를 사용해 type auto 의 배열 입력을 나열해요. 예시는 Ingesting arrays: Native batch and streaming ingestion 문서를 참고해요.
- SQL 기반 배치 수집의 경우 query context 파라미터 "arrayIngestMode": "array" 를 포함하고, 컬럼 이름과 데이터 타입을 나열하는 EXTEND 절에 해당 배열 타입( VARCHAR ARRAY , BIGINT ARRAY 또는 DOUBLE ARRAY )을 참조해요. 예시는 Ingesting arrays: SQL-based ingestion 문서를 참고해요.
MVD 수집 방법
같은 컬럼에서 배열과 MVD를 섞을 수 없어요. 계속 MVD를 사용해야 한다면, 데이터를 수집할 때 ARRAY_TO_MV 함수를 사용해요. 이렇게 하면 VARCHAR ARRAY 가 문자열 배열이 아닌 MVD로 저장되도록 보장해요. 기존 쿼리에서 계속 MVD를 사용하려면, 배열과 MVD가 다르게 동작하므로 MVD를 명시적으로 수집해야 해요.
ARRAY_TO_MV 사용 예시는 Multi-value dimensions: SQL-based ingestion 문서를 참고해요.
MVD 컬럼이 있고 배열 컬럼으로 마이그레이션하려면 데이터를 재인덱싱해 스키마를 업데이트해요. 재인덱싱은 새 데이터의 소스가 기존 데이터 자체일 때 기존 데이터를 덮어써요. How to ingest arrays 문서의 동일한 지침을 따르면 돼요.
더 알아보기 (Learn more)
- Querying arrays — 배열 쿼리 상세
- Multi-value dimensions — MVD 쿼리
- SQL 배열 함수 — 배열 함수 참고