Lompati ke konten utama
Modul 9 · Pelajaran 2 dari 434/57 dalam kursus~12 min
Pelajaran modul (2/4)

Batasan berganda dan tingkat tabel

Memastikan bahwa data dalam database sudah benar pada lapisan paling dasar ("integritas data") adalah hal yang mendasar. Jika Anda hanya menulis keamanan ke dalam aplikasi Node.js, bug dapat menyebabkan data di DB tidak konsisten. Kendala di level DDL adalah garis pertahanan terakhir yang tidak bisa ditembus.

Kendala utama

Selain PRIMARY KEY (yang menjadikan kolom unik dan BUKAN NULL) dan NOT NULL klasik dan UNIQUE, ada dua kategori mendasar untuk konsistensi logis data:

1. KUNCI ASING (Integritas Referensial)

Batasan REFERENCES memastikan bahwa ID penautan benar-benar ada di tabel "induk" yang ditunjuknya. Misalnya, pesanan harus ditautkan ke pelanggan yang ada.

SQL
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  customer_id INTEGER REFERENCES customers(id)
);

Apa yang dilakukan Kunci Asing?

  • Ini mencegah Anda memasukkan customer_id yang tidak ada di customers.
  • Ini mencegah Anda dari DELETE (menghapus) pelanggan dari customers jika ada pesanan yang mengarah ke mereka (ini melindungi dari catatan "yatim piatu").

Kita juga dapat memutuskan apa yang akan terjadi bila "induk" dihapus:

SQL
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE

Dengan ON DELETE CASCADE, jika kami menghapus pelanggan, Postgres akan secara otomatis menghapus semua orders yang tertaut! (Gunakan dengan sangat hati-hati; biasanya pengaturan default yang memblokir pengoperasian lebih disukai.)

2. PERIKSA Batasan

Batasan CHECK memvalidasi baris dengan menguji ekspresi boolean sebelum melanjutkan untuk menyimpan.

SQL
CREATE TABLE contratti (
  id SERIAL PRIMARY KEY,
  stipendio NUMERIC(10,2) CHECK (stipendio > 0),
  data_inizio DATE,
  data_fine DATE,
  CHECK (data_fine > data_inizio)
);

CHECK pertama adalah batasan kolom (hanya mengacu pada stipendio). CHECK kedua di bawah adalah batasan tabel (dapat melintasi nilai dari beberapa kolom, dan harus dideklarasikan di bagian bawah).

Jika INSERT atau UPDATE mencoba menyimpan akhir sebelum awal, Postgres akan menolaknya dengan kesalahan!

Batasan Penamaan

Seringkali merupakan praktik yang baik untuk memberi batasan nama yang eksplisit (menggunakan kata kunci CONSTRAINT). Dengan cara ini, ketika Postgres memblokir catatan, kesalahan akan memberi tahu Anda misalnya "batasan 'stipendio_positivo' dilanggar", yang jauh lebih jelas untuk proses debug!

SQL
CREATE TABLE prodotti (
  id SERIAL PRIMARY KEY,
  nome VARCHAR(50),
  CONSTRAINT nome_univoco UNIQUE(nome)
);

Cobalah

Latihan#sql.m9.l2.e1
Upaya: 0Memuat…

Buat tabel 'prenotazioni' dengan id (SERIAL PRIMARY KEY) dan 'customer_id' (INTEGER). Gunakan CONSTRAINT fk_cliente FOREIGN KEY (customer_id) REFERENCES pelanggan(id) untuk memberikan nama eksplisit pada batasan Kunci Asing. Lakukan di bagian bawah, sebagai batasan tabel.

Memuat editor…
Tunjukkan petunjuk

Tulis CONSTRAINT fk_cliente FOREIGN KEY (local_column) REFERENSI external_table(external_col)

Solusi tersedia setelah 3 upaya

Batasan dengan logika khusus

Latihan#sql.m9.l2.e2
Upaya: 0Memuat…

Buat tabel 'eventi' dengan id (SERIAL PRIMARY KEY), posti_totali (INTEGER) dan biglietti_venduti (INTEGER). Tambahkan batasan tabel bernama 'check_capienza' di mana biglietti_venduti tidak boleh lebih besar dari posti_totali.

Memuat editor…
Tunjukkan petunjuk

Tambahkan batasan di bagian bawah menggunakan CONSTRAINT check_capienza CHECK (ekspresi)

Solusi tersedia setelah 3 upaya