동적 테이블 만들기
동적 테이블 만들기
이 튜토리얼은 동적 테이블(dynamic table)을 만들고 그것을 두 테이블 파이프라인에 연결하는 방법을 보여줘요.
전체 구문 참조는 CREATE DYNAMIC TABLE 문서를 참조하세요.
📌 이 튜토리얼은 테이블을 만들고
SELECT쿼리를 작성하는 방법을 안다고 가정해요. Snowflake가 처음이라면 먼저 20분 만에 배우는 Snowflake 튜토리얼을 완료하세요.
이 페이지의 예시는 CREATE OR ALTER DYNAMIC TABLE을 사용해요. 이 명령은 동적 테이블이 없으면 만들고, 있으면 정의와 일치하도록 변경해요. 프로덕션 데이터에 의도치 않은 변경을 피하려면 테스트 데이터베이스와 스키마에서 실행하세요.
출처: Snowflake 문서
본문
시작하기 전에
웨어하우스와 스키마에 USAGE, target 스키마에 CREATE DYNAMIC TABLE 권한이 있는지 확인하세요. 전체 요구 사항은 동적 테이블 접근 제어 문서를 참조하세요.
기본 테이블 설정
기본 테이블과 차원 테이블을 만들고 샘플 데이터를 삽입해 이 페이지의 모든 예시를 복사해 실행할 수 있게 하세요:
CREATE OR REPLACE TABLE raw_orders (
order_id INT,
customer_id INT,
order_date TIMESTAMP_NTZ,
product_name VARCHAR,
quantity INT,
unit_price DECIMAL(10,2),
order_status VARCHAR,
CONSTRAINT pk_raw_orders PRIMARY KEY (order_id) RELY
);
INSERT INTO raw_orders (order_id, customer_id, order_date, product_name, quantity, unit_price, order_status)
VALUES
(1001, 1, '2025-01-15 08:30:00', 'Widget A', 3, 29.99, 'completed'),
(1002, 2, '2025-01-15 09:45:00', 'Widget B', 1, 49.99, 'completed'),
(1003, 1, '2025-01-15 14:20:00', 'Widget A', 2, 29.99, 'pending'),
(1004, 3, '2025-01-16 10:00:00', 'Gadget X', 5, 12.50, 'completed'),
(1005, 2, '2025-01-16 11:30:00', 'Widget B', 1, 49.99, 'returned');
이 튜토리얼의 다운스트림 동적 테이블도 차원 테이블에 조인해요. 그 테이블을 지금 만드세요:
CREATE OR REPLACE TABLE dim_customers (
customer_id INT,
customer_name VARCHAR,
region VARCHAR,
segment VARCHAR,
CONSTRAINT pk_dim_customers PRIMARY KEY (customer_id) RELY
);
INSERT INTO dim_customers (customer_id, customer_name, region, segment)
VALUES
(1, 'Acme Corp', 'US-West', 'Enterprise'),
(2, 'Globex Inc', 'US-East', 'Mid-Market'),
(3, 'Initech LLC', 'EU-West', 'Startup');
💡 기본 키는 선택 사항이지만 증분 갱신 성능을 개선해요. 두 기본 테이블 모두
RELY가 있는PRIMARY KEY를 선언해 갱신 중 Snowflake가 변경된 행을 식별할 수 있게 해요. 자세한 내용은 기본 키 모범 사례 문서를 참조하세요.
동적 테이블 만들기
반환된(returned) 주문을 걸러 내고 각 행에 라인 합계(line total)를 계산하는 동적 테이블을 만들려면 다음 문을 실행하세요:
CREATE OR ALTER DYNAMIC TABLE dt_orders
TARGET_LAG = '10 minutes'
WAREHOUSE = transform_wh
REFRESH_MODE = INCREMENTAL
AS
SELECT
order_id,
customer_id,
order_date,
TRIM(UPPER(product_name)) AS product_name,
quantity,
unit_price,
quantity * unit_price AS line_total,
order_status
FROM raw_orders
WHERE order_status != 'returned';
📌
REFRESH_MODE를 생략하면 기본값은AUTO이며 Snowflake가 생성 시점에 증분 또는 전체 갱신을 선택해요. 이 튜토리얼은 재생성 간에 갱신 모드가 결정적이도록 명시적으로REFRESH_MODE = INCREMENTAL을 설정해요. 각 모드의 동작에 대한 자세한 내용은 동적 테이블 갱신 모드 문서를 참조하세요.
테이블 이름 외의 핵심 매개 변수는:
TARGET_LAG: 데이터의 신선도 목표예요. Snowflake는 데이터가 소스보다 10분 이상 뒤처지지 않도록 갱신을 스케줄해요. 실제 지연은 갱신 실행 시간에 따라 이를 초과할 수 있어요.WAREHOUSE: 예약 갱신을 실행하는 컴퓨팅 리소스예요.REFRESH_MODE: Snowflake가 변경을 처리하는 방식을 결정해요.INCREMENTAL은 변경된 행만 다시 처리하고,FULL은 갱신할 때마다 전체 테이블을 처음부터 갱신해요. 다음 비고를 참조하세요.
동적 테이블은 생성 직후 기본적으로 초기화돼요.
📌 예상치 못한 갱신 모드 변경을 피하려면 프로덕션 워크로드에는
REFRESH_MODE를 명시적으로 설정하세요. 자세한 내용은 갱신 모드 선택 문서를 참조하세요.
SHOW DYNAMIC TABLES로 확인
CREATE 문은 해결된 갱신 모드를 보고하지 않아요. SHOW DYNAMIC TABLES를 실행해 모드를 확인하고 scheduling_state가 RUNNING인지 확인하세요:
SHOW DYNAMIC TABLES LIKE 'dt_orders';
+------------+-----+--------------+---------------------+------------------+--------------+-----+
| name | ... | refresh_mode | refresh_mode_reason | scheduling_state | warehouse | ... |
|------------+-----+--------------+---------------------+------------------+--------------+-----|
| DT_ORDERS | ... | INCREMENTAL | NULL | RUNNING | TRANSFORM_WH | ... |
+------------+-----+--------------+---------------------+------------------+--------------+-----+
refresh_mode가 예상한 모드를 보여주고 scheduling_state가 RUNNING인지 확인하세요.
다운스트림 동적 테이블 추가
다운스트림 동적 테이블은 기본 테이블 대신 다른 동적 테이블에서 읽어요. 이 다운스트림 테이블은 dt_orders를 dim_customers와 조인하고 리전·세그먼트별 일일 수익을 집계해요:
CREATE OR ALTER DYNAMIC TABLE dt_orders_daily
TARGET_LAG = '30 minutes'
WAREHOUSE = transform_wh
REFRESH_MODE = INCREMENTAL
AS
SELECT
s.order_date::DATE AS order_day,
c.region,
c.segment,
COUNT(*) AS order_count,
SUM(s.line_total) AS daily_revenue
FROM dt_orders s
JOIN dim_customers c ON s.customer_id = c.customer_id
GROUP BY ALL;
Snowflake는 동적 테이블 간 의존성을 추적하고 올바른 순서로 자동으로 갱신해요(파이프라인 순서 참조). 그래서 dt_orders는 항상 dt_orders_daily보다 먼저 갱신돼요.
📌 다운스트림 동적 테이블의
TARGET_LAG는 그것이 의존하는 동적 테이블의TARGET_LAG보다 크거나 같아야 해요. 이 예시에서dt_orders_daily(30분)는dt_orders(10분)보다 커요. 자세한 내용은 동적 테이블의 target lag 설정 문서를 참조하세요.
파이프라인 출력 쿼리
SELECT * FROM dt_orders_daily ORDER BY order_day, region;
+------------+---------+------------+-------------+---------------+
| ORDER_DAY | REGION | SEGMENT | ORDER_COUNT | DAILY_REVENUE |
|------------+---------+------------+-------------+---------------|
| 2025-01-15 | US-East | Mid-Market | 1 | 49.99 |
| 2025-01-15 | US-West | Enterprise | 2 | 149.95 |
| 2025-01-16 | EU-West | Startup | 1 | 62.50 |
+------------+---------+------------+-------------+---------------+
dt_orders는 반환된 주문(주문 1005)을 제외하므로 집계 결과에 나타나지 않아요.
만든 파이프라인을 시각화하려면 Snowsight에서 Transformation » Dynamic tables로 이동해 파이프라인의 아무 테이블이나 선택하고 Graph 탭을 열어요. 파이프라인 시각화에 대한 자세한 내용은 Snowsight에서 파이프라인 그래프 보기 문서를 참조하세요.
갱신 기록 확인
쿼리 출력을 확인한 후 갱신이 성공적으로 완료되는지 확인하세요:
SELECT name, state, state_message, refresh_trigger, refresh_action, data_timestamp
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORY())
WHERE name IN ('DT_ORDERS', 'DT_ORDERS_DAILY')
ORDER BY data_timestamp DESC
LIMIT 10;
갱신 상태를 모니터링하고 알림을 설정하고 실패를 트러블슈팅하는 더 많은 방법은 동적 테이블 모니터링 문서를 참조하세요.
일반적인 문제 트러블슈팅
동적 테이블에 데이터가 없음(Dynamic table shows no data): 동적 테이블이 성공적으로 생성됐는데 행이 반환되지 않으면, 쿼리를 독립 SELECT로 실행했을 때 데이터를 반환하는지 확인하세요. 흔한 원인은 현재 모든 행을 걸러 내는 WHERE 절이에요. 또한 확인하세요:
- 테이블이 다른 역할에 의해 생성됐다면 현재 역할에 대해 접근 또는 마스킹 정책이 데이터를 다르게 필터링할 수 있어요.
- 올바른 웨어하우스, 데이터베이스, 스키마 컨텍스트가 있고 기본 테이블에
SELECT권한이 있는지 확인하세요.
갱신 모드가 INCREMENTAL 대신 FULL임(Refresh mode is FULL instead of INCREMENTAL): SHOW DYNAMIC TABLES가 INCREMENTAL을 기대했는데 FULL로 보여주면 정의에 증분 갱신을 지원하지 않는 SQL 기능이 있는 거예요. refresh_mode_reason 컬럼을 확인하고, 지원되는 쿼리 패턴의 전체 목록은 동적 테이블 지원 쿼리 문서를 참조하세요.
정리
테스트 목적으로 이 객체들을 만들었다면 예약 갱신으로 인한 지속적인 웨어하우스 비용을 피하기 위해 삭제하세요:
DROP DYNAMIC TABLE IF EXISTS dt_orders_daily;
DROP DYNAMIC TABLE IF EXISTS dt_orders;
DROP TABLE IF EXISTS dim_customers;
DROP TABLE IF EXISTS raw_orders;
다음 단계
- 워크로드의 target lag 선택: 동적 테이블의 target lag 설정
- 증분 대 전체 갱신 이해: 동적 테이블 갱신 모드
- 갱신 기록 모니터링 및 실패 트러블슈팅: 동적 테이블 모니터링
- DROP 의미 없이 동적 테이블을 멱등적으로 생성·수정: 동적 테이블 수정