Ilustrasi sampul artikel: Perbedaan Primary Key dan Foreign Key di SQL (Penjelasan + Contoh)
·SQLDatabaseTutorial

Perbedaan Primary Key dan Foreign Key di SQL (Penjelasan + Contoh)

Primary key adalah penanda unik tiap baris, foreign key adalah kolom yang menghubungkan ke tabel lain. Pelajari perbedaan, cara membuat, dan relasi antar tabel di SQL.

Pembuat Hyper Sheets & BelajarWeb.dev

Primary key adalah kolom yang menjadi penanda unik untuk setiap baris di sebuah tabel, sedangkan foreign key adalah kolom yang merujuk ke primary key tabel lain untuk menghubungkan kedua tabel itu. Sederhananya: primary key menjawab “baris ini yang mana?”, dan foreign key menjawab “baris ini milik siapa?”. Keduanya adalah pasangan yang bikin database relasional bisa menyimpan data yang saling terhubung, pelanggan dengan pesanannya, artikel dengan komentarnya, siswa dengan kelasnya, tanpa menyalin data berulang-ulang.

Kalau kamu baru mulai belajar SQL dan bingung kenapa sebuah tabel butuh kolom id, atau kenapa tiba-tiba muncul kolom aneh bernama user_id di tabel lain, artikel ini menjawabnya dari nol. Kita bahas berurutan: apa itu primary key dan aturannya, apa itu foreign key dan cara kerjanya, perbedaan keduanya dalam satu tabel perbandingan, cara membuat keduanya dengan CREATE TABLE, sampai bagaimana keduanya membentuk relasi antar tabel. Semua contoh SQL di sini runnable, tinggal copy ke SQLite, MySQL 8, atau PostgreSQL.

Perbedaan Primary Key dan Foreign Key

Perbedaan intinya: primary key mengidentifikasi baris di dalam tabelnya sendiri dan wajib unik, sedangkan foreign key menghubungkan tabelnya ke tabel lain dengan menunjuk ke primary key tabel tersebut, dan boleh berisi nilai yang berulang. Satu tabel biasanya hanya punya satu primary key, tapi bisa punya banyak foreign key ke tabel-tabel berbeda.

Bayangkan dua tabel: users (data pengguna) dan orders (data pesanan). Tabel users butuh cara memastikan tiap pengguna punya identitas unik, itu tugas primary key id. Tabel orders butuh cara menyimpan “pesanan ini milik siapa”, itu tugas foreign key user_id, yang nilainya adalah id dari salah satu pengguna di tabel users.

users
idPKINT
namaVARCHAR
emailVARCHAR
orders
idPKINT
user_idFKINT
totalINT
orders.user_id (foreign key) menunjuk keusers.id (primary key). Satu user bisa punya banyak order.

Perhatikan diagram di atas. Kolom id di users adalah primary key: setiap pengguna punya id yang berbeda, tidak ada yang kembar. Kolom user_id di orders adalah foreign key: nilainya selalu mengacu ke id yang benar-benar ada di users. Karena satu pengguna bisa melakukan banyak pesanan, nilai user_id yang sama boleh muncul di beberapa baris orders, inilah kenapa foreign key boleh berulang, sedangkan primary key tidak.

Ini tabel perbandingan lengkapnya:

Aspek Primary Key Foreign Key
Fungsi Penanda unik tiap baris Penghubung ke tabel lain
Harus unik? Ya, wajib Tidak, boleh berulang
Boleh NULL? Tidak pernah Boleh (artinya “belum terhubung”)
Jumlah per tabel Umumnya satu Boleh banyak
Menunjuk ke mana? Barisnya sendiri Primary key tabel lain
Dibuat otomatis? Sering pakai auto-increment Diisi dari nilai PK yang sudah ada

Primary Key Adalah… (Aturan dan Contoh)

