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.

AspekDependent MartIndependent Mart
Sumber datawarehouse intisistem operasional langsung
Konsistensi antar marttinggi, satu sumber kebenaranrendah, definisi bisa berbeda
Ketergantungan pipelinemenunggu warehouse siapmandiri, berjalan lebih awal
Beban pada sistem sumbertidak menyentuh OLTPmenambah beban transaksi
Cocok untukorganisasi dengan warehouse matangkebutuhan 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.

python
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:

text
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:

  1. Baris 7-36 (executescript): warehouse inti dimuat lengkap — dua dimensi dan satu fact table dengan tiga pesanan; inilah satu-satunya sumber mart.
  2. Baris 39-53 (bangun_mart_penjualan): DROP TABLE IF EXISTS diikuti CTAS membangun ulang mart penuh dari warehouse. Select di dalamnya menggabungkan fakta ke dim_produk dan dim_pelanggan, menghitung bulan lewat strftime, lalu mengagregasi jumlah pesanan dan total penjualan per bulan per kategori.
  3. Baris 63-67 (pesanan baru): ORD-4 disisipkan ke fact_pesanan di warehouse, bukan ke mart; setelah bangun_mart_penjualan berjalan 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.