Concetto di Chiave Primaria
Scrivo un breve articolo per utenti non esperti per chiarire il concetto di chiave primaria.
Una relazione, prendiamo ad esempio 1:n, si realizza quando la chiave primaria della tabella1 è riportata come chiave esterna nella tabella2.
Per ogni unica chiave primaria possono corrispondere infiniti riferimenti ad essa nella tabella2, come chiave esterna.
Approfondiamo quindi il concetto di chiave primaria:
Lo scopo di una chiave primaria è quello di individuare con la massima rapidità possibile un dato record all’interno di una tabella in modo univoco.
Ad esempio per trovare il record numero 484892 all’interno di una tabella da milioni di record.
Tale operazione avviene di fatto ogni volta che bisogna andare a recuperare i dati presenti in un’altra tabella, attività che su un database relazionale viene utilizzata molto frequentemente.
Una chiave primaria sulla maggior parte dei DBMS puà essere impostata come numerico, numerico auto incrementale, testuale, su più campi di vari formati etc…
Il fatto importante è che la chiave primaria di una tabella rispetti le seguenti affermazioni:
La chiave primaria DEVE essere univoca all’interno della tabella, infatti non è possibile che due record abbiano la stessa chiave primaria.
La chiave primaria deve avere come requisito (non obbligatorio ma di buon senso) la compattezza:
1.Essendo fondamentale per mantenere un indice primario, con lo scopo di velocizzare la ricerca.
Maggiore è la compattezza del campo che descrive la chiave primaria della tabella e più efficace sarà la gestione di questo indice.
Se ne evince chiaramente che una chiave primaria intera (numerica) è tendenzialmente meglio ottimizzata rispetto ad un campo stringa a lunghezza variabile.
2.Essendo il contenuto della chiave primaria utilizzato in qualità di chiave esterna in altre tabelle è chiaro che se la chiave primaria non è compatta cià comporta uno spreco di spazio occupato dal database.
La chiave primaria nei principali DBMS viene utilizzata di solito come dato numerico e con la proprietà di essere automaticamente incrementato dal database all’inserimento di ogni nuovo record.
In questo modo lo sviluppatore e l’utente non devono preoccuparsi di gestire la chiave primaria e quindi di dover preoccuparsi che essa non sia già presente.
Rischio di duplicati
Un facile esempio in cui una chiave primaria numerica autoincrementale puà comportare la creazione di duplicati è data per esempio dall’anagrafica di una società .
Infatti se l’amministrazione non è attenta a verificare che una data azienda è già presente a database il rischio è di ritrovarsi 8 Telecom, 5 Enel etc…
Questa situazione è molto pericolosa sia perchè comporta uno spreco di dati e ridondanza di informazioni e sia perchè rende poco consistenti e validi i dati nel caso ad esempio di reportistiche e statistiche, questo perchè la stessa società verrebbe (giustamente) trattata dal database come differenti aziende.
Saluti, Maxgrante
info[AT]massimo-caselli[DOT]com
premessa :sono un semplice studente di ing. inf. con scarsa esperienza sul campo (semplici db amministrativi o db di supporto a siti dinamici con max 1000 record e sviluppati con mysql)
lo scopo dell PK nn sarebbe quello di identificare (tramite 1 o + attributi) un dato garantendo univocità e minimalità piuttosto ke velocità ???
x la rapidità nn si ricorre agli indici????
IMHO una PK int autoincrement sembrerebbe poco “relazionale” in un db di anagrafica clienti in cui utilizzerei CF o PIVA ????
sbaglio???
Negli applicativi sul campo fatti da professionisti del settore si utilizzano + pk numerike o composte da attribbuti ???
saluti e complimenti per il blog ke riporta sempre spunti interessanti
Ciao Gigiozzz,
grazie prima di tutto per i complimenti.
Cercherà di risponderti a tutto di seguito:
Riguardo allo scopo dell’univocità certo, non posso che confermarti.
In ogni caso la chiave primaria stessa è di fatto un indice che tende a velocizzare notevolmente le query sul campo/i che la rappresenta.
Da questo se ne evince che quindi anche la velocizzazione è un suo scopo, infatti gli indici si utilizzano su campi non facenti parte della chiave primaria.
Sinceramente per quanto riguarda la chiave primaria in un DB di anagrafica clienti eviterei di usare CF o PI come chiave primaria per il fatto che sono molto “abbondanti” come formato di campi, preferirei perà fare un indice univoco su CF e/o PI in modo da evitare proprio i duplicati.
Negli applicativi web, ma in generale direi anche per gli altri la tendenza è quella di usare PK numeriche e al massimo verificare univocità di certi campi con indici UNIQUE.
Almeno questa è la mia opinione…
Un saluto e grazie del post,
Ciao. Max
Ciao Gigiozzz,
ho aggiunto alla frase che esprimo sul concetto di chiave primaria che deve anche garantire univocità del record nella tabella.
Ciao. Max
Come si imposta una chiave esterna?
Ciao Claudio,
una chiave esterna su mysql ad esempio si può gestire solo con tabelle di tipo InnoDB se vuoi garantirti la gestione da parte del DB di integrità referenziale.
Altrimenti è gestita come una chiave esterna e con i controlli del caso lato applicativo.
Per info riguardo le foreign key su mysql ti rimando a questo link:
http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
Ciao. Max
Ciao,
aggiungo solo una nota all’esempio dei clienti. Dalla mia esperienza su sistemi gestionali professionali (es. IBM), ritengo che sia opportuno valutare il tipo di chiave in base alla tabella a cui ci si riferisce e al grado di leggibilità che si vuole ottenere.
Ad esempio, è molto utile identificare un cliente tramite un ‘codice_cliente’ numerico (es. 000152 nel caso piaccia il padding) e usare questo dappertutto, controllando via software che non si stia inserendo un cliente già esistente (facendo attenzione anche a eliminare i punti, in modo da non farsi ingannare da srl/s.r.l./S.r.L./srl./ecc…).
In altri casi trovo invece più utile avere una chiave alfanumerica ‘parlante’; ad esempio, per la tabella delle divise monetarie si potrebbe utilizzare il codice ISO: EUR, USD…; o, per le nazioni: IT, NL, UK, US, ecc.
In questo modo, leggendo dal db un record di riga d’ordine (es. per debug), vedrò “quantita=100, unita_misura=’KG’, prezzo=10, divisa=’EUR’” e non “quantita=100, unita_misura=5, prezzo=10, divisa=1″, dovendo poi andare a vedere a cosa corrispondono quegli id…
Ancora, per le righe di un ordine, adotterei una chiave primaria composta da ‘id_ordine’ e da ‘riga_ordine’ piuttosto che un id univoco…
Spero di essermi spiegato
Dato