Data governance adalah aturan dan kebiasaan tentang data: siapa pemiliknya, apa artinya, dari mana asalnya, siapa boleh melihatnya, dan berapa lama disimpan. Data lineage adalah salah satu bagiannya: silsilah sebuah angka, dari tabel sumber sampai laporan. Bayangin rantai pasok makanan kemasan. Tiap kemasan punya label: asal bahan, pabrik, tanggal kedaluwarsa, siapa penanggung jawabnya. Kalau satu bahan ketahuan tercemar, pabrik menelusuri balik ke pemasoknya, lalu menarik semua produk di rak yang memakai bahan itu. Ruang gudang tertentu cuma boleh dimasuki petugas tertentu. Label itu katalog, telusur balik dan tarik dari rak itu lineage, kunci gudang itu access control, dan tanggal kedaluwarsa itu retensi.
🧪 Tebakan cepat: Maya Sari minta data pribadinya dihapus dari Toko Buku. Setelah namanya dihapus dan warehouse dibangun ulang, laporan
laris_mingguanberubah? Baris "Tidak diketahui, minggu 5 Oktober: Bumi Manusia 1" (pesanan Maya) masih ada atau hilang? Tebak dulu, jawabannya ada di bagian "Hak hapus dan retensi".
Pemilik dan katalog data
Tiap dataset butuh pemilik (owner): orang atau tim yang menjawab "angka ini benar gak?", menyetujui siapa boleh membaca, dan dihubungi kalau ada yang rusak. Di Toko Buku yang kecil, pemiliknya satu tim data. Di perusahaan besar, tabel pesanan dimiliki tim checkout dan tabel marketing dimiliki tim marketing.
Data catalog adalah daftar semua dataset beserta keterangannya: deskripsi, pemilik, kolom dan artinya, klasifikasi, kapan terakhir diperbarui, dan lineage-nya. Gunanya supaya orang bisa menemukan, memahami, dan mempercayai dataset yang ada tanpa harus bertanya ke tim lain. Di proyek dbt, keterangan itu ditulis di YAML yang sama dengan tes. Ini lolos dbt parse di dbt 1.12.5 tanpa peringatan:
models:
- name: dim_pelanggan
description: "Satu baris per pelanggan Toko Buku."
config:
meta:
pemilik: tim-data
retensi: "anonimkan saat pelanggan minta dihapus"
columns:
- name: nama
description: "Nama pelanggan."
config:
meta:
pii: true
tags: ["pii"]
- name: kota
config:
meta:
pii: kuasi
dbt docs generate memasukkan semua ini ke situs dokumentasi dbt. Untuk banyak sistem sekaligus (warehouse, Kafka, dashboard, dbt), tim memakai katalog terpisah seperti DataHub (1.6, Apache 2.0) atau OpenMetadata (2.0, Apache 2.0), yang menarik metadata dari semua sistem itu.
Lineage: dari mana angka ini?
Data lineage adalah pelacakan asal-usul data: dari mana datanya, transformasi apa yang dilalui, dan ke mana hasilnya. Di proyek dbt, lineage tingkat model gratis: tiap ref() adalah satu panah. Dua arah yang sering dipakai:
- Ke hulu (debugging): "Kenapa Jakarta minggu 28 September juaranya Laskar Pelangi 3?" Telusuri
laris_mingguankefact_penjualankestg_order_itemskeorder_items, dan ketemu baris dobel item 9 yang dibuang di staging. - Ke hilir (impact analysis): "Tim aplikasi mau mengganti nama
customers.city. Apa yang rusak?" Hasildbt ls --select source:toko_buku.customers+ --resource-type model:
toko_buku.marts.dim_pelanggan
toko_buku.marts.fact_penjualan
toko_buku.marts.laris_mingguan
toko_buku.staging.stg_customers
Empat model. Lineage per kolom lebih halus: kolom mana dibuat dari kolom mana. Untuk kolom kota di laporan pemilik, dibaca langsung dari file modelnya:
| Kolom | Dibuat dari | File |
|---|---|---|
laris_mingguan.kota |
p.kota |
models/marts/laris_mingguan.sql |
dim_pelanggan.kota |
coalesce(kota, 'Tidak diketahui') |
models/marts/dim_pelanggan.sql |
stg_customers.kota |
city as kota |
models/staging/stg_customers.sql |
customers.city |
sumber, MySQL | _sources.yml |
Kolom laporan yang kelihatan polos ternyata berasal dari alamat pelanggan. dbt Core menggambar lineage per model; lineage per kolom butuh alat yang membaca SQL-nya, misalnya DataHub atau OpenMetadata. Untuk pipeline di luar dbt (Airflow, Spark), OpenLineage (1.53) adalah standar terbuka untuk mengirim kejadian lineage dari tiap run ke katalog.
Data pribadi di Toko Buku
Data pribadi adalah data tentang orang yang bisa dikenali, sendiri atau digabung dengan data lain. Sering disebut PII (personally identifiable information). Tabel customers di contoh ini cuma punya nama dan kota; aplikasi Laravel biasanya juga menyimpan email di tabel users, dan itu juga data pribadi.
| Kolom | Klasifikasi | Pemilik toko | Analis |
|---|---|---|---|
nama |
data pribadi umum (nama lengkap) | lihat | disamarkan |
kota |
data pribadi kalau digabung dengan nama | lihat | lihat |
pelanggan_key |
kunci buatan warehouse | lihat | lihat |
judul, qty |
bukan data pribadi | lihat | lihat |
Analis yang menghitung pembeli per kota gak perlu tahu namanya. Jadi mart punya view yang menyamarkan (masking) nama, dan analis cuma diberi akses ke view itu:
CREATE VIEW dim_pelanggan_analis AS
SELECT pelanggan_key,
CASE WHEN nama IS NULL THEN NULL ELSE substr(nama, 1, 1) || '***' END AS nama,
kota
FROM dim_pelanggan;
Hasilnya di SQLite (Lab): 1 | B*** | Jakarta, 2 | S*** | Bandung, 6 | M*** | Tidak diketahui. Cara lain: ganti nama dengan hash (misalnya SHA-256 dari email) supaya baris satu orang tetap bisa digabung tanpa namanya kelihatan.
Akses per peran
Access control menentukan siapa boleh membaca apa, per peran (role), bukan per orang. Di PostgreSQL:
GRANT SELECT ON dim_pelanggan_analis TO analis;
REVOKE SELECT ON dim_pelanggan FROM analis;
Warehouse cloud punya cara per kolom: BigQuery dengan policy tag di kolom, Snowflake dengan masking policy. Prinsipnya least privilege: tiap peran cuma mendapat akses yang dia butuhkan. Ditambah audit log, catatan siapa membaca tabel apa dan kapan, supaya akses bisa diperiksa belakangan.
Hak hapus dan retensi
Maya meminta data pribadinya dihapus. Di MySQL aplikasi:
UPDATE customers SET name = NULL WHERE id = 6;
Lalu dbt build membangun ulang dim_pelanggan, dan nama Maya jadi NULL di sana juga. Fakta penjualannya tetap: 2 baris dan 2 buku di fact_penjualan, dan laris_mingguan tetap 9 baris dengan total 15 buku. Baris "Tidak diketahui, minggu 5 Oktober: Bumi Manusia 1" masih ada. Itu jawaban tebakannya. Yang dihapus identitasnya, bukan transaksinya: toko tetap butuh angka penjualan untuk laporan dan pajak.
Retensi adalah berapa lama data disimpan. Ada dua arah yang harus dicocokkan:
- Pembukuan harus disimpan: UU KUP Pasal 28 ayat (11) mewajibkan buku, catatan, dan dokumen dasar pembukuan disimpan 10 tahun.
- Data pribadi harus dihapus atau dimusnahkan saat gak dibutuhkan lagi, masa retensinya habis, atau orangnya meminta (UU PDP Pasal 43 dan 44).
Penghapusan juga harus mengejar salinannya: file mentah di lake (lapisan bronze), event lama di topic Kafka (disimpan 7 hari), snapshot, dan backup. Lineage yang sama yang menunjukkan ke mana data mengalir.
💡 UU PDP dan GDPR, singkatnya (bukan nasihat hukum)
UU PDP (Undang-Undang Nomor 27 Tahun 2022 tentang Pelindungan Data Pribadi) disahkan dan diundangkan 17 Oktober 2022 (Lembaran Negara 2022 Nomor 196) dan berlaku sejak diundangkan (Pasal 76). Pasal 74 memberi pengendali dan prosesor data waktu menyesuaikan paling lama 2 tahun sejak diundangkan, jadi masa transisinya berakhir 17 Oktober 2024. Pasal 4 membagi data pribadi jadi spesifik (antara lain kesehatan, biometrik, genetika, catatan kejahatan, data anak, keuangan pribadi) dan umum (antara lain nama lengkap, jenis kelamin, kewarganegaraan, agama, status perkawinan, dan data yang dikombinasikan untuk mengidentifikasi seseorang). Pasal 8 memberi subjek data, orang yang datanya diproses, hak meminta datanya dihapus. Aturan pelaksananya, PP Nomor 33 Tahun 2026, ditetapkan 16 Juli 2026 dan mulai berlaku 16 Januari 2027; menurut pemberitaan September 2026, lembaga pengawas yang diamanatkan Pasal 58 belum terbentuk.
GDPR (General Data Protection Regulation, Regulation (EU) 2016/679) berlaku sejak 25 Mei 2018 di Uni Eropa, dan juga untuk usaha di luar Uni Eropa yang menawarkan barang atau jasa ke orang di sana (Pasal 3 ayat 2). Isinya mirip: hak hapus (Pasal 17), data disimpan selama dibutuhkan saja (Pasal 5 ayat 1 huruf e), dan denda sampai 20 juta euro atau 4% omzet tahunan global, mana yang lebih besar (Pasal 83 ayat 5). Toko Buku yang cuma berjualan di Indonesia umumnya gak terkena GDPR. Ini ringkasan untuk engineer, bukan nasihat hukum: keputusan kepatuhan tanyakan ke ahli hukum.
⚠️ Jebakan yang sering ketemu
- Menghapus di MySQL saja. Nama Maya masih hidup di warehouse sampai build berikutnya, di file bronze lake, di topic Kafka, dan di backup. Pakai lineage untuk menemukan semua salinannya.
- Menyamarkan di dashboard saja. Analis yang bisa query tabel aslinya tetap melihat nama. Samarkan di warehouse, dan atur aksesnya per peran.
- Menghapus transaksinya untuk "menghapus pelanggan". Laporan dan pembukuan jadi bolong. Anonimkan identitasnya, simpan faktanya.
- Katalog tanpa pemilik. Deskripsi yang gak ada yang merawat cepat basi, dan orang kembali bertanya di chat. Tiap dataset harus punya nama pemilik.
TL;DR: Data governance mengatur pemilik, arti, asal, akses, dan umur data. Data catalog (dbt docs, DataHub, OpenMetadata) membuat orang bisa menemukan, memahami, dan mempercayai dataset tanpa bertanya ke tim lain. Data lineage melacak asal-usul data: dari mana, transformasi apa, ke mana; di dbt tiap ref() adalah panah, ke hulu untuk debugging, ke hilir untuk dampak (customers mengalir ke 4 model), dan lineage per kolom menunjukkan laris_mingguan.kota berasal dari customers.city. Nama pelanggan itu data pribadi: samarkan di mart (B***), beri akses per peran dengan GRANT, catat aksesnya. Saat Maya minta dihapus, namanya jadi NULL dan transaksinya tetap (laporan tetap 9 baris), termasuk di semua salinan. Pembukuan disimpan 10 tahun (UU KUP), data pribadi dihapus saat gak dibutuhkan (UU PDP). UU PDP diundangkan 17 Oktober 2022 dengan transisi sampai 17 Oktober 2024; GDPR berlaku sejak 25 Mei 2018.