Quando si lavora con i database, è comune incontrare problemi come dati ridondanti e aggiornamenti incoerenti. La seconda forma normale è un passaggio di normalizzazione del database che si basa sulla prima forma normale (1NF) per creare tabelle più pulite e efficienti.
Comprendere la 2NF è fondamentale per chiunque lavori nel design dei database o nella gestione dei dati, e getta le basi per forme di normalizzazione superiori come la terza forma normale (3NF). In questo articolo, esploreremo come funziona la 2NF e come trasformare le tabelle per soddisfare i requisiti della 2NF, con esempi pratici. Parleremo anche dei vantaggi e degli svantaggi della 2NF e dei casi d’uso in cui si adatta meglio.
Comprensione della Seconda Forma Normale
La seconda forma normale è un passaggio di normalizzazione del database focalizzato sull’eliminazione delle dipendenze parziali. È stata introdotta da Edgar F. Codd, il pioniere dei database relazionali, come parte del suo lavoro sulla normalizzazione.
Prima che una tabella possa essere in 2NF, deve soddisfare le regole della prima forma normale:
- Atomicità: Ogni cella deve contenere un singolo valore (nessun gruppo ripetuto o array).
- Righe univoche: La tabella deve avere una chiave primaria chiara.
La 2NF va un passo oltre con una regola aggiuntiva: eliminare le dipendenze parziali.
Una dipendenza parziale si verifica quando un attributo non primo (colonna che non fa parte di alcuna chiave candidata) dipende solo da parte di una chiave composita anziché dall’intera chiave. La regola del 2NF garantisce che tutti gli attributi non primi dipendano dall’intera chiave primaria, non solo da una parte di essa. Lasciare dipendenze parziali in una tabella significa che dati ridondanti possono infiltrarsi nel database, portando a inefficienze e potenziali inconsistenze durante gli aggiornamenti o le eliminazioni.
La teoria da sola può essere un po’ noiosa, quindi diamo un’occhiata a un esempio pratico.
Di seguito è riportata una tabella di Iscrizione ai Corsi degli studenti di Datacamp.
Student ID | Course ID | Course Name | Instructor Name |
---|---|---|---|
1001 | 201 | Fondamenti di SQL | Ken Smith |
1002 | 202 | Introduzione a Python | Merlin O’Donnell |
1001 | 202 | Introduzione a Python | Merlin O’Donnell |
Qui, la chiave primaria è il composto di ID Studente e ID Corso. Tuttavia, gli attributi non primi Nome Corso e Quota Corso dipendono solo da ID Corso, non dall’intera chiave. Questo viola la 2NF.
Passaggi per Decomporre le Tabelle per Raggiungere la 2NF
Per assicurarti che una tabella segua le regole della 2NF, devi:
- Identificare Tutte le Chiavi Candidate: Determinare i set minimi di attributi che identificano univocamente le righe nella tabella. Queste sono le tue chiavi candidate.
- Determinare le Dipendenze Funzionali: Identificare tutte le dipendenze funzionali nella tabella. In particolare, cerca dipendenze in cui gli attributi non primari (quelli che non fanno parte di alcuna chiave candidata) dipendono solo da una parte di una chiave composta.
- Elimina le Dipendenze Parziali: Per ogni dipendenza parziale:
- Sposta gli attributi dipendenti in una nuova tabella insieme alla parte della chiave da cui dipendono.
- Assicurati che la nuova tabella abbia una chiave primaria unica.
- Ripeti Fino a Quando Non Rimangono Dipendenze Parziali: Conferma che ogni attributo non primario in tutte le tabelle dipenda completamente dalla sua rispettiva chiave primaria.
Esempi di Seconda Forma Normale in Pratica
Vediamo ora due esempi.
Esempio 1: Tabella di iscrizione ai corsi
Precedentemente, abbiamo visto la seguente tabella di iscrizione ai corsi:
Student ID | Course ID | Course Name | Instructor Name |
---|---|---|---|
1001 | 201 | Fondamenti di SQL | Ken Smith |
1002 | 202 | Introduzione a Python | Merlin O’Donnell |
1001 | 202 | Introduzione a Python | Merlin O’Donnell |
Seguiamo i passaggi che abbiamo delineato nella sezione precedente.
1. Identifica la nostra chiave candidata.
In questo caso, la chiave candidata è una chiave composta di ID Studente e ID Corso. Questa combinazione unica identifica ogni riga nella tabella.
2. Determinare le nostre dipendenze funzionali
Nome del Corso e Nome dell’Istruttore dipendono da ID del Corso, non dall’intera chiave composta (ID Studente, ID Corso). Si tratta di una dipendenza parziale perché questi attributi dipendono solo da parte della chiave composta.
3. Eliminare le dipendenze parziali
Abbiamo bisogno di spostare gli attributi che dipendono solo da una parte della chiave (Nome del Corso e Nome dell’Istruttore) in una nuova tabella che si basa esclusivamente su ID del Corso.
Dopo la decomposizione, le nostre nuove tabelle appaiono così:
Tabella di iscrizione al corso
Student ID | Course ID |
---|---|
1001 | 201 |
1002 | 202 |
1001 | 202 |
Tabella dei dettagli del corso
Course ID | Course Name | Instructor Name |
---|---|---|
201 | Fondamenti di SQL | Ken Smith |
202 | Introduzione a Python | Merlin O’Donnell |
Se vuoi mettere in pratica creando i tuoi database, dai un’occhiata al nostro corso su PostgresQL. Se sei un po’ più avanzato, potresti provare questa Introduzione alla modellazione dei dati in Snowflake, che copre concetti come la modellazione entità-relazione e dimensionale.
Esempio 2: Tabella degli ordini
Inizieremo con questa tabella degli Ordini. Cerca di seguire i passaggi che abbiamo delineato sopra e decomponi questa tabella da solo!
Order ID | Product ID | Order Date | Product Name | Supplier Name |
---|---|---|---|---|
1 | 201 | 2024-11-01 | Portatile | TechSupply |
1 | 202 | 2024-11-01 | Mouse | TechSupply |
2 | 201 | 2024-11-02 | Portatile | TechSupply |
3 | 203 | 2024-11-03 | Tastiera | KeyMasters |
1. Identifica la nostra chiave candidata
L’ID Ordine e ID Prodotto in combinazione identifica in modo univoco ciascuna riga, rendendo (ID Ordine, ID Prodotto) una chiave candidata composita. Nessuna singola colonna può identificare in modo univoco le righe perché:
- ID ordine da solo non è univoco, in quanto diversi prodotti possono far parte dello stesso ordine.
- ID prodotto da solo non è univoco, in quanto lo stesso prodotto può comparire in ordini diversi.
Questo significa che (ID Ordine, ID Prodotto) è anche la nostra chiave primaria.
2. Determinare le nostre dipendenze funzionali
Data dell’ordine dipende da ID dell’ordine (non dalla chiave composita completa). Questa è una dipendenza parziale.
Nome Prodotto e Nome Fornitore dipendono da ID Prodotto (non sull’intera chiave composita). Queste sono anche dipendenze parziali.
3. Eliminare le dipendenze parziali
Dobbiamo dividere la tabella in tabelle più piccole, ognuna affrontando una dipendenza logica.
Innanzitutto, creeremo una tabella per le informazioni sugli ordini, che contiene informazioni specifiche per ID Ordine.
Tabella Ordini
Order ID | Order Date |
---|---|
1 | 2024-11-01 |
2 | 2024-11-02 |
3 | 2024-11-03 |
Successivamente, creiamo una tabella che contiene informazioni specifiche per ID Prodotto.
Tabella degli ordini
Product ID | Product Name | Supplier Name |
---|---|---|
201 | Laptop | TechSupply |
202 | Mouse | TechSupply |
203 | Tastiera | KeyMasters |
La tabella originale è ora ridotta solo alla chiave composta e alle relazioni tra ordini e prodotti.
Order ID | Product ID |
---|---|
1 | 201 |
1 | 202 |
2 | 201 |
3 | 203 |
Adesso, il nostro database è in 2NF perché 1) sono state eliminate tutte le dipendenze parziali, e 2) gli attributi non primi dipendono interamente dalle rispettive chiavi primarie.
Quando implementare la Seconda Forma Normale
Quindi, perché dovresti rifattorizzare il tuo database in 2NF? È sufficiente da solo o dovresti fare un ulteriore passo e puntare alla 3NF?
Benefici e limitazioni della seconda forma normale
La seconda forma normale offre diversi vantaggi, rendendola un passo utile nel processo di normalizzazione del database:
- Maggiore integrità dei dati: Eliminando le dipendenze parziali, la 2NF minimizza le anomalie di inserimento, aggiornamento e cancellazione, portando a un database più affidabile.
- Riduzione della ridondanza: La 2NF riduce la ripetizione dei dati, ottimizzando l’uso dello spazio di archiviazione e semplificando la manutenzione dei dati.
- Struttura dati migliorata: Posa le basi per ulteriore normalizzazione, come il passaggio alla terza forma normale, creando un design del database più pulito ed efficiente.
Ma presenta alcune limitazioni:
- Complessità aumentata: Decomporre le tabelle per soddisfare la 2NF può rendere il processo di progettazione più complesso, soprattutto quando si tratta di chiavi composite e dipendenze.
- Unioni aggiuntive: La suddivisione delle tabelle può richiedere più unioni nelle query, potenzialmente influenzando le prestazioni in sistemi con grandi dataset o query complesse – maggiori dettagli di seguito.
- Redundanza residua: Sebbene la 2NF riduca le dipendenze parziali, non affronta le dipendenze transitive, lasciando una certa ridondanza fino a quando non viene affrontata nella 3NF.
Considerazioni sulle prestazioni con la seconda forma normale
Decomporre le tabelle per eliminare le dipendenze parziali può influire direttamente sulle prestazioni del database. Da un lato, raggiungere la 2NF riduce la ridondanza dei dati e migliora la coerenza, portando a meno anomalie durante le operazioni di inserimento, aggiornamento o eliminazione. D’altro canto, la normalizzazione può aumentare il numero di tabelle, il che significa che sono necessari ulteriori join per recuperare dati correlati. Questo potrebbe influire sulle prestazioni delle query in grandi set di dati.
Per assicurarti che il tuo database normalizzato rimanga performante, assicurati di seguire queste best practice:
- Indicizzazione: Utilizza gli indici per velocizzare i join tra le tabelle decomposte.
- Ottimizzazione delle query: Ottimizza le query per minimizzare il costo di join aggiuntivi.
- Approccio ibrido: Combina la normalizzazione con la denormalizzazione nelle aree dove le prestazioni sono importanti, come le tabelle di reporting.
- Monitoraggio regolare: Valuta continuamente le prestazioni del tuo database con strumenti di profiling per rilevare eventuali problemi potenziali.
È la 2NF solo un passo intermedio per raggiungere la terza forma normale?
Nella maggior parte dei casi, i progettisti di database si sforzano di raggiungere la terza forma normale per la sua capacità di ridurre ulteriormente la ridondanza e migliorare l’integrità complessiva dei dati. Tuttavia, raggiungere la 3NF spesso comporta lavoro aggiuntivo, come la creazione di più tabelle e relazioni, che possono introdurre complessità e compromessi sulle prestazioni nell’esecuzione delle query.
Ci sono casi in cui l’utilizzo della seconda forma normale da sola può essere sufficiente. Se la semplicità e l’implementazione rapida sono priorità, come nei progetti su piccola scala, nel prototipaggio o in situazioni in cui la ridondanza dei dati è minima, la 2NF può essere sufficiente. Ad esempio, in sistemi in cui tutti gli attributi dipendono già completamente da una chiave primaria semplice, raggiungere la 2NF potrebbe soddisfare l’obiettivo principale di ridurre la dipendenza parziale, senza la necessità di ulteriori normalizzazioni.
Andando oltre la seconda forma normale: verso la terza forma normale
Se desideri normalizzare ulteriormente il tuo database, puoi continuare a rifattorizzare le tue tabelle per raggiungere la terza forma normale.
La 3NF si basa sulla 2NF affrontando le dipendenze transitive – situazioni in cui gli attributi non chiave dipendono da altri attributi non chiave anziché dalla chiave primaria. Questa progressione garantisce che ciascun attributo dipenda direttamente dalla chiave primaria e da nient’altro.
Ad esempio, in una tabella che tiene traccia delle iscrizioni ai corsi:
- 2NF: Garantisce che attributi come il nome del corso e il nome dello studente dipendano interamente dai rispettivi chiavi primarie (ad esempio, ID studente e ID corso). Ciò elimina le dipendenze parziali, in cui gli attributi non chiave dipendono solo da parte della chiave composta.
- 3NF: Garantisce che attributi come i dettagli dell’istruttore o le informazioni sul dipartimento siano memorizzati in tabelle separate, eliminando le dipendenze transitive.
La 3NF è ideale per sistemi più complessi dove l’integrità dei dati e l’efficienza sono fondamentali, soprattutto man mano che il volume dei dati cresce. Dai un’occhiata al nostro Cosa è la terza forma normale? articolo se vuoi saperne di più sulla 3NF e sulla sua forma più restrittiva, la BCNF.
Conclusione
La seconda forma normale è un passo essenziale nella normalizzazione dei database, colmando il divario tra la 1NF e forme superiori come la 3NF. Rimuovendo le dipendenze parziali, la 2NF riduce la ridondanza e migliora l’affidabilità dei tuoi dati. Anche se può aggiungere un po’ di complessità, i vantaggi di un’integrità dei dati migliorata e una manutenzione semplificata la rendono una parte fondamentale di un design efficace del database.
Se sei pronto a portare ulteriormente le tue abilità, esplora il nostro corso Progettazione di Database per approfondire la tua comprensione delle tecniche di normalizzazione e delle loro applicazioni pratiche. Puoi anche convalidare le tue competenze in SQL e gestione dei database e dimostrare la tua esperienza ai potenziali datori di lavoro con la nostra Certificazione Associata SQL!
Infine, voglio dire, se sei un decision maker in un’azienda e sai di avere lavoro da fare per creare database più puliti e efficienti, considera di inviare una richiesta per una demo di DataCamp per le Aziende. Possiamo aiutare a trasformare le capacità del tuo team in modo da poter creare sistemi di database scalabili che promuovono efficienza e innovazione aziendale. Possiamo anche creare percorsi di apprendimento personalizzati e tracciati su misura.
Source:
https://www.datacamp.com/tutorial/second-normal-form