Primary key adalah satu kolom (atau kombinasi kolom) yang nilainya unik untuk setiap baris dan dipakai database untuk membedakan satu baris dari baris lainnya. Karena tugasnya mengidentifikasi, primary key punya dua aturan mutlak: nilainya tidak boleh sama antar baris (unik), dan tidak boleh kosong/NULL. Tanpa keduanya, database tidak bisa menjamin ia sedang menunjuk ke baris yang benar.

Cara membuatnya di CREATE TABLE:

CREATE TABLE users (
  id    INTEGER PRIMARY KEY,   -- primary key: unik & tidak boleh NULL
  nama  TEXT NOT NULL,
  email TEXT NOT NULL
);

Kata kunci PRIMARY KEY di belakang kolom id memberi tahu database: kolom inilah identitas baris. Sekali sebuah id dipakai, database akan menolak baris baru dengan id yang sama.

INSERT INTO users (id, nama, email) VALUES
  (1, 'Andi',  '[email protected]'),
  (2, 'Bunga', '[email protected]');

-- Baris di bawah GAGAL: id = 1 sudah dipakai Andi
INSERT INTO users (id, nama, email) VALUES
  (1, 'Citra', '[email protected]');

Di praktik nyata, kamu jarang mengisi id secara manual. Database bisa mengisinya otomatis dan berurutan lewat auto-increment, jadi kamu tinggal memasukkan data lain dan id terisi sendiri:

-- Sintaks auto-increment berbeda tiap database:
-- SQLite  : INTEGER PRIMARY KEY AUTOINCREMENT
-- MySQL   : INT AUTO_INCREMENT PRIMARY KEY
-- Postgres: SERIAL PRIMARY KEY  (atau GENERATED ALWAYS AS IDENTITY)

CREATE TABLE users (
  id    INTEGER PRIMARY KEY AUTOINCREMENT,
  nama  TEXT NOT NULL,
  email TEXT NOT NULL
);

-- id tidak perlu diisi, database yang menentukan
INSERT INTO users (nama, email) VALUES ('Andi', '[email protected]');   -- id jadi 1
INSERT INTO users (nama, email) VALUES ('Bunga', '[email protected]'); -- id jadi 2

Foreign Key Adalah… (Aturan dan Contoh)

Foreign key adalah kolom di sebuah tabel yang nilainya harus cocok dengan primary key di tabel lain, sehingga kedua tabel jadi terhubung. Foreign key inilah yang membuat database disebut “relasional”, ia adalah benang yang mengikat tabel-tabel yang terpisah menjadi satu jaringan data yang masuk akal.

Sekarang buat tabel orders yang terhubung ke users lewat foreign key:

CREATE TABLE orders (
  id      INTEGER PRIMARY KEY,
  user_id INTEGER NOT NULL,      -- kolom yang akan jadi foreign key
  total   INTEGER NOT NULL,
  FOREIGN KEY (user_id) REFERENCES users(id)
);

Baris FOREIGN KEY (user_id) REFERENCES users(id) adalah kuncinya. Terjemahannya: “kolom user_id di tabel ini wajib berisi nilai yang benar-benar ada di kolom id tabel users”. Aturan ini disebut referential integrity (integritas rujukan), database akan menjaganya untukmu.

-- BERHASIL: user_id = 1 (Andi) memang ada di tabel users
INSERT INTO orders (id, user_id, total) VALUES (1, 1, 150000);
INSERT INTO orders (id, user_id, total) VALUES (2, 1, 90000);   -- Andi pesan lagi, boleh
INSERT INTO orders (id, user_id, total) VALUES (3, 2, 200000);  -- pesanan Bunga

-- GAGAL: user_id = 99 tidak ada di tabel users
INSERT INTO orders (id, user_id, total) VALUES (4, 99, 50000);

Perhatikan dua hal penting. Pertama, user_id = 1 muncul dua kali (baris 1 dan 2), itu sah, karena Andi memang boleh punya banyak pesanan. Kedua, memasukkan user_id = 99 ditolak karena tidak ada pengguna ber-id 99. Inilah perlindungan yang diberikan foreign key: database mencegah munculnya pesanan “hantu” yang tidak punya pemilik.

Bagaimana PK dan FK Membentuk Relasi Antar Tabel

