Fact Table vs Dimension Table: Dasar Dimensional Modeling Kimball
Blog/Tutorial SQL/Fact Table vs Dimension Table: Dasar Dimensional Modeling Kimball

Fact Table vs Dimension Table: Dasar Dimensional Modeling Kimball

BimaBima
·21 September 2025·9 menit baca

Penulis

Bima

Bima

Founder & Data Professional

Bagikan

TL;DR

Fact table nyimpen angka hasil pengukuran dari sebuah proses bisnis, misalnya jumlah unit terjual dan nilai transaksi, plus kunci penghubung ke tabel dimensi. Dimension table nyimpen atribut deskriptif yang jadi konteks angka itu, misalnya nama produk, kategori, cabang, dan tanggal. Susunan satu fact table di tengah yang dikelilingi beberapa dimension table disebut star schema, dan itu bentuk dasar dimensional modeling ala Kimball.

Fact table nyimpen angka yang diukur. Dimension table nyimpen konteks dari angka itu.

Kalimat itu 80 persen dari yang perlu kamu tau. Sisanya soal cara nyusunnya biar query-mu nggak berantakan.

Model ini dipopulerkan Ralph Kimball di awal 1990-an, dan sampai sekarang masih jadi bentuk standar isi gudang data di banyak perusahaan Indonesia. Power BI, Looker Studio, dan Tableau semuanya paling nyaman dikasih data dalam bentuk ini.

Di bawah ini beda keduanya, cara nentuin grain, dan contoh query dari data toko ritel.

Apa itu fact table?

Fact table adalah tabel yang nyimpen hasil pengukuran dari satu proses bisnis, misalnya penjualan, pengiriman, atau klaim asuransi. Isinya dua jenis kolom: kolom angka yang bisa dijumlahkan (disebut measure), dan kolom kunci penghubung ke tabel dimensi. Fact table tumbuh cepat, bisa jutaan baris per bulan.

fact_penjualan
-------------------------------
tanggal_key      INT   -- kunci ke dim_tanggal
produk_key       INT   -- kunci ke dim_produk
cabang_key       INT   -- kunci ke dim_cabang
pelanggan_key    INT   -- kunci ke dim_pelanggan
nomor_struk      VARCHAR
jumlah_unit      INT       -- measure
nilai_transaksi  NUMERIC   -- measure
nilai_diskon     NUMERIC   -- measure

Kolom nomor_struk di situ namanya degenerate dimension. Dia keterangan, bukan angka, tapi nggak punya tabel dimensi sendiri karena nggak ada atribut lain yang nempel di nomor struk.

Tiga jenis measure

  • Additive. Bisa dijumlah di semua dimensi. Nilai transaksi bisa dijumlah per hari, per cabang, per produk, hasilnya tetap benar.
  • Semi additive. Bisa dijumlah di sebagian dimensi. Saldo rekening boleh dijumlah antar nasabah, tapi nggak boleh dijumlah antar tanggal.
  • Non additive. Nggak boleh dijumlah sama sekali. Persentase margin dan rasio itu contohnya. Simpan pembilang dan penyebutnya terpisah, lalu hitung rasionya di lapisan laporan.

Kesalahan yang paling sering aku temuin di gudang data: kolom persentase disimpan langsung di fact table, lalu dijumlahkan orang di dashboard. Hasilnya angka margin 480 persen.

Apa itu dimension table?

Dimension table adalah tabel yang nyimpen atribut deskriptif buat memfilter, mengelompokkan, dan memberi label pada angka di fact table. Isinya jawaban dari pertanyaan siapa, apa, di mana, dan kapan. Barisnya jauh lebih sedikit dari fact table, dan kolomnya justru lebih banyak.

dim_produk
-------------------------------
produk_key       INT   -- surrogate key
kode_produk      VARCHAR  -- kode dari sistem sumber
nama_produk      VARCHAR
kategori         VARCHAR
subkategori      VARCHAR
merek            VARCHAR
satuan           VARCHAR
berlaku_dari     DATE
berlaku_sampai   DATE
baris_aktif      BOOLEAN

Dimensi yang bagus itu lebar. Kolom kayak kategori dan merek memang bisa dinormalisasi jadi tabel terpisah, tapi di dimensional modeling itu sengaja nggak dilakukan. Tujuannya biar query cuma butuh satu join.

Kenapa pakai surrogate key?

Surrogate key adalah angka urut yang dibikin gudang data sendiri, terpisah dari kode di sistem sumber. Alasannya: kode sumber bisa berubah, bisa dipakai ulang buat produk lain, dan formatnya sering beda antar sistem.

Manfaat keduanya lebih penting. Dengan surrogate key, kamu bisa nyimpen beberapa versi baris buat entitas yang sama.

