Quando rivedo i modelli di database per RDBMS, di solito sono sorpreso di trovare poco o nessun vincolo (a parte PK / FK). Ad esempio, la percentuale viene spesso memorizzata in una colonna di tipo int
(mentre tinyint
sarebbe più appropriato) e non vi è alcun vincolo CHECK
per limitare il valore all'intervallo 0..100. Analogamente su SE.SE, le risposte che suggeriscono i limiti di controllo spesso ricevono commenti che suggeriscono che il database è il posto sbagliato per i vincoli.
Quando chiedo la decisione di non implementare i vincoli, i membri del team rispondono:
-
O non sanno nemmeno che tali funzionalità esistono nel loro database preferito. È comprensibile dai programmatori che utilizzano solo gli ORM, ma molto meno dai DBA che dichiarano di avere più di 5 anni di esperienza con un determinato RDBMS.
-
O che applicano tali vincoli a livello di applicazione e la duplicazione di quelle regole nel database non è una buona idea, violando SSOT.
Più di recente, vedo sempre più progetti in cui non vengono utilizzate nemmeno le chiavi esterne. Allo stesso modo, ho visto alcuni commenti qui su SE.SE che mostra che agli utenti non interessa molto l'integrità referenziale, lasciando che sia l'applicazione a gestirlo.
Quando chiedi ai team la scelta di non usare FK, dicono che:
-
È PITA, ad esempio quando si deve rimuovere un elemento a cui si fa riferimento in altre tabelle.
-
NoSQL oscilla e non ci sono chiavi esterne lì. Pertanto, non sono necessari in RDBMS.
-
Non è un grosso problema in termini di prestazioni (il contesto è di solito piccole applicazioni web intranet che lavorano su piccoli set di dati, quindi in effetti anche gli indici non contano troppo: a nessuno interesserebbe una performance di un data la query passa da 1,5 s a 20 ms.)
Quando guardo l'applicazione stessa, noto sistematicamente due pattern:
-
L'applicazione disinfetta correttamente i dati e li controlla prima di inviarli al database. Ad esempio, non c'è modo di memorizzare un valore
102
come percentuale attraverso l'applicazione. -
L'applicazione presuppone che tutti i dati provenienti dal database siano perfettamente validi. Cioè, se
102
è in percentuale, o qualcosa, da qualche parte andrà in crash, o verrà semplicemente visualizzato come è per l'utente, portando a situazioni strane. -
Mentre oltre il 99% delle query viene eseguito da una singola applicazione, nel tempo, gli script iniziano a comparire, ovvero gli script eseguiti a mano quando necessario o i lavori cron. Alcune operazioni sui dati vengono anche eseguite manualmente sul database stesso. Entrambi gli script e le query SQL manuali presentano un rischio elevato di introduzione di valori non validi.
E qui arriva la mia domanda:
Quali sono i motivi per modellare i database relazionali senza controllare i vincoli e alla fine anche senza chiavi esterne?
Per quello che vale, questa domanda e le risposte che ho ricevuto (specialmente l'interessante discussione con Thomas Kilian) mi hanno portato a scrivere un articolo con le mie conclusioni sull'argomento dei vincoli del database .