Pasangan primary key dan foreign key inilah yang menciptakan relasi antar tabel, paling sering relasi “satu ke banyak” (one-to-many): satu baris di tabel induk terhubung ke banyak baris di tabel anak. Dalam contoh kita, satu users (induk) bisa punya banyak orders (anak). Primary key ada di sisi “satu”, foreign key ada di sisi “banyak”.

Setelah relasi terbentuk, kamu bisa menggabungkan data dari kedua tabel dengan JOIN, mencocokkan foreign key dengan primary key-nya:

-- Tampilkan nama pemesan di sebelah tiap pesanan
SELECT u.nama, o.id AS order_id, o.total
FROM orders o
JOIN users u ON u.id = o.user_id
ORDER BY o.id;

Baris ON u.id = o.user_id adalah tempat pertemuan PK dan FK: primary key users.id disamakan dengan foreign key orders.user_id. Hasilnya, tiap pesanan tampil lengkap dengan nama pemiliknya:

nama order_id total
Andi 1 150000
Andi 2 90000
Bunga 3 200000

Andi muncul dua kali karena punya dua pesanan, persis relasi one-to-many yang tadi kita rancang. Kalau mekanisme JOIN ini masih terasa baru, konsepnya kita bahas lebih dalam (dan bisa kamu latih langsung di browser) di lesson relasi tabel Hyper Sheets, yang membangun contoh users-orders seperti ini dari awal.

Pola relasi ini adalah fondasi dari hampir semua aplikasi yang kamu pakai sehari-hari. Setelah data tersimpan rapi dalam tabel-tabel yang terhubung, kamu bisa menyusun query analitik yang lebih rumit di atasnya, misalnya menggabungkan beberapa langkah query dengan CTE (Common Table Expression) supaya laporan yang panjang tetap terbaca. Dan kalau kamu mengakses database lewat framework, relasi PK-FK ini biasanya sudah dibungkus rapi oleh ORM, misalnya lewat Eloquent yang kita bahas di panduan belajar Laravel untuk pemula.

Composite Primary Key (Ketika Satu Kolom Tidak Cukup)

Composite primary key adalah primary key yang terdiri dari gabungan dua kolom atau lebih, dipakai ketika tidak ada satu kolom pun yang bisa menjamin keunikan sendirian. Contoh paling khas adalah tabel penghubung many-to-many, misalnya pendaftaran yang mencatat siswa mana ambil kelas mana:

CREATE TABLE pendaftaran (
  siswa_id INTEGER NOT NULL,
  kelas_id INTEGER NOT NULL,
  tanggal  DATE NOT NULL,
  PRIMARY KEY (siswa_id, kelas_id),          -- kombinasi keduanya = unik
  FOREIGN KEY (siswa_id) REFERENCES siswa(id),
  FOREIGN KEY (kelas_id) REFERENCES kelas(id)
);

Di sini siswa_id sendiri tidak unik (satu siswa ambil banyak kelas), kelas_id sendiri juga tidak unik (satu kelas diambil banyak siswa), tapi kombinasi keduanya unik: satu siswa hanya boleh terdaftar sekali di satu kelas. Perhatikan juga tabel ini punya dua foreign key sekaligus, satu ke siswa dan satu ke kelas. Inilah bentuk konkret tabel penghubung many-to-many yang disebut di callout tadi.

Kesalahan Umum Pemula Soal Primary & Foreign Key

