-- ============================================
-- Bronze: Streaming Table (원본 데이터 수집)
-- ============================================
CREATE OR REFRESH STREAMING TABLE bronze_orders
AS SELECT * FROM STREAM read_files(
'/volumes/catalog/schema/landing/orders/',
format => 'json'
);
CREATE OR REFRESH STREAMING TABLE bronze_customers
AS SELECT * FROM STREAM read_files(
'/volumes/catalog/schema/landing/customers/',
format => 'json'
);
-- ============================================
-- Silver: Streaming Table (데이터 정제)
-- ============================================
CREATE OR REFRESH STREAMING TABLE silver_orders (
CONSTRAINT valid_order_id EXPECT (order_id IS NOT NULL) ON VIOLATION DROP ROW,
CONSTRAINT positive_amount EXPECT (amount > 0) ON VIOLATION DROP ROW
)
AS SELECT
CAST(order_id AS BIGINT) AS order_id,
CAST(customer_id AS BIGINT) AS customer_id,
CAST(amount AS DECIMAL(12,2)) AS amount,
CAST(order_date AS TIMESTAMP) AS order_date,
CAST(status AS STRING) AS status
FROM STREAM(bronze_orders);
-- Silver: CDC 처리
CREATE OR REFRESH STREAMING TABLE silver_customers;
APPLY CHANGES INTO silver_customers
FROM STREAM(bronze_customers)
KEYS (customer_id)
SEQUENCE BY updated_at
STORED AS SCD TYPE 1;
-- ============================================
-- Gold: Materialized View (비즈니스 집계)
-- ============================================
CREATE OR REFRESH MATERIALIZED VIEW gold_daily_revenue
AS SELECT
DATE(o.order_date) AS sale_date,
COUNT(*) AS order_count,
SUM(o.amount) AS total_revenue,
AVG(o.amount) AS avg_order_value
FROM silver_orders o
GROUP BY DATE(o.order_date);
CREATE OR REFRESH MATERIALIZED VIEW gold_customer_orders
AS SELECT
c.customer_id,
c.name AS customer_name,
c.city,
COUNT(o.order_id) AS total_orders,
SUM(o.amount) AS total_spent,
MAX(o.order_date) AS last_order_date
FROM silver_customers c
LEFT JOIN silver_orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.name, c.city;