Vincoli in un database relazionale - Perché non rimuoverli completamente?

20

C'è qualche motivo per creare vincoli tra le tabelle (all'interno di SQLserver) al giorno d'oggi? Se sì, quando? La maggior parte delle applicazioni nella mia area sono basate su principi di oggetti e le tabelle vengono unite su richiesta. La domanda si basa sulla necessità dell'applicazione. Non caricherò un mucchio di tabelle vincolate per una semplice ricerca, che a sua volta (dopo l'azione) richiedono l'un l'altro una semplice ricerca.

Gli strumenti ORM come EntityContext, Linq2Data, NHibernate gestiscono da soli i vincoli, almeno sai quali tabelle hanno bisogno l'una dell'altra. Fare dei vincoli all'interno del server equivale a fare (forzare) le stesse modifiche due volte?

Di solito non è una domanda da prendere per decisione, ma questo database è stato progettato in modo abbastanza diverso. Il design sembra regolare, per lo più rispecchiava gli oggetti utilizzati dalle applicazioni. Ciò che mi disturba sono tutti i vincoli configurati all'interno di SQLserver con "not cascade". Il che significa che devi giocare "cerca e trova" quando codi nuove query del database. Alcuni casi richiedono fino a 10 livelli di un ordine esatto per effettuare una singola eliminazione.

Questo mi sorprende e non sono sicuro di come gestirlo.

Nel mio mondo semplice, questa impostazione rende i vincoli perdere la maggior parte dello scopo. OK se il database è stato acceduto da host senza conoscenza del design.

Come agiresti in questo scenario?
Perché non rimuovere solo tutti i vincoli da db e tenerli a livello di applicazione?

    
posta Independent 13.05.2011 - 09:42
fonte

9 risposte

46

Due motivi generali per non rimuovere i contrainti dal DB :

  • È possibile accedere a più app, ora o in futuro , che possono utilizzare o meno ORM. Anche se gli sviluppatori di quelle applicazioni duplicano fedelmente tutti i vincoli presenti (che possono essere significativamente più difficili utilizzando soluzioni non ORM di livello inferiore), è sempre un lavoro extra. E se no, anche una piccola omissione è sufficiente per rompere l'integrità dello schema ... che è qualcosa che non vuoi rischiare. Nella maggior parte delle aziende, i dati memorizzati nel loro DB sono la linfa vitale della loro attività, quindi la sua integrità deve essere garantita con ogni mezzo. E il mezzo migliore provato e dimostrato per raggiungere questo obiettivo è quello di implementare il maggior numero possibile di limiti nel DB.
  • Query Optimizer si basa molto sui vincoli noti a livello di DB. Se rimuovi i vincoli, le prestazioni delle query potrebbero iniziare a peggiorare . Potresti non notarlo immediatamente, ma un giorno ti colpirà, e a quel punto potrebbe essere troppo tardi per sistemarlo facilmente. La natura delle cose è che le prestazioni del DB tendono ad abbattere al momento del carico di punta, quando c'è la minima possibilità di fare miglioramenti attenti e ben progettati, supportati da misure esatte delle prestazioni e analisi dettagliate per individuare le cause alla radice.

Il tuo caso concreto suona come lo schema DB potrebbe essere stato originariamente generato da uno strumento ORM (o progettato da qualcuno non molto esperto con il mondo relazionale), quindi non è ottimale dal punto di vista relazionale. Probabilmente è meglio analizzarlo e migliorarlo verso un design relazionale più "naturale", mantenendolo coerente con le viste ORM. Potrebbe essere utile coinvolgere un esperto di DB in questa analisi.

    
risposta data 13.05.2011 - 09:51
fonte
27

Le applicazioni possono andare e venire ma i dati rimangono per sempre. Nella mia azienda il DB ha più di 30-40 anni, vivrà fino a quando la compagnia esiste. Le applicazioni cambiano, gli sviluppatori vanno e vengono. È meglio avere integrità e un buon modello di dati logici. In questo modo, chiunque può esaminare i dati e ottenere una comprensione significativa senza dover passare attraverso una base di codice complessa. Questo aiuta anche a riportare in modo significativo. Anche le applicazioni possono avere e avranno bug e il vincolo del DB è una guardia contro questo. La mia posizione di default è di avere il massimo vincolo (FK e controllo) possibile.
L'unica ragione per non avere un vincolo sarebbe se il tuo modello di progettazione non lo consente, ad es. Tabella per gerarchia o problemi di rendimento.

    
risposta data 13.05.2011 - 10:12
fonte
15

What disturbing me is all constraints configured inside SQLserver with "not cascade".

Questo non mi disturba, questo significa che qualcuno ha dimostrato buonsenso. Le eliminazioni a cascata sono spesso molto dannose per il database. In primo luogo, a volte vuoi che un'eliminazione fallisca se hai dati in tabelle correlate. Ad esempio, se hai un cliente che ha un ordine in passato, non vuoi che venga cancellato o perdi i dati su chi era l'ordine e un eliminatore a cascata elimina il record che potrebbe compromettere i tuoi report finanziari .

Sembra che tu pensi che la facilità di sviluppo sia la cosa più importante. Nel mondo dei database questo non è semplicemente vero. L'integrità dei dati è la prima cosa più importante seguita da vicino dalle prestazioni e dalla sicurezza dei dati. Se ci vuole più tempo per scrivere le domande, così sia.

Il database viene generalmente utilizzato da molte applicazioni = uno o più siti Web o applicazioni desktop, un'applicazione di reporting, servizi Web, la finestra di query, i processi ETL, ecc. Se non si applicano i contrappunti a livello di database, si perdere l'integrità dei dati in quanto una di queste applicazioni potrebbe non seguire tutte le regole. In secondo luogo, è necessario codificare più volte tali conflitti e riscriverli se si decide di utilizzare un'applicazione diversa in un secondo momento. In terzo luogo, non è possibile controllare in anticipo se sarà necessario eseguire una sorta di attività di manutenzione dei dati che non si verificherà attraverso l'applicazione (correzione dei dati da un'importazione errata dei dati del cliente, ad esempio o modifica di tutti i 10.000.000 di record da un client ad un altro cliente quando l'azienda viene acquistata da un concorrente). Generalmente gli sviluppatori di applicazioni non pensano a come i dati potrebbero dover essere manipolati nel tempo e quindi dimenticano di aggiungere vincoli importanti a livello di database che è il primo, il più importante luogo a cui appartengono.

    
risposta data 13.05.2011 - 16:51
fonte
10

Ho letto da qualche parte una volta che diceva sostanzialmente: I dati sono la chiave della tua applicazione . Se solo accederai MAI ai dati attraverso l'interfaccia utente (e intendo mai , come ora e per sempre, per l'eternità ... o la durata della tua applicazione, comunque) non hai bisogno vincoli di database. Ma c'è sempre la possibilità che qualcosa di diverso dall'app stessa debba toccare i dati, ad esempio un servizio Web, un'API pubblica, un'attività di rake / un processo SQL / cron / script automatico, quindi ti risparmierai un sacco di potenziali problemi nel strada mantenendo i vincoli del DB.