Kesalahan tersering: lupa memberi primary key sama sekali, menaruh foreign key di tabel yang salah, dan mengira foreign key harus unik seperti primary key. Berikut yang paling sering menjebak di minggu-minggu pertama:

  1. Tabel tanpa primary key. Secara teknis boleh, tapi ini pintu masalah: baris jadi susah dirujuk, mudah terduplikasi, dan tidak bisa jadi target foreign key. Biasakan setiap tabel punya id primary key.
  2. Menaruh foreign key di sisi “satu”. Foreign key selalu diletakkan di tabel sisi “banyak”. Pesanan yang menyimpan user_id, bukan pengguna yang menyimpan daftar order_id. Salah sisi = relasi tidak jalan.
  3. Mengira FK wajib unik. Ini kebalikan dari primary key. Foreign key justru dirancang untuk berulang, itulah yang memungkinkan satu induk punya banyak anak.
  4. Tipe data PK dan FK berbeda. Kalau users.id bertipe INTEGER, maka orders.user_id juga harus INTEGER. Tipe yang tidak cocok bikin database menolak membuat relasinya.
  5. Lupa mengaktifkan foreign key di SQLite. Seperti di callout sebelumnya, tanpa PRAGMA foreign_keys = ON;, aturan rujukannya diabaikan diam-diam.
Cek Pemahaman

Di tabel orders yang punya foreign key user_id menunjuk ke users.id, kenapa nilai user_id boleh muncul berkali-kali (misalnya user_id = 1 di beberapa baris)?

FAQ Seputar Primary Key dan Foreign Key

Apa itu primary key dalam SQL?

Primary key adalah kolom (atau gabungan kolom) yang menjadi penanda unik untuk setiap baris di sebuah tabel. Nilainya wajib unik dan tidak boleh NULL, sehingga database bisa memastikan ia selalu menunjuk ke baris yang tepat. Umumnya berupa kolom id angka yang diisi otomatis lewat auto-increment.

Apa itu foreign key dalam SQL?

Foreign key adalah kolom di sebuah tabel yang nilainya merujuk ke primary key tabel lain, sehingga kedua tabel terhubung. Foreign key menjaga integritas rujukan: database menolak nilai yang tidak ada di tabel tujuan, sehingga mencegah data “yatim” yang tidak punya induk.

Apa perbedaan utama primary key dan foreign key?

Primary key mengidentifikasi baris di dalam tabelnya sendiri dan wajib unik; foreign key menghubungkan tabelnya ke tabel lain dan boleh berisi nilai yang berulang. Satu tabel umumnya punya satu primary key tapi boleh punya banyak foreign key. Singkatnya: PK menunjuk ke dalam (identitas), FK menunjuk keluar (relasi).

Apakah foreign key harus unik?

Tidak. Justru sebaliknya, foreign key dirancang boleh berulang. Karena satu baris induk (misalnya satu pengguna) bisa terhubung ke banyak baris anak (misalnya banyak pesanan), nilai foreign key yang sama wajar muncul berkali-kali. Yang harus unik adalah primary key yang dirujuknya.

Bisakah satu tabel punya lebih dari satu primary key?

Tidak, satu tabel hanya boleh punya satu primary key. Tapi primary key itu boleh terdiri dari beberapa kolom sekaligus (disebut composite primary key), yang keunikannya dinilai dari kombinasi kolom-kolom tersebut. Ini berbeda dengan foreign key, yang boleh ada beberapa dalam satu tabel.

Apakah foreign key boleh NULL?

Boleh, dan itu punya arti: baris tersebut belum terhubung ke induk mana pun. Misalnya kolom manajer_id di tabel karyawan bisa NULL untuk karyawan yang belum punya manajer. Ini berbeda dari primary key yang tidak pernah boleh NULL. Kalau kamu ingin relasi selalu wajib terisi, tambahkan NOT NULL pada kolom foreign key-nya.

Langkah Selanjutnya

Kamu sekarang sudah paham dua pilar database relasional: primary key yang memberi identitas unik pada tiap baris, dan foreign key yang menjalin tabel-tabel jadi satu jaringan data yang saling terhubung. Dari sini, semua konsep SQL lanjutan, JOIN, relasi many-to-many, sampai desain skema, tinggal menumpuk di atas fondasi ini.

Cara tercepat membuatnya melekat adalah membangun relasi users-orders-mu sendiri dan menjalankan JOIN-nya. Mulai dari lesson relasi tabel di Hyper Sheets yang latihannya langsung dinilai di browser, lalu lanjut ke panduan CTE SQL begitu kamu mau menyusun query yang lebih kompleks di atas tabel-tabel yang sudah terhubung. Selamat ngoding!