ClickHouse — 열 지향 분석 DB 를 속까지 · 구체화 뷰는 INSERT 트리거 · 퀴즈
퀴즈: 구체화 뷰는 트리거다
6문항. 정답과 해설은 풀어 본 뒤에 보여 드립니다.
원천 표에 20만 행이 있는 상태에서 `CREATE MATERIALIZED VIEW ... TO target AS SELECT ...` 를 (POPULATE 없이) 만들었다. 직후 target 에는 무엇이 있나?
- 원천 20만 행을 SELECT 로 변환한 결과 전체
- 아무것도 없다 — 뷰는 이후에 들어오는 INSERT 블록만 처리한다
- 첫 조회가 들어올 때 원천 전체를 계산해 채운다
- 백그라운드 병합이 돌 때 원천 파트를 하나씩 읽어 채운다
뷰가 2차분(9월 16–30일)을 처리한 뒤, 되채우기로 `INSERT INTO daily_sales SELECT ... FROM orders GROUP BY day, shop` 을 WHERE 없이 실행했다. 결과는?
- 9월 1–15일만 새로 채워지고 나머지는 그대로다
- SummingMergeTree 가 같은 날의 중복을 알아서 버린다
- 9월 16–30일의 주문·매출이 두 번 더해진다
- 뷰와 충돌해 INSERT 가 오류로 거절된다
대상 표 daily_sales 를 `SELECT orders FROM daily_sales WHERE shop = 'a' AND day = '2026-09-03'` 로 읽는 코드가 가끔 두 줄을 돌려준다. 올바른 고침은?
- sum(orders) 와 GROUP BY 로 조회에서 다시 더한다
- 뷰의 SELECT 에서 GROUP BY 를 빼 원시 행을 그대로 보낸다
- 대상 표 엔진을 MergeTree 로 바꿔 중복이 생기지 않게 한다
- INSERT 마다 OPTIMIZE TABLE ... FINAL 을 뒤따라 실행한다
상점별 한 달 고유 구매자를 구체화 뷰로 미리 계산하려 한다. 대상 표에 무엇을 저장해야 하나?
- 날마다의 uniqExact(user_id) 결과를 UInt64 로 저장하고 조회 때 더한다
- user_id 의 최댓값과 최솟값을 저장해 조회 때 범위로 센다
- user_id 를 그대로 복사해 두고 조회 때 원천처럼 센다
- uniqExactState 상태를 AggregateFunction 열에 담고 조회 때 uniqExactMerge 로 합친다
`ENGINE = Null` 표 raw 에 뷰 raw_mv(TO orders)가 걸려 있고, orders 에는 daily_sales_mv 가 걸려 있다. raw 에 5만 행을 INSERT 하면?
- raw 에 5만 행이 저장되고, 두 뷰는 다음 백그라운드 병합 때 차례로 돈다
- raw 는 비어 있고, orders 에 들어간 INSERT 가 daily_sales_mv 까지 깨운다
- Null 표는 INSERT 를 곧바로 버리므로 raw_mv 를 포함해 어떤 뷰도 돌지 않는다
- raw_mv 만 돌고, 뷰가 쓴 INSERT 는 다른 뷰를 깨우지 않아 daily_sales 는 그대로다
주문 표를 상품 표와 INNER JOIN 해 범주별 집계를 내는 뷰가 있다. 신상품 주문이 들어온 뒤 그 상품이 상품 표에 등록되었다. 범주 집계는 어떻게 되나?
- 상품 표의 INSERT 가 뷰를 깨워 빠졌던 주문이 채워진다
- 다음 백그라운드 병합 때 조인이 다시 계산된다
- 빠진 주문은 그대로다 — 방아쇠는 맨 왼쪽 표의 INSERT 뿐이다
- 조회할 때 FINAL 을 붙이면 조인이 다시 계산된다