Credo fermamente che questa sia l'unica area dello sviluppo del software in cui dovresti not applicare DRY (e mi sto aspettando completamente una serie di downvotes per quella dichiarazione). I tuoi dati sono il cuore e l'anima della tua applicazione - se è mai corrotta in modo irreparabile, che: game over. Ne vale la pena IMO per far rispettare i vincoli ovunque siano necessari. Se ciò significa sotto forma di trigger e vincoli a livello di DB, convalide lato server sul middleware e Javascript lato client sull'interfaccia utente (per applicazioni Web), allora è IMO un male necessario per garantire che i dati siano sempre incontaminati .

    
risposta data 13.05.2011 - 14:32
fonte
6

Sai cosa significa ORM? Mappatura relazionale oggettuale. Citando la tecnica di Wikipedia "per convertire i dati tra incompatibili sistemi di tipi". Sì, i modelli relazionali e oggettivi non si adattano insieme. Gli ORM fanno una conversione piuttosto buona, rispettando le regole di entrambi i sistemi di tipi. Gli RDBMS sono organizzati in modo tale da ottenere l'integrità dei dati utilizzando i vincoli. In generale, l'integrità è una cosa molto bella da avere, quindi gli ORM tendono a usarli quando creano il modello di dati per la memorizzazione dei dati dell'oggetto. Probabilmente il tuo ORM ha una buona ragione per usare i vincoli "non a cascata". E se questo ti costringe a fare query complicate invece di creare / aggiornare / rilasciare determinati oggetti, allora qualcosa non va nella tua configurazione di ORM.

Se consideri il concetto relazionale fastidioso, allora perché non usi il database degli oggetti? Qualche tempo fa erano lenti (motivo per cui la maggior parte delle persone usa ancora RDBMS) ma da quello che ho sentito le cose sono cambiate un po '. Ti libereresti di tutti i nitpicks relazionali. Semplicemente oggetti dentro, oggetti fuori.

    
risposta data 13.05.2011 - 10:42
fonte
6

Bene, questo è ciò che eBay ha fatto e probabilmente hanno uno dei più grandi database al mondo:

link link

Nonostante ciò che è stato detto sopra in merito all'aumento delle prestazioni da parte dell'integrità referenziale, può essere effettivamente degradato; ecco perché i massicci database hanno abbandonato i loro vincoli e hanno svolto il lavoro nel livello dell'applicazione. E per quanto posso dire è l'unica vera ragione.

Rilasciando questi vincoli si perde la rete di sicurezza che mantiene i dati puliti e questo causa i suoi problemi. Quindi come con tutto è un atto di bilanciamento. Immagino che in generale mantenere l'integrità referenziale sia la cosa giusta da fare.

