Kardinalitas & Relasi — Database

Kardinalitas dalam Database Kardinalitas menjelaskan jumlah hubungan antara dua entitas. Ini menentukan bagaimana tabel saling terhubung. 1. One-to-One (1:1)…

Kardinalitas adalah jawaban untuk pertanyaan "satu baris di tabel A boleh terhubung dengan berapa baris di tabel B, dan sebaliknya?". Jawabannya cuma tiga kemungkinan, dan kamu sudah mengenal ketiganya dari hidup sehari-hari: satu orang punya satu KTP (1:1), satu ibu bisa punya banyak anak tapi tiap anak punya satu ibu kandung (1:N), dan satu siswa ikut banyak ekskul sementara tiap ekskul punya banyak siswa (M:N). Kardinalitas menentukan di mana foreign key ditaruh, jadi salah menebaknya berarti salah membuat tabel.

🧪 Tebakan cepat: pesanan #1 Kedai Senja berisi Kopi Susu dan Roti Bakar, dan Kopi Susu juga ada di pesanan #3. Kolom penunjuknya ditaruh di tabel orders, di tabel products, atau di tempat lain? Tebak dulu, jawabannya ada di bagian "Many-to-many: butuh tabel perantara".

Satu pertanyaan, dua arah

Kardinalitas selalu ditanyakan dari dua arah, dengan contoh data yang nyata:

Pasangan Satu A punya berapa B? Satu B milik berapa A? Kardinalitas
customers dan profiles satu (alamat dan tanggal lahir) satu 1:1 one-to-one
customers dan orders banyak (Budi pesan 2 kali) satu (tiap pesanan punya 1 pemilik) 1:N one-to-many
orders dan products banyak (Kopi Susu dan Roti Bakar) banyak (Kopi Susu ada di #1 dan #3) M:N many-to-many

Pasangan lain yang sering ketemu: user dan profile (1:1), user dan post di blog (1:N), order dan baris item-nya (1:N), student dan course (M:N), tag dan article (M:N). Mahasiswa dan mata kuliah juga M:N: satu mahasiswa mengambil banyak mata kuliah, satu mata kuliah diambil banyak mahasiswa. M:N kadang ditulis N:M atau N:N, artinya sama.

One-to-one (1:1)

Satu customer punya paling banyak satu profile. Foreign key customer_id ditaruh di profiles, ditambah UNIQUE supaya gak ada profile kedua:

CREATE TABLE profiles (
  id INTEGER PRIMARY KEY,
  customer_id INTEGER NOT NULL UNIQUE REFERENCES customers(id),
  address TEXT NOT NULL
);

INSERT INTO profiles (id, customer_id, address) VALUES (1, 1, 'Jl. Melati 5');
INSERT INTO profiles (id, customer_id, address) VALUES (3, 1, 'Jl. Mawar 9');
-- Error: UNIQUE constraint failed: profiles.customer_id

One-to-many (1:N)

Satu customer punya banyak orders, tiap order milik satu customer. Foreign key ditaruh di sisi banyak, yaitu orders.customer_id, tanpa UNIQUE:

CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer_id INTEGER NOT NULL REFERENCES customers(id),
  ordered_at TEXT NOT NULL
);

Budi pesan dua kali, jadi dua baris orders sama-sama berisi customer_id = 1, dan itu sah. Pesanan #1 gak bisa sekaligus milik Siti: sel customer_id-nya cuma muat satu angka, dan baris kedua dengan id = 1 ditolak (UNIQUE constraint failed: orders.id). Kalau UNIQUE dari contoh 1:1 tadi ikut ditempel di sini, pesanan kedua Budi yang ditolak: modelnya terlalu ketat.

Many-to-many: butuh tabel perantara

Orders dan products gak bisa dihubungkan dengan satu foreign key biasa:

Jadi jawabannya: di tempat lain, yaitu tabel baru di tengah. Itu jawaban tebakannya. Tabel ini disebut tabel perantara (junction table, atau pivot table di Laravel), dan isinya pasangan foreign key dari kedua sisi:

CREATE TABLE order_items (
  order_id INTEGER NOT NULL REFERENCES orders(id),
  product_id INTEGER NOT NULL REFERENCES products(id),
  qty INTEGER NOT NULL,
  PRIMARY KEY (order_id, product_id)
);

INSERT INTO order_items (order_id, product_id, qty) VALUES (1, 1, 2);  -- #1: 2 Kopi Susu
INSERT INTO order_items (order_id, product_id, qty) VALUES (1, 4, 1);  -- #1: 1 Roti Bakar
INSERT INTO order_items (order_id, product_id, qty) VALUES (3, 1, 1);  -- #3: 1 Kopi Susu

Di mana foreign key-nya

Kardinalitas Foreign key Penjaga
1:1 di salah satu tabel, biasanya yang opsional (profiles.customer_id) UNIQUE
1:N di sisi banyak (orders.customer_id) foreign key biasa
M:N di tabel perantara, dua-duanya (order_items) PRIMARY KEY gabungan

📌 Relasi ke diri sendiri

Kadang tabel menunjuk dirinya sendiri, disebut self-referencing. Contohnya karyawan dan atasannya: kolom manager_id di employees menunjuk employees.id. Kardinalitasnya tetap 1:N (satu atasan, banyak bawahan), cuma kedua sisinya tabel yang sama.

⚠️ Jebakan yang sering ketemu

TL;DR: Kardinalitas menjawab "satu A terhubung dengan berapa B, dan sebaliknya", ditanyakan dua arah dengan data nyata. 1:1 (customer dan profile, user dan profile): foreign key plus UNIQUE. 1:N (customer dan orders, user dan post, order dan item-nya): foreign key di sisi banyak. M:N (orders dan products, student dan course, tag dan article): tabel perantara seperti order_items dengan dua foreign key dan primary key gabungan; foreign key biasa saja gak cukup.

Yang akan kamu pelajari