Modulelessen (2/4)
Beperkingen op meerdere niveaus en op tabelniveau
Ervoor zorgen dat de gegevens in de database correct zijn op de meest basale laag ("data-integriteit") is van fundamenteel belang. Als u alleen veiligheid in de Node.js-toepassing schrijft, kunnen bugs inconsistente gegevens in de database veroorzaken. Beperkingen op DDL-niveau vormen de laatste, ondoordringbare verdedigingslinie.
De belangrijkste beperkingen
Naast PRIMARY KEY (wat een kolom uniek maakt en NIET NULL) en de klassieke NOT NULL en UNIQUE, zijn er twee fundamentele categorieën voor de logische consistentie van de gegevens:
1. BUITENLANDSE SLEUTEL (referentiële integriteit)
Een beperking REFERENCES zorgt ervoor dat een koppelings-ID werkelijk bestaat in de 'bovenliggende' tabel waarnaar deze verwijst.
Een bestelling moet bijvoorbeeld gekoppeld zijn aan een bestaande klant.
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id)
);Wat doet de buitenlandse sleutel?
- Het voorkomt dat u een
customer_idinvoegt die niet bestaat incustomers. - Het voorkomt dat u een klant
DELETE(verwijdert) uitcustomersals er bestellingen naar hem verwijzen (het beschermt tegen "verweesde" records).
We kunnen ook beslissen wat er moet gebeuren als de "ouder" wordt verwijderd:
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADEAls we met ON DELETE CASCADE de klant verwijderen, verwijdert Postgres automatisch alle gekoppelde orders! (Wees uiterst voorzichtig; normaal gesproken verdient de standaardinstelling die de bewerking blokkeert de voorkeur.)
2. CONTROLEER beperkingen
Een beperking CHECK valideert de rij door een Booleaanse expressie te testen voordat u doorgaat met opslaan.
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)
);De eerste CHECK is een kolombeperking (deze verwijst alleen naar stipendio).
De tweede CHECK onderaan is een tabelbeperking (deze kan waarden uit meerdere kolommen overschrijden en moet onderaan worden gedeclareerd).
Als een INSERT of UPDATE het einde vóór het begin probeert op te slaan, zal Postgres dit afwijzen met een foutmelding!
Naamgevingsbeperkingen
Het is vaak een goede gewoonte om beperkingen een expliciete naam te geven (met behulp van het trefwoord CONSTRAINT). Op deze manier zal, wanneer Postgres een record blokkeert, de fout u bijvoorbeeld vertellen dat de beperking 'stipendio_positivo' is geschonden', wat veel duidelijker is bij het debuggen!
CREATE TABLE prodotti (
id SERIAL PRIMARY KEY,
nome VARCHAR(50),
CONSTRAINT nome_univoco UNIQUE(nome)
);Probeer het
Maak een 'prenotazioni'-tabel met id (SERIAL PRIMARY KEY) en een 'customer_id' (INTEGER). Gebruik CONSTRAINT fk_cliente FOREIGN KEY (klant_id) REFERENTIES klanten(id) om een expliciete naam te geven aan de beperking van de buitenlandse sleutel. Doe het onderaan, als tabelbeperking.
Toon hint
Schrijf CONSTRAINT fk_cliente FOREIGN KEY (lokale_kolom) REFERENTIES externe_tabel (externe_col)
Oplossing beschikbaar na 3 pogingen
Beperkingen met aangepaste logica
Maak een 'eventi'-tabel met id (SERIAL PRIMARY KEY), posti_totali (INTEGER) en biglietti_venduti (INTEGER). Voeg een tabelbeperking toe met de naam 'check_capienza', waarbij biglietti_venduti nooit groter mag zijn dan posti_totali.
Toon hint
Voeg de beperking onderaan toe met CONSTRAINT check_capienza CHECK (expressie)
Oplossing beschikbaar na 3 pogingen