Lompat ke konten
Kembali ke modul

Data: Database dan SQL · 2/7

Tabel, kolom, key, dan relasi

Memodelkan hal nyata sebagai baris, dan menghubungkannya tanpa menduplikasi data.

Baca 30 menit

Setelah pelajaran ini kamu bisa

  • Merancang tabel dengan kolom dan type yang tepat
  • Memakai primary key dan foreign key untuk menghubungkan tabel
  • Menjelaskan normalisasi sebagai cara menghindari kontradiksi
  • Memilih constraint yang membuat data buruk jadi mustahil

Tabel adalah daftar hal-hal dari satu jenis. Row adalah salah satu dari hal itu. Kolom adalah satu fakta tentang masing-masingnya. Pekerjaan desainnya adalah menentukan apa yang dihitung sebagai "satu jenis hal".

sql
CREATE TABLE users (
  id    INTEGER PRIMARY KEY,          -- uniquely identifies a row
  name  TEXT    NOT NULL UNIQUE       -- must exist, and no two the same
);

CREATE TABLE venues (
  id              INTEGER PRIMARY KEY,
  name            TEXT    NOT NULL,
  price_per_night INTEGER NOT NULL CHECK (price_per_night > 0),
  owner_id        INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
);

CREATE TABLE bookings (
  id       INTEGER PRIMARY KEY,
  venue_id INTEGER NOT NULL REFERENCES venues(id) ON DELETE CASCADE,
  guest    TEXT    NOT NULL,
  nights   INTEGER NOT NULL,
  paid     INTEGER NOT NULL DEFAULT 0
);
Tiga tabel, tiga jenis hal. price_per_night adalah INTEGER dari satuan mata uang terkecil — aturan uang dari modul 2, diterapkan pada penyimpanan.

Key

  • Primary key — kolom yang mengidentifikasi sebuah row. Satu per tabel, tidak pernah dipakai ulang, tidak pernah berubah.
  • Foreign key — kolom yang menyimpan primary key tabel lain. bookings.venue_id menyatakan booking ini untuk venue yang mana.
  • Unique — tidak ada dua row yang boleh punya nilai ini sama. Tidak sama dengan primary key: sebuah tabel bisa punya beberapa kolom unique.
text
-- With foreign keys ON, the database refuses impossible data.
-- These are the real error messages, from this project's SQLite:

INSERT INTO venues (name, price_per_night, owner_id) VALUES ('Orphan', 100, 999);
=> FOREIGN KEY constraint failed

INSERT INTO venues (name, price_per_night, owner_id) VALUES ('Bad', -5, 1);
=> CHECK constraint failed: price_per_night > 0

INSERT INTO users (name) VALUES ('Ana');     -- already exists
=> UNIQUE constraint failed: users.name
Error-error ini adalah fitur. Constraint di database tetap berlaku bahkan saat ada bug di kodemu, atau aplikasi kedua, yang mencoba menulis data ngawur.

Normalisasi

Normalisasi berarti menyimpan setiap fakta di tepat satu tempat. Terdengar akademis; versi praktisnya adalah data yang diduplikasi cepat atau lambat akan bertentangan dengan dirinya sendiri.

Coba sendiri

Nama owner yang sama disimpan di tiga row versus disimpan sekali. Lalu owner-nya mengganti namanya.

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Relasi

JenisContohCaranya
Satu ke banyakSebuah venue punya banyak bookingForeign key di sisi 'banyak'
Satu ke satuSeorang user punya satu profilForeign key dengan constraint UNIQUE
Banyak ke banyakSebuah venue punya banyak tag, sebuah tag punya banyak venueTabel ketiga yang menghubungkan keduanya
sql
-- Many to many needs a join table. Note the composite primary key:
-- it makes a duplicate pairing impossible.
CREATE TABLE venue_tags (
  venue_id INTEGER NOT NULL REFERENCES venues(id) ON DELETE CASCADE,
  tag_id   INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
  PRIMARY KEY (venue_id, tag_id)
);
Proyek ini memakai ide yang sama di lesson_progress: PRIMARY KEY (user_id, lesson_id) berarti satu learner tidak bisa menyelesaikan satu pelajaran dua kali.

Tugas praktik

Rancang tabel untuk blog sederhana: authors, posts, comments, dan tags. Tulis statement CREATE TABLE-nya dengan primary key, foreign key, NOT NULL di tempat yang tepat, dan satu CHECK. Putuskan apa yang harus terjadi saat seorang author dihapus, dan pastikan kamu bisa membelanya. Lalu bandingkan skemamu dengan MIGRATIONS di features/db/index.ts.

Hasil yang diharapkan

Empat tabel plus satu tabel join untuk tag postingan.