Avendo lavorato in un ambiente di sviluppo con una strong integrità referenziale, so che dal punto di vista di uno sviluppatore può essere un dolore totale; spesso in un ambiente di sviluppo un po 'di dati sporchi non ha importanza e capire come eliminare una riga potrebbe richiedere un'ora o più. Tuttavia, può anche essere molto utile, poiché i vincoli rendono esplicito lo schema.

    
risposta data 13.05.2011 - 14:46
fonte
4

Prima - la mia risposta: No, non dovresti affidarti solo all'applicazione per occuparti dei tuoi dati.

Ciò indica un dibattito più ampio: gli ORM hanno incoraggiato una cultura di disprezzo per l'interazione DB "diretta", spesso a scapito della normalizzazione / integrità referenziale. Le tabelle sono mappate forzatamente a gerarchie arbitrarie di oggetti, a spese del design implicito nel modello relazionale. Il disaccoppiamento favorito da OOP è probabilmente sacrificato qui in quanto l'applicazione fa sentire il suo design nella struttura dei dati. Mentre ORM ha dimostrato una grande utilità, sembra essere basato sull'abuso o la sfiducia di SQL.

Nuovi paradigmi stanno ri-emergendo, prendiamo ad esempio la programmazione funzionale. Se il team di sviluppo decide di adottare una nuova metodologia di programmazione, quali conseguenze avrà per i dati che sono stati strutturati in base ai requisiti dell'ORM?

Sono d'accordo con @Jacek Prucia - Penso che l'ORM sia una brutta corrispondenza per RDBMS, personalmente opterei per un DBAL su RDBMS, o opterei per un OODB con ORM.

    
risposta data 13.05.2011 - 15:47
fonte
3

I vincoli sono la tua unica garanzia di coerenza e integrità dei dati a livello di database. Certo, puoi imporre vincoli usando il tuo codice applicativo, ma cosa succede se, in futuro, hai bisogno di modificare i dati direttamente? Potresti capire come mantenere l'integrità dei dati, ma qualcun altro potrebbe non farlo. Mantenere i vincoli a livello di dati assicura che l'integrità sia assicurata anche quando qualcuno sta facendo una monkeking in luoghi che non capiscono.

Inoltre, supponiamo che la tua applicazione debba essere riscritta, ma con lo stesso database sul posto. Tutti questi vincoli nel codice stanno solo chiedendo bug che impediscano l'accesso a dati errati.

Durante lo sviluppo, mantienilo semplice. I vincoli ti permettono di farlo. (Ciò detto, quando un vincolo genera un errore, non sputare lo stesso errore all'utente. Rendi comprensibile l'errore.)

(Per quanto riguarda il problema a cascata: questa è una buona cosa, preferirei lanciare un errore che certi altri record debbano essere eliminati prima, piuttosto che fare affidamento sulla cascata per ottenere tutto correttamente. Le cascate sono belle in teoria, ma non necessariamente così in pratica.)

    
risposta data 13.05.2011 - 17:43
fonte
2

Un problema con i vincoli in un database è che forniscono al programma informazioni limitate su cosa non è riuscito e su come risolverlo. Ciò significa che, per una gestione omogenea, è spesso necessario ripetere il controllo dei vincoli nell'applicazione e quindi il controllo dei vincoli del database è uno sforzo inutile.

Questo comporta il rischio di compromettere l'integrità dei dati, quindi abbiamo qui i compromessi. Per dati importanti, garantire l'integrità dei dati è quasi sempre più importante delle prestazioni, ed è molto meglio fallire una transazione anche se sembra arbitraria piuttosto che rovinare i dati.

Per rimuovere in modo sicuro i vincoli, è quindi fondamentale proteggere l'accesso al database in modo che nulla possa modificare il database senza controllare i vincoli. Questo non è affidabile quando si scrivono nuove applicazioni o si creano modi ad hoc di trattare i dati, poiché tutto ciò che serve è un errore e il database è corrotto.

Pertanto, per fare a meno dei vincoli del database, è necessario stabilire cosa può e cosa non può essere fatto con il database in primo piano, in modo che tutte le applicazioni possano essere scritte, revisionate e testate estesamente. Tutti i requisiti del database devono essere stabiliti in anticipo e qualsiasi modifica ai requisiti del database richiederà un lungo lavoro. Questo è qualcosa di una metodologia cascata congelata, che funziona solo in casi molto specifici. (Progettare, implementare e mantenere i requisiti è come camminare sull'acqua: qualcosa deve essere congelato per primo, e se non è congelato abbastanza i risultati possono essere disastrosi.)

Un caso in cui funziona sono le massicce applicazioni aziendali come PeopleSoft e SAP, dove l'applicazione fa già praticamente tutto, e ci sono modi accuratamente definiti per estenderlo. Ci sono altre possibilità, molto rare.

Quindi, a meno che tu non lavori su un progetto aziendale molto grande (e non vorrei farlo) o non possa camminare sull'acqua liquida, lascia quei vincoli nel database.

    
risposta data 13.05.2011 - 17:18
fonte

Leggi altre domande sui tag