Warehouse inti yang dibangun melalui bab-bab sebelumnya melayani seluruh organisasi: satu tempat untuk fact, dimensi, dan snapshot lintas domain. Namun tim penjualan hanya butuh potongan penjualan per kategori, tim keuangan butuh pendapatan dan pajak, sementara tim marketing butuh kampanye dan kohort pelanggan. Memaksa semua tim bekerja langsung di warehouse inti membuat query rumit, izin sulit diberikan per tim, dan masing-masing tetap menulis agregasi sendiri. Data mart adalah lapisan distribusi: potongan warehouse yang dibentuk khusus untuk satu departemen.
Mart per Departemen #
Data mart menyalin atau meringkas data warehouse ke bentuk yang langsung siap dipakai satu tim. Tim penjualan menerima tabel lebar mart_penjualan berisi bulan, kategori, jumlah pesanan, dan total penjualan — tanpa perlu memahami surrogate key atau join lima dimensi. Tim keuangan menerima mart_keuangan dengan pendapatan, pajak, dan metode pembayaran. Setiap mart memilih kolom, grain, dan istilah yang sesuai bahasa departemennya.
Pendekatan per departemen memberi tiga manfaat konkret: query analisis menjadi sederhana karena bentuk data sudah sesuai kebutuhan, kontrol akses bisa diberikan per mart sehingga data gaji tidak ikut tersebar, dan beban query dashboard satu tim tidak mengganggu tim lain karena mart bisa ditempatkan pada database terpisah.
Bentuk mart juga tidak harus meniru warehouse. Mart penjualan bisa berupa star schema kecil, tabel lebar satu-grain, atau tabel agregat siap grafik; pilihan bentuk mengikuti pertanyaan yang paling sering diajukan departemen pemilik mart. Frekuensi penyegaran pun berbeda antar tim: keuangan cukup diperbarui harian, sedangkan tim kampanye bisa meminta mart menyala per jam saat event berlangsung.
Dependent vs Independent Mart #
Pertanyaan arsitektur terpenting: mart dibangun dari warehouse inti, atau langsung dari sistem operasional? Mart yang lahir dari warehouse disebut dependent mart; mart yang menarik sendiri dari sumber disebut independent mart.
| Aspek | Dependent Mart | Independent Mart |
|---|---|---|
| Sumber data | warehouse inti | sistem operasional langsung |
| Konsistensi antar mart | tinggi, satu sumber kebenaran | rendah, definisi bisa berbeda |
| Ketergantungan pipeline | menunggu warehouse siap | mandiri, berjalan lebih awal |
| Beban pada sistem sumber | tidak menyentuh OLTP | menambah beban transaksi |
| Cocok untuk | organisasi dengan warehouse matang | kebutuhan cepat di awal |
Trade-off inti keduanya adalah konsistensi berhadapan dengan kecepatan. Dependent mart menjamin seluruh departemen membaca angka dari definisi yang sama karena warehouse menjadi satu-satunya pemasok, tetapi mart baru tidak bisa berjalan sebelum pipeline warehouse inti siap. Independent mart sanggup berdiri dalam hitungan hari tanpa menunggu warehouse, namun setiap mart yang menarik sendiri dari sumber berpotensi menyimpang dari mart lain — dan angka antar departemen justru sulit dipertemukan kembali di rapat pimpinan.
Contoh: mart_penjualan dari fact_pesanan #
Kita bangun dependent mart dari star schema kecil. Warehouse inti memuat fact_pesanan plus dua dimensi; mart penjualan dirakit dengan satu pernyataan CREATE TABLE AS SELECT (CTAS) yang menggabungkan fakta ke dimensi lalu mengagregasi per bulan dan kategori.
import sqlite3
koneksi = sqlite3.connect(":memory:")
cur = koneksi.cursor()
# --- Warehouse inti: star schema hasil Chapter Star Schema ---
cur.executescript("""
CREATE TABLE dim_produk (
sk_produk INTEGER PRIMARY KEY,
nama_produk TEXT NOT NULL,
kategori TEXT NOT NULL
);
CREATE TABLE dim_pelanggan (
sk_pelanggan INTEGER PRIMARY KEY,
nama TEXT NOT NULL,
kota TEXT NOT NULL
);
CREATE TABLE fact_pesanan (
id_pesanan TEXT NOT NULL,
sk_produk INTEGER NOT NULL,
sk_pelanggan INTEGER NOT NULL,
tanggal TEXT NOT NULL,
qty INTEGER NOT NULL,
harga INTEGER NOT NULL
);
INSERT INTO dim_produk VALUES
(1, 'Kemeja Flanel', 'Pakaian'),
(2, 'Sepatu Lari', 'Olahraga');
INSERT INTO dim_pelanggan VALUES
(1, 'Budi', 'Jakarta'),
(2, 'Siti', 'Bandung');
INSERT INTO fact_pesanan VALUES
('ORD-1', 1, 1, '2026-01-05', 2, 150000),
('ORD-2', 2, 2, '2026-01-06', 1, 500000),
('ORD-3', 1, 2, '2026-02-10', 1, 150000);
""")
def bangun_mart_penjualan():
"""Dependent data mart: dibangun ulang dari warehouse, bukan dari sumber."""
cur.execute("DROP TABLE IF EXISTS mart_penjualan")
cur.execute("""
CREATE TABLE mart_penjualan AS
SELECT
strftime('%Y-%m', f.tanggal) AS bulan,
p.kategori,
COUNT(*) AS jumlah_pesanan,
SUM(f.qty * f.harga) AS total_penjualan
FROM fact_pesanan f
JOIN dim_produk p ON p.sk_produk = f.sk_produk
JOIN dim_pelanggan c ON c.sk_pelanggan = f.sk_pelanggan
GROUP BY bulan, p.kategori
""")
bangun_mart_penjualan()
print("mart_penjualan (rebuild pertama):")
for baris in cur.execute(
"SELECT * FROM mart_penjualan ORDER BY bulan, kategori"
):
print(" ", baris)
# pesanan baru masuk ke warehouse, mart dibangun ulang
cur.execute(
"INSERT INTO fact_pesanan VALUES ('ORD-4', 2, 1, '2026-02-15', 1, 500000)"
)
bangun_mart_penjualan()
print()
print("mart_penjualan (rebuild setelah ORD-4):")
for baris in cur.execute(
"SELECT * FROM mart_penjualan ORDER BY bulan, kategori"
):
print(" ", baris)Output yang Dihasilkan:
mart_penjualan (rebuild pertama):
('2026-01', 'Olahraga', 1, 500000)
('2026-01', 'Pakaian', 1, 300000)
('2026-02', 'Pakaian', 1, 150000)
mart_penjualan (rebuild setelah ORD-4):
('2026-01', 'Olahraga', 1, 500000)
('2026-01', 'Pakaian', 1, 300000)
('2026-02', 'Olahraga', 1, 500000)
('2026-02', 'Pakaian', 1, 150000)Mari kita telaah baris-baris kode di atas:
- Baris 7-36 (
executescript): warehouse inti dimuat lengkap — dua dimensi dan satu fact table dengan tiga pesanan; inilah satu-satunya sumber mart. - Baris 39-53 (
bangun_mart_penjualan):DROP TABLE IF EXISTSdiikuti CTAS membangun ulang mart penuh dari warehouse. Select di dalamnya menggabungkan fakta kedim_produkdandim_pelanggan, menghitung bulan lewatstrftime, lalu mengagregasi jumlah pesanan dan total penjualan per bulan per kategori. - Baris 63-67 (pesanan baru): ORD-4 disisipkan ke
fact_pesanandi warehouse, bukan ke mart; setelahbangun_mart_penjualanberjalan lagi, baris Februari Olahraga muncul — mart selalu mengikuti keadaan warehouse, bukan keadaan sumber.
Dalam praktik modern, mart lazim dikelola sebagai model dbt yang terdefinisi di kode dan diuji otomatis — dokumentasi pola tersebut ada di docs.getdbt.com
, sementara sintaks CREATE TABLE AS yang dipakai contoh ini dirinci di dokumentasi SQLite
.
Data mart menyeragamkan bentuk data per departemen, tetapi satu masalah konsistensi masih tersisa: dua dashboard yang menghitung “pendapatan” bisa saja memakai rumus berbeda meski membaca mart yang sama. Lapisan yang mendefinisikan metrik sekali untuk semua pemakai dibahas pada Chapter Semantic Layer.