Apa bedanya fact table dan dimension table?

AspekFact tableDimension table
Isi kolomAngka terukur dan kunci penghubungKeterangan berbentuk teks dan tanggal
Jumlah barisJutaan, tumbuh tiap hariRatusan sampai puluhan ribu
Jumlah kolomSedikit, biasanya di bawah 20Banyak, bisa lebih dari 50
Peran di querySumber angka buat SUM dan COUNTSumber filter dan GROUP BY
Kunci utamaGabungan beberapa kunci dimensiSatu surrogate key
Perubahan dataDitambah, jarang diubahDiperbarui saat atribut berubah

Patokan cepat: kalau kolomnya masuk akal buat dijumlahkan, itu fact. Kalau kolomnya masuk akal buat ditaruh di dropdown filter, itu dimension. Bacaan lebih lanjut soal aggregate function yang dipakai di fact table ada di glossary.

Gimana cara nentuin grain fact table?

Grain adalah definisi apa yang diwakili oleh satu baris di fact table. Tulis grain-nya dalam satu kalimat sebelum kamu milih kolom apa pun. Kalimat itu yang nentuin dimensi mana yang boleh nempel dan measure mana yang valid.

Contoh kalimat grain yang jelas:

  • "Satu baris sama dengan satu item produk dalam satu struk penjualan."
  • "Satu baris sama dengan posisi stok satu produk di satu gudang pada akhir hari."
  • "Satu baris sama dengan satu tiket keluhan pelanggan pada saat ditutup."

Kimball nyusun empat langkah perancangan yang urutannya nggak boleh ditukar: pilih proses bisnis, tentukan grain, tentukan dimensi, lalu tentukan fact. Rinciannya ada di daftar teknik dimensional modeling dari Kimball Group.

Kalau grain kamu campur, misalnya sebagian baris level struk dan sebagian level item, semua penjumlahan bakal salah dan susah dilacak penyebabnya.

Apa itu star schema?

Star schema adalah susunan satu fact table di tengah yang dikelilingi beberapa dimension table, masing-masing terhubung lewat satu join. Bentuknya kalau digambar mirip bintang. Ini bentuk paling umum dari dimensional modeling karena query-nya pendek dan gampang dibaca orang bisnis.

            dim_tanggal
                 |
dim_produk -- fact_penjualan -- dim_cabang
                 |
           dim_pelanggan

Alternatifnya snowflake schema, di mana dimensi dipecah lagi jadi tabel bertingkat. Misalnya dim_produk dipisah jadi dim_produk, dim_kategori, dan dim_merek. Itu hemat ruang tapi nambah join.

Buat alat BI modern, star schema masih jadi rekomendasi resmi. Microsoft menuliskannya di panduan star schema Power BI.

Contoh query: omzet per kategori dari star schema

Query di bawah ini narik omzet dan jumlah struk per kategori produk per bulan buat cabang di Depok.

SELECT
    d.tahun,
    d.nama_bulan,
    p.kategori,
    SUM(f.nilai_transaksi)        AS omzet,
    COUNT(DISTINCT f.nomor_struk) AS jumlah_struk,
    SUM(f.jumlah_unit)            AS unit_terjual
FROM fact_penjualan f
JOIN dim_tanggal d ON f.tanggal_key = d.tanggal_key
JOIN dim_produk  p ON f.produk_key  = p.produk_key
JOIN dim_cabang  c ON f.cabang_key  = c.cabang_key
WHERE d.tahun = 2025
  AND c.kota   = 'Depok'
GROUP BY d.tahun, d.nama_bulan, p.kategori
ORDER BY omzet DESC;

Perhatikan polanya. Semua SUM datang dari fact table, semua filter dan GROUP BY datang dari dimension table. Pola itu berlaku di hampir semua query gudang data.

Contoh kasus: laporan yang beda gara-gara satu baris dimensi

Di dataset toko_berkah, produk "Minyak goreng 2L" pindah dari kategori Sembako ke kategori Kebutuhan Dapur pada 1 Juli 2025.

Kalau baris dimensinya cuma ditimpa, seluruh riwayat penjualan produk itu ikut pindah kategori. Omzet Sembako periode Januari sampai Juni yang tadinya Rp 284,6 juta turun jadi Rp 231,9 juta di laporan yang dijalankan ulang bulan Agustus. Selisihnya Rp 52,7 juta, dan angka itu muncul entah dari mana buat orang keuangan.

Penanganan yang benar namanya slowly changing dimension tipe 2. Baris lama nggak dihapus, cuma ditutup masa berlakunya, lalu baris baru ditambahkan dengan surrogate key berbeda.

produk_key | kode  | nama              | kategori         | berlaku_dari | berlaku_sampai | aktif
1042       | 00841 | Minyak goreng 2L  | Sembako          | 2023-01-01   | 2025-06-30     | false
2317       | 00841 | Minyak goreng 2L  | Kebutuhan Dapur  | 2025-07-01   | 9999-12-31     | true

Dengan cara ini, transaksi Januari tetap nempel ke produk_key 1042 dan tetap kehitung sebagai Sembako. Laporan lama nggak berubah waktu dijalankan ulang.

Itu alasan utama surrogate key ada. Bukan soal performa, tapi soal laporan yang bisa dipercaya.

FAQ

Gimana cara cepat bedain fact dan dimension?

Kalau kolomnya masuk akal buat dijumlahkan, itu fact. Kalau kolomnya dipakai buat memfilter dan mengelompokkan, itu dimension. Fact tumbuh cepat tiap hari, dimension tumbuh pelan.

Apa itu grain dan kenapa penting?

Grain adalah tingkat detail satu baris fact table, misalnya satu item dalam satu struk. Tentukan grain sebelum milih kolom. Grain yang campur bikin semua penjumlahan salah.

Kenapa dimension pakai surrogate key?

Karena kode dari sistem sumber bisa berubah dan dipakai ulang. Surrogate key juga bikin kamu bisa nyimpen beberapa versi baris buat entitas yang sama tanpa bentrok.

Star schema atau snowflake?

Star schema buat mayoritas kasus. Lebih sedikit join, query lebih pendek, dan orang bisnis lebih gampang paham. Snowflake hemat ruang tapi nambah kerumitan.

Model Kimball masih relevan?

Masih. Alasan performanya berkurang karena mesin modern sudah cepat, tapi manfaat kejelasan struktur dan penanganan riwayat data tetap sama. Power BI juga masih menyarankan star schema.

Ringkasnya

Fact table isinya angka yang diukur, dimension table isinya konteks buat memfilter dan mengelompokkan. Tentukan grain dalam satu kalimat sebelum bikin tabelnya, dan pakai surrogate key supaya riwayat perubahan bisa disimpan.

Kalau kamu lagi ngerapikan alur data dari sistem sumber ke gudang data, konsep ETL dan metric yang konsisten bakal sering kepakai berbarengan.

Latihan nulis query star schema kayak contoh di atas bisa kamu kerjakan langsung di NgulikSQL, tanpa perlu pasang database sendiri.

Coba ambil satu laporan yang sering kamu bikin, lalu tulis kalimat grain-nya. Kalau kalimat itu susah dibikin, biasanya laporannya memang lagi nyampur dua level detail.

Coba Langsung

Mau praktek langsung? Mulai latihan SQL gratis

Latihan interaktif, langsung di browser.

Buka NgulikSQL →
Bagikan:
Bima
Ditulis oleh

Bima

Founder & Data Professional

Founder Ngulik Data. Passionate about making data analysis accessible for everyone.

Artikel terkait

Cara Membuat Pivot Dinamis di SQL (Panduan 2026)
Tutorial SQL
19 Juli 2026•10 menit baca

Cara Membuat Pivot Dinamis di SQL (Panduan 2026)

Pivot dinamis di SQL ngubah baris jadi kolom tanpa kamu hardcode nama kolomnya. Ini cara bikinnya pakai CASE WHEN dan versi yang kolomnya ngikut data.

BimaBima
Menghitung YTD, QTD, dan MTD di SQL (Panduan 2026)
Tutorial SQL
17 Juli 2026•9 menit baca

Menghitung YTD, QTD, dan MTD di SQL (Panduan 2026)

YTD, QTD, dan MTD ngukur total dari awal tahun, kuartal, atau bulan sampai hari ini. Ini cara ngitungnya di SQL pakai DATE_TRUNC, plus satu query gabungan.

BimaBima
Gap and Island Analysis di SQL
Tutorial SQL
15 Juli 2026•10 menit baca

Gap and Island Analysis di SQL

Gap and island analysis di SQL nyari deret data yang berturut-turut (island) dan celah yang bolong (gap). Cocok buat hitung streak login atau cari tanggal transaksi yang hilang.

BimaBima
Kembali ke Blog
Ngulik Data logoNgulik Data

Platform edukasi data lengkap untuk professionals Indonesia. Belajar SQL, Data Analysis, dan lebih banyak lagi dengan praktek langsung dan feedback real-time.

© 2026 Ngulik Data. Semua hak dilindungi.

TAUTAN
BantuanHargaDatasetBlogAfiliasi
LEGAL
Syarat & KetentuanKebijakan Privasi
Ngulik Data
DatasetLeaderboardBlogStore