Data Warehouse Concepts — Data Engineering

Data Warehouse Concepts Data warehouse adalah sistem penyimpanan yang dioptimalkan untuk analitik, bukan transaksi. Memahami perbedaan ini fundamental untuk…

Data warehouse adalah database terpisah dari aplikasi, yang disusun khusus untuk menjawab pertanyaan tentang banyak baris dan riwayat yang panjang. Bayangin toko dan gudangnya. Di toko depan, pelayan mengambil satu buku dari rak untuk satu pembeli: cepat, satu barang. Di gudang, barang yang sama ditumpuk per jenis, supaya waktu stok opname semua barang bisa dihitung sekaligus tanpa membongkar rak toko. Barangnya sama, susunannya beda, karena pertanyaannya beda. Database aplikasi itu toko depan, warehouse itu gudangnya.

🧪 Tebakan cepat: tabel penjualan punya 18 baris dan 8 kolom, jadi 144 sel. Warehouse menyimpannya per kolom. Query SELECT kota, SUM(qty) FROM penjualan GROUP BY kota membaca berapa sel: 144, 36, atau 18? Tebak dulu, jawabannya ada di bagian "Columnar: baca kolom yang perlu saja".

OLTP dan OLAP, sekali lagi

Di pelajaran pertama kamu sudah ketemu dua jenis kerja database. Sekarang lengkapnya:

OLTP (Online Transaction Processing) OLAP (Online Analytical Processing)
Tujuan transaksi operasional, saat itu juga analisis data historis dalam jumlah besar
Contoh di Toko Buku checkout menulis 1 pesanan, halaman "Pesanan saya" "buku apa paling laku per kota per minggu?"
Bentuk query banyak query kecil, tiap query menyentuh sedikit baris sedikit query besar yang membaca hampir semua baris
Datanya keadaan sekarang: harga buku hari ini riwayat: semua pesanan sejak toko buka
Tool MySQL, PostgreSQL (database aplikasi) BigQuery, Snowflake, Redshift, ClickHouse, DuckDB

Warehouse adalah database OLAP. Isinya disalin dari database aplikasi oleh pipeline (pelajaran ETL vs ELT), jadi query berat pemilik gak pernah memperlambat checkout.

Tabel penjualan di warehouse

Ini tabel yang dibangun pipeline Toko Buku di pelajaran sebelumnya, dari salinan mentah raw_order_lines:

CREATE TABLE penjualan (
  order_id INT,
  book_id INT,
  tanggal DATE,        -- hari pesanan
  minggu DATE,         -- Senin minggunya
  kota VARCHAR(50),    -- 'Tidak diketahui' kalau kosong
  judul VARCHAR(200),
  qty INT,
  harga INT            -- harga katalog
);

Columnar: baca kolom yang perlu saja

Database aplikasi menyimpan per baris (row-oriented): semua kolom satu baris ditulis berdampingan di disk. Warehouse menyimpan per kolom (columnar), seperti file Parquet di pelajaran Data Formats: semua nilai satu kolom ditulis berdampingan.

Per baris (MySQL, PostgreSQL, SQLite):
[1, 1, 2026-09-28, 2026-09-28, Jakarta, Laskar Pelangi, 1, 89000]
[2, 2, 2026-09-28, 2026-09-28, Bandung, Bumi Manusia, 1, 125000]
...

Per kolom (BigQuery, Snowflake, ClickHouse, DuckDB):
kota: [Jakarta, Bandung, Bandung, Surabaya, Jakarta, ...]
qty:  [1, 1, 1, 2, 2, ...]
...

Berapa sel yang dibaca dua query ini dari 144 sel penjualan:

Query Per baris Per kolom
SELECT kota, SUM(qty) FROM penjualan GROUP BY kota 144 sel: tiap baris dibaca utuh 36 sel: kolom kota dan qty saja
SELECT * FROM penjualan WHERE order_id = 6 8 sel dari 1 tempat (lewat index) 8 sel dari 8 tempat, satu per kolom

Jawabannya 36. Itu jawaban tebakannya: 2 kolom kali 18 baris. Hasilnya Bandung 5, Jakarta 9, Surabaya 5, Tidak diketahui 2. Di 1 juta baris, pelajaran Data Formats mengukur GROUP BY city 0,59 detik di CSV dan 0,009 detik di Parquet. Selain membaca lebih sedikit, kolom juga mudah dimampatkan: kota cuma punya 4 nilai berbeda, jadi tiap nilai disimpan sekali (encoding dictionary).

Baris kedua menjelaskan kenapa aplikasi tetap memakai penyimpanan per baris: membaca atau menulis satu pesanan cukup di satu tempat. Columnar cepat untuk scan, lambat untuk satu baris.

Warehouse, data mart, data lake

Isinya Di Toko Buku
Data warehouse semua data analitik perusahaan, bersih dan tersusun, jadi satu sumber kebenaran raw_order_lines, penjualan, nanti juga stok dan iklan
Data mart potongan warehouse untuk satu tim atau satu pertanyaan tabel laris_mingguan untuk dashboard pemilik
Data lake file mentah (Parquet, JSON Lines, CSV) di object storage seperti S3, GCS, atau R2; schema dibaca saat query file order_lines.parquet per hari

Di dalam warehouse, tabel biasanya berlapis: raw (salinan mentah) ke bersih ke mart (siap pakai), atau dengan nama lain bronze, silver, gold. Di Toko Buku: raw_order_lines ke penjualan ke laris_mingguan. Data lake dan lakehouse (lake yang bisa di-query seperti warehouse) dibahas di pelajaran Data Lake Architecture.

Fakta dan dimensi: sekilas

Kolom penjualan ada dua jenis:

Di pelajaran Data Modeling (Star Schema), tabel lebar ini dipecah jadi satu tabel fakta fact_penjualan yang menyimpan angka dan kunci, dikelilingi tabel dimensi dim_buku, dim_tanggal, dan dim_pelanggan. Untuk sekarang, cukup bisa membedakan mana fakta dan mana dimensi.

💡 Data yang berubah pelan-pelan

Kolom harga diambil dari katalog books waktu tabel dibangun. Sabtu 10 Oktober, harga Bumi Manusia turun dari 125000 jadi 119000, lalu malamnya penjualan dibangun ulang penuh dari raw:

UPDATE books SET price = 119000 WHERE id = 2;
-- lalu CREATE TABLE penjualan AS SELECT ... JOIN books b ... seperti biasa
SELECT SUM(qty * harga) AS omzet FROM penjualan;

Hasilnya di SQLite 2178000, padahal sebelumnya 2214000. Ke-6 Bumi Manusia yang terjual 28 September sampai 9 Oktober dengan harga 125000 sekarang tercatat 119000: omzet minggu lalu berubah, padahal gak ada yang terjadi minggu lalu. Keterangan yang berubah pelan-pelan seperti harga, alamat, atau kota pelanggan disebut slowly changing dimension (SCD). Dua obat yang umum: simpan harga saat transaksi di baris fakta dan jangan pernah dihitung ulang, atau simpan tiap versi harga dengan kolom valid_from dan valid_to. Detailnya di pelajaran Data Modeling (Star Schema).

Load harian yang idempoten

Warehouse diisi per tanggal, satu bagian (partisi) tiap malam, dengan pola dari pelajaran ETL vs ELT:

BEGIN;
DELETE FROM penjualan WHERE tanggal = '2026-10-01';
INSERT INTO penjualan
SELECT DISTINCT r.order_id, r.book_id,
       date(r.created_at) AS tanggal,
       date(r.created_at, 'weekday 0', '-6 days') AS minggu,
       COALESCE(r.city, 'Tidak diketahui') AS kota,
       r.title AS judul,
       r.qty,
       b.price AS harga
FROM raw_order_lines r
JOIN books b ON b.id = r.book_id
WHERE date(r.created_at) = '2026-10-01';
COMMIT;

Pola query di warehouse

Pertanyaan analitik hampir selalu salah satu dari ini: menjumlah per waktu (GROUP BY minggu), memberi peringkat dalam kelompok (RANK(), pelajaran SQL untuk Data Engineering), atau membandingkan dengan periode sebelumnya:

SELECT kota, minggu, SUM(qty) AS buku,
       LAG(SUM(qty)) OVER (PARTITION BY kota ORDER BY minggu) AS minggu_lalu
FROM penjualan
GROUP BY kota, minggu
ORDER BY kota, minggu;
kota minggu buku minggu_lalu
Bandung 2026-09-28 3 NULL
Bandung 2026-10-05 2 3
Jakarta 2026-09-28 6 NULL
Jakarta 2026-10-05 3 6
Surabaya 2026-09-28 3 NULL
Surabaya 2026-10-05 2 3
Tidak diketahui 2026-09-28 1 NULL
Tidak diketahui 2026-10-05 1 1

Satu kebiasaan lagi: saring tanggal sedini mungkin (WHERE tanggal >= '2026-10-05'). Warehouse yang dipartisi per tanggal cuma membaca partisi yang cocok, dan di BigQuery itu langsung memotong biaya. Itu bahan pelajaran berikutnya.

⚠️ Jebakan yang sering ketemu

TL;DR: Data warehouse adalah database OLAP yang terpisah dari aplikasi: OLTP melayani transaksi operasional saat itu juga, OLAP menganalisis data historis dalam jumlah besar. Warehouse menyimpan per kolom, jadi SELECT kota, SUM(qty) cuma membaca 36 dari 144 sel penjualan; penyimpanan per baris lebih cocok untuk membaca atau menulis satu pesanan. Data mart adalah potongan warehouse untuk satu tim, data lake adalah file mentah di object storage. Tabel penjualan itu denormalisasi dengan grain satu judul per pesanan; kolomnya fakta (qty, harga) dan dimensi (tanggal, kota, judul). Membangun ulang dari katalog yang harganya sudah berubah mengubah sejarah (Rp 2.214.000 jadi Rp 2.178.000 setelah Bumi Manusia turun harga). Isi warehouse per tanggal dengan DELETE lalu INSERT dalam satu transaksi, dan pakai pola query per waktu, peringkat, dan LAG untuk banding periode.

Yang akan kamu pelajari