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".
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
);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_idmenyatakan 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.
-- 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.nameNormalisasi
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.
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
| Jenis | Contoh | Caranya |
|---|---|---|
| Satu ke banyak | Sebuah venue punya banyak booking | Foreign key di sisi 'banyak' |
| Satu ke satu | Seorang user punya satu profil | Foreign key dengan constraint UNIQUE |
| Banyak ke banyak | Sebuah venue punya banyak tag, sebuah tag punya banyak venue | Tabel ketiga yang menghubungkan keduanya |
-- 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)
);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.