Surrogate Key vs Natural Key untuk Analis Data
Blog/Tutorial SQL/Surrogate Key vs Natural Key untuk Analis Data

Surrogate Key vs Natural Key untuk Analis Data

BimaBima
·24 September 2025·8 menit baca

Penulis

Bima

Bima

Founder & Data Professional

Bagikan

TL;DR

Natural key adalah kolom yang udah ada di data bisnis dan unik secara alami, kayak NIK atau kode SKU. Surrogate key adalah ID buatan tanpa makna bisnis, biasanya angka urut atau UUID, yang dibikin database khusus buat jadi identitas baris. Praktik paling aman buat analis: pakai surrogate key sebagai primary key, lalu pasang unique constraint di natural key-nya supaya duplikat tetap ketahan.

Natural key adalah kolom yang udah ada di data bisnis dan unik secara alami, misalnya NIK atau kode SKU. Surrogate key adalah ID buatan yang dibikin database dan nggak punya makna bisnis apa pun.

Pilihan antara keduanya kelihatan sepele waktu tabelnya masih 200 baris. Setahun kemudian, waktu ada pelanggan ganti email dan tiga tabel ikut rusak, baru kerasa.

Di bawah ini bedanya, kapan masing-masing dipakai, dan pola yang aku pakai di hampir semua proyek.

Apa itu natural key dan surrogate key?

Natural key adalah kolom atau gabungan kolom yang nilainya berasal dari dunia nyata dan udah unik dengan sendirinya. Contohnya nomor invoice, kode SKU, NPWP, atau kode pos. Surrogate key adalah nilai yang dibikin sistem khusus buat jadi identitas baris, biasanya angka urut atau UUID, dan nggak punya arti di luar database.

Bedanya paling gampang dilihat dari satu pertanyaan: kalau data ini dicetak di kertas dan dikasih ke orang bisnis, dia ngerti nggak nilai itu artinya apa?

Kode BRK-014 dia ngerti. Angka 4471 nggak berarti apa-apa buat dia, dan memang itu maksudnya.

Apa bedanya secara praktis?

AspekNatural keySurrogate key
Asal nilaiDari data bisnisDibikin database
MaknaBisa dibaca manusiaNggak ada artinya
StabilitasBisa berubah kapan ajaNggak pernah berubah
UkuranSering panjang, tipe teksRingkas, biasanya bigint
JoinLebih lambat kalau teks panjangCepat, indeksnya kecil
Gabung banyak sumberBentrok kalau format bedaAman, tiap sumber dipetakan
Risiko privasiTinggi kalau isinya NIK atau emailRendah, nilainya nggak bermakna
Query ad hocEnak, nggak perlu joinPerlu join ke tabel dimensi

Baris stabilitas itu yang paling sering nyakitin. Manajemen ganti format kode produk dari BRK-014 jadi ACC-BRK-014, dan tiba-tiba semua tabel yang nunjuk ke situ harus di-update bareng.

Kapan sebaiknya pakai surrogate key?

Pakai surrogate key kalau nilai bisnisnya bisa berubah, kalau kamu gabungin data dari lebih dari satu sistem, atau kalau natural key-nya berupa data pribadi. Ini juga wajib di tabel dimensi data warehouse yang harus nyimpen riwayat perubahan.

Di PostgreSQL, cara paling bersih bikinnya lewat identity column:

CREATE TABLE pelanggan (
    pelanggan_sk BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    email        TEXT NOT NULL,
    nama         TEXT NOT NULL,
    kota         TEXT,
    CONSTRAINT uq_pelanggan_email UNIQUE (email)
);

Perhatiin barisnya: primary key-nya surrogate, tapi email tetap dikasih unique constraint. Jadi kamu dapet dua-duanya, identitas yang stabil plus perlindungan dari data dobel.

GENERATED ALWAYS AS IDENTITY itu cara standar SQL, lebih rapi dari tipe serial yang lama. Penjelasan lengkapnya ada di dokumentasi resmi PostgreSQL.

Kapan natural key masih pilihan yang bener?

Natural key cocok buat tabel referensi yang kodenya udah baku dan dikontrol pihak luar. Kode provinsi dari BPS, kode mata uang ISO, atau kode bandara IATA nggak bakal berubah, jumlahnya sedikit, dan jauh lebih enak dibaca langsung di hasil query tanpa perlu join.

CREATE TABLE provinsi (
    kode_prov  CHAR(2) PRIMARY KEY,
    nama_prov  TEXT NOT NULL
);

Tabel begini isinya 38 baris dan hampir nggak pernah berubah. Nambahin surrogate key di sini cuma bikin query kamu satu join lebih panjang tanpa manfaat.

Satu lagi kasus yang sah: tabel jembatan many to many. Primary key-nya gabungan dua foreign key, dan itu udah cukup.

Contoh kasus: data pelanggan toko_berkah dari dua sistem

Toko Berkah punya data pelanggan di dua tempat: sistem kasir toko fisik dan platform toko online. Dua-duanya pakai email sebagai identitas pelanggan.

Waktu digabung, ketahuan masalahnya.

SELECT email, COUNT(*) AS jumlah
FROM pelanggan_mentah
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY jumlah DESC;

Hasil di dataset latihan ngulikdata: dari 8.417 baris pelanggan gabungan, 312 email muncul lebih dari sekali. Sebagian karena orangnya beneran daftar dua kali. Sebagian lagi karena kasir ngisi email default tokoberkah@gmail.com buat pelanggan yang nggak mau ngasih email, dan itu kepakai 148 kali.

Kalau email dijadiin primary key, proses impornya gagal total di baris ke-59. Kalau dipaksa pakai upsert, 148 transaksi dari orang berbeda bakal nempel ke satu pelanggan yang sama.

Solusinya: surrogate key sebagai identitas, plus tabel pemetaan yang nyimpen ID asli dari tiap sumber.

CREATE TABLE pelanggan_sumber (
    pelanggan_sk  BIGINT NOT NULL REFERENCES pelanggan (pelanggan_sk),
    sistem_asal   TEXT   NOT NULL,
    id_di_sumber  TEXT   NOT NULL,
    PRIMARY KEY (sistem_asal, id_di_sumber)
);

Dengan pola ini, kamu tetap bisa nelusuri satu baris balik ke sistem asalnya waktu ada selisih angka. Ini bagian dari kerapian ETL yang biasanya baru kerasa gunanya waktu ada audit.

Kenapa data warehouse hampir selalu pakai surrogate key?

Karena tabel dimensi harus nyimpen riwayat. Kalau pelanggan pindah dari Bandung ke Jakarta, laporan bulan lalu harus tetap nunjukkin Bandung. Artinya kamu butuh dua baris untuk satu pelanggan yang sama, dan natural key-nya bakal kembar di dua baris itu.

pelanggan_sk | customer_id | kota     | valid_from | valid_to   | is_current
4471         | C001        | Bandung  | 2024-01-05 | 2025-06-30 | FALSE
8892         | C001        | Jakarta  | 2025-07-01 | 9999-12-31 | TRUE

Tabel fakta nyimpen pelanggan_sk, bukan customer_id. Jadi transaksi Maret 2025 otomatis nyambung ke baris Bandung, dan angka historisnya nggak berubah waktu pelanggannya pindah.

Pola lengkapnya aku bahas di panduan SCD Type 2 di SQL.

Kesalahan umum soal primary key

  • Nganggep natural key pasti unik selamanya. Cek dulu pakai GROUP BY dan HAVING sebelum nentuin. Keunikan yang berlaku di satu sistem sering langsung rusak waktu digabung.
  • Pakai nomor telepon atau email sebagai primary key. Dua-duanya bisa diganti pemiliknya, dan dua-duanya data pribadi.
  • Bikin surrogate key tapi lupa unique constraint di natural key-nya. Hasilnya duplikat masuk tanpa ada yang ngeblok, dan angka laporan jadi lebih besar dari kenyataan.
  • Natural key gabungan lima kolom. Setiap tabel yang nunjuk ke situ harus nyimpen lima kolom juga. Indeksnya jadi berat.
  • Nampilin surrogate key ke pengguna akhir. Angka 4471 nggak berarti apa-apa buat tim penjualan. Tampilkan kode bisnisnya di laporan.

Nomor tiga yang paling sering aku temuin. Duplikatnya nggak bikin error apa-apa, cuma bikin total penjualan naik diam-diam. Bikin pengecekan kualitas data yang jalan tiap kali data baru masuk, dan pola insert amannya ada di panduan upsert dan merge.

FAQ

Mana yang lebih bagus, surrogate key atau natural key?

Buat tabel operasional dan tabel dimensi di data warehouse, surrogate key hampir selalu lebih aman karena nilainya nggak pernah berubah. Natural key masih pas buat tabel referensi yang kodenya udah baku dan dikontrol pihak luar, kayak kode provinsi BPS. Kombinasi paling umum: surrogate key jadi primary key, natural key dikasih unique constraint.

Boleh nggak pakai email sebagai primary key?

Sebaiknya jangan. Email itu bisa diganti pelanggan kapan aja, dan begitu diganti kamu harus update semua tabel yang nunjuk ke situ. Email juga data pribadi, jadi nyebar ke banyak tabel bikin kerjaan kamu makin berat waktu ada permintaan hapus data. Simpan email di satu tabel dengan unique constraint, sisanya pakai surrogate key.

Pilih integer atau UUID buat surrogate key?

Integer lebih kecil, lebih cepat di-join, dan enak dibaca waktu debugging. UUID lebih pas kalau ID-nya dibikin di banyak sistem sekaligus atau bakal muncul di URL publik. Buat tabel analitik yang isinya jutaan baris dan sering di-join, integer biasanya menang dari sisi kecepatan.

Gimana cara ngecek natural key saya beneran unik?

Jalankan GROUP BY di kolom itu lalu saring pakai HAVING COUNT(*) > 1. Kalau hasilnya kosong, aman untuk sekarang. Tapi ulangi pengecekan ini tiap kali ada sumber data baru masuk, soalnya keunikan yang berlaku di satu sistem sering langsung rusak begitu digabung sama sistem lain.

Kenapa data warehouse selalu pakai surrogate key?

Karena tabel dimensi harus bisa nyimpen riwayat. Kalau satu pelanggan pindah kota, kamu butuh dua baris untuk pelanggan yang sama: versi lama dan versi baru. Natural key nggak bisa dipakai sebagai primary key di situ karena nilainya kembar. Surrogate key ngasih tiap versi identitas sendiri.

Pola yang aman dipakai default

Surrogate key jadi primary key, natural key dikasih unique constraint, dan simpan ID asli tiap sumber di tabel pemetaan terpisah.

Tiga hal itu nutup hampir semua kasus yang bakal kamu temuin, dan biayanya cuma satu kolom tambahan.

Coba cek satu tabel di database kamu sekarang: jalanin GROUP BY di kolom yang kamu anggap unik, lihat ada duplikat atau nggak. Kalau kamu masih ngasah dasar SQL-nya, latihan soalnya ada di kumpulan latihan SQL tingkat menengah.

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