İki farklı dünya
| OLTP (işlem) | OLAP (analitik) | |
|---|---|---|
| Amaç | Uygulamayı çalıştırmak: sipariş al, stok düş | Analiz ve raporlama |
| Sorgu | Çok sayıda küçük okuma/yazma | Az sayıda büyük taramalı sorgu |
| Tasarım | Normalize (3NF) | Denormalize (yıldız/kar tanesi) |
| Depolama | Satır tabanlı | Sütun tabanlı |
| Örnek | PostgreSQL, MySQL, SQL Server | Snowflake, BigQuery, Redshift, ClickHouse |
Yıldız şema (star schema)
- Fact (olgu) tablosu: Ölçülebilir olaylar ve sayısal metrikler. Ör.
fact_sales(date_key, product_key, customer_key, quantity, revenue). Çok satırlı, dar. - Dimension (boyut) tabloları: Olayların bağlamı.
dim_date,dim_product,dim_customer. Az satırlı, geniş, açıklayıcı. - Fact ortada, dimension'lar etrafında: yıldız. Dimension'lar da normalize edilirse kar tanesi (snowflake) şema.
Tanecik (grain): Fact tablosundaki bir satır tam olarak neyi temsil eder? “Bir sipariş satırı” mı, “günlük ürün özeti” mi? Modellemenin ilk ve en önemli kararıdır.
Anadolu Market için küçük bir yıldız
CREATE TABLE dim_date AS
SELECT DISTINCT order_date AS date_key,
CAST(strftime('%Y', order_date) AS INTEGER) AS year,
CAST(strftime('%m', order_date) AS INTEGER) AS month,
FLOOR((CAST(strftime('%m', order_date) AS INTEGER) + 2) / 3) AS quarter
FROM orders;
CREATE TABLE fact_sales AS
SELECT o.order_date AS date_key, oi.product_id, o.customer_id,
oi.quantity, oi.quantity * oi.unit_price * (1 - oi.discount) AS revenue
FROM orders o JOIN order_items oi ON oi.order_id = o.order_id
WHERE o.status = 'delivered';
SELECT d.year, d.quarter, ROUND(SUM(f.revenue)) AS ciro
FROM fact_sales f JOIN dim_date d ON d.date_key = f.date_key
GROUP BY d.year, d.quarter
ORDER BY d.year, d.quarter;