Immagina di avere due tabelle: una con i dati degli studenti e un'altra con i dati dei corsi. Secondo te, come si può rappresentare l'informazione su quali studenti sono iscritti a quali corsi? Potresti aggiungere una colonna nella tabella degli studenti per salvare tutti i corsi a cui sono iscritti, ma questo porterebbe subito al caos. Una delle soluzioni migliori è usare le chiavi esterne!
Chiave esterna (FOREIGN KEY) — è una colonna o un insieme di colonne che viene usato per creare una relazione tra tabelle. Indica una colonna (di solito il PRIMARY KEY) in un'altra tabella, garantendo l'integrità referenziale dei dati tra di loro. Quindi, se uno studente è iscritto a un corso, possiamo essere sicuri che quel corso esista davvero.
Le chiavi esterne:
- Aiutano a mantenere l'integrità dei dati, garantendo che i record in una tabella corrispondano ai dati in un'altra.
- Rendono il database chiaro e logicamente organizzato.
- Semplificano la gestione dei dati, prevengono duplicazioni ed errori.
Esempio dalla vita reale
Immagina una biblioteca. La tabella books contiene la lista dei libri, mentre la tabella members — la lista dei lettori. Per tracciare chi ha preso quale libro, possiamo creare una tabella borrowed_books, che farà riferimento a books e members tramite chiavi esterne. Così, ogni volta che qualcuno prende un libro, sappiamo esattamente chi era e quale libro ha preso.
Tipi di relazioni tra tabelle
Le chiavi esterne permettono di descrivere diversi tipi di relazioni tra tabelle. Vediamo insieme i tre tipi principali:
1. Relazione "Uno-a-Uno" (ONE-TO-ONE)
Questa è la relazione più semplice, dove un record in una tabella corrisponde esattamente a un record in un'altra tabella. Ad esempio, la tabella users può contenere informazioni sugli utenti, mentre la tabella profiles può contenere informazioni aggiuntive, come indirizzi o foto.
Esempio SQL per la relazione ONE-TO-ONE:
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
username TEXT NOT NULL
);
CREATE TABLE profiles (
profile_id SERIAL PRIMARY KEY,
user_id INT UNIQUE REFERENCES users(user_id), -- riferimento a users.user_id
address TEXT
);
Qui la colonna user_id nella tabella profiles agisce come chiave esterna che fa riferimento a user_id nella tabella users.
Esempio della tabella users:
| user_id - PRIMARY KEY | username |
|---|---|
| 1 | alice |
| 2 | bob |
| 3 | charlie |
Esempio della tabella profiles:
| profile_id - PRIMARY KEY | user_id - FOREIGN KEY | address |
|---|---|---|
| 1 | 1 | Berlino, Germania |
| 2 | 2 | Parigi, Francia |
| 3 | 3 | Tokyo, Giappone |
2. Relazione "Uno-a-Molti" (ONE-TO-MANY)
Questa è la relazione più comune. Ad esempio, un cliente può fare molti ordini. In questo caso la tabella customers sarà collegata alla tabella orders tramite una chiave esterna.
Esempio SQL per la relazione ONE-TO-MANY:
CREATE TABLE customers (
customer_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(customer_id), -- riferimento a customers.customer_id
order_date DATE NOT NULL
);
La tabella orders può contenere molti record che fanno riferimento a un record nella tabella customers
Esempio della tabella customers:
| customer_id - PRIMARY KEY | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
Esempio della tabella orders:
| order_id - PRIMARY KEY | customer_id - FOREIGN KEY | order_date |
|---|---|---|
| 1 | 1 | 2024-12-01 |
| 2 | 1 | 2024-12-05 |
| 3 | 2 | 2024-12-03 |
| 4 | 3 | 2024-12-07 |
3. Relazione "Molti-a-Molti" (MANY-TO-MANY)
A volte un record in una tabella può essere collegato a più record in un'altra tabella, e viceversa. Ad esempio, gli studenti si iscrivono ai corsi, e in un corso possono esserci molti studenti. Per questo di solito si crea una tabella intermedia.
Esempio SQL per la relazione MANY-TO-MANY:
-- studenti
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
-- corsi
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL
);
-- "iscrizione di uno studente a un corso specifico"
CREATE TABLE enrollments (
student_id INT REFERENCES students(student_id), -- riferimento a id-studente
course_id INT REFERENCES courses(course_id), -- riferimento a id-corso
PRIMARY KEY (student_id, course_id)
);
Qui la tabella enrollments fa da "ponte" tra le tabelle students e courses.
Esempio della tabella students:
| student_id - PRIMARY KEY | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
Esempio della tabella courses:
| course_id - PRIMARY KEY | title |
|---|---|
| 1 | SQL Basics |
| 2 | Data Structures |
| 3 | Algorithms |
Esempio della tabella enrollments:
| student_id - FOREIGN KEY | course_id - FOREIGN KEY |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 3 | 3 |
Vantaggi dell'uso delle chiavi esterne
- I dati restano coerenti. Se una chiave esterna punta a un record inesistente, PostgreSQL non permette di inserire o aggiornare i dati.
- Semplifica il lavoro con le tabelle. Le chiavi esterne permettono di collegare facilmente i dati tra le tabelle e fare query complesse come
JOIN. - Comportamento automatico. Puoi configurare le azioni quando vengono eliminate o aggiornate le righe collegate (ad esempio, eliminazione a cascata, impostare
NULL, ecc.).
Come appare una chiave esterna in PostgreSQL?
Sintassi per creare una chiave esterna durante la creazione di una tabella:
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(customer_id) -- chiave esterna-riferimento
);
Qui:
customer_id— è la chiave esterna.- Fa riferimento a
customer_idnella tabellacustomers.
Puoi anche specificare esplicitamente la chiave esterna usando FOREIGN KEY:
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
Curiosità
Il termine stesso "chiave esterna" (FOREIGN KEY) viene dalla teoria dei database relazionali, sviluppata negli anni '70 da Edgar Codd. Incredibile, ma l'idea di base è così potente che ancora oggi è un elemento chiave nei database moderni. Chi ha detto che la vecchia scuola non è attuale?
Ora hai capito cos'è una chiave esterna e perché è così importante. Ti resta ancora da scoprire come crearle quando fai le tabelle e come usare correttamente le operazioni a cascata. Ma questo lo vediamo nelle prossime lezioni!
GO TO FULL VERSION