La vista nidificata è una buona progettazione di database?


42

Ho letto da qualche parte molto tempo fa. Il libro afferma che non dovremmo consentire di avere una vista nidificata in SQL Server. Non sono sicuro del motivo per cui non possiamo farlo o potrei ricordare un'affermazione errata.

Studenti

SELECT studentID, first_name, last_name, SchoolID, ... FROM students

CREATE VIEW vw_eligible_student
AS 
SELECT * FROM students
WHERE enroll_this_year = 1

Insegnanti

SELECT TeacherID, first_name, last_name, SchoolID, ... FROM teachers

CREATE VIEW vw_eligible_teacher
AS 
SELECT * FROM teachers
WHERE HasCert = 1 AND enroll_this_year = 1

scuole

CREATE VIEW vw_eligible_school
AS 
SELECT TOP 100 PERCENT SchoolID, school_name 

FROM schools sh 
JOIN
     vw_eligible_student s 
     ON s.SchoolID = sh.SchoolID
JOIN 
     vw_eligible_teacher t
     ON s.SchoolID = t.SchoolID

Nel mio posto di lavoro, ho studiato una delle nostre applicazioni di database interne. Ho controllato gli oggetti e ho scoperto che ci sono due o tre strati della pila di vedute. Questo mi ha ricordato ciò che ho letto in passato. Qualcuno può aiutare a spiegarlo?

Se non è OK per farlo, voglio sapere che è limitato a solo SQL Server o è per la progettazione di database in generale.

Informazioni aggiuntive: ho aggiornato un esempio dalla mia azienda. Cambio un po 'per essere più generale senza troppi aspetti tecnici (troppe colonne in questo esempio). Principalmente la vista nidificata che abbiamo usato si basa sulla vista astratta o aggregata. Ad esempio, abbiamo una grande tabella degli studenti con centinaia di colonne. Diciamo, Eligible Student Viewsi basa sugli studenti che si iscrivono quest'anno. E la vista idonea per gli studenti potrebbe essere quella di utilizzare altri luoghi come nella procedura memorizzata.


3
Direi che gli stessi pro e contro si equivalgono approssimativamente a prescindere dalla piattaforma specifica.
Aaron Bertrand

Risposte:


47

Indipendentemente dalla piattaforma, si applicano le seguenti osservazioni.

(-) Visualizzazioni nidificate:

  • sono più difficili da capire ed eseguire il debug

    ad es. a quale colonna della tabella fa riferimento questa colonna della vista? Scorri attraverso 4 livelli di definizioni di vista ...

  • rendere più difficile per Query Optimizer elaborare il piano di query più efficiente

    Vedi questo , questo , questo e questo per prove aneddotiche. Confronta con questo , il che dimostra che l'ottimizzatore è spesso abbastanza intelligente da decomprimere correttamente le viste nidificate e selezionare un piano ottimale, ma non senza un costo di compilazione.

    È possibile misurare il costo delle prestazioni confrontando la query di visualizzazione con una query equivalente scritta con le tabelle di base.

(+) D'altra parte, le visualizzazioni nidificate consentono di:

  • centralizzare e riutilizzare aggregazioni o regole aziendali
  • allontana la tua struttura sottostante (diciamo, da altri sviluppatori di database)

Ho scoperto che raramente sono necessari.


Nel tuo esempio stai utilizzando le visualizzazioni nidificate per centralizzare e riutilizzare alcune definizioni di attività (ad esempio "Che cos'è uno studente idoneo?"). Questo è un uso valido per le viste nidificate. Se stai gestendo o ottimizzando questo database, sopporta il costo di mantenerlo rispetto a quello di rimuoverlo.

  • Mantieni: mantenendo le visualizzazioni nidificate si incorre nei vantaggi e negli svantaggi elencati sopra.

  • Rimuovi: per rimuovere le visualizzazioni nidificate:

    1. È necessario sostituire tutte le occorrenze delle viste con le loro query di base.

    2. È necessario ricordare di aggiornare tutte le domande pertinenti se la definizione di studente / insegnante / scuola ammissibile cambia, anziché aggiornare semplicemente la definizione di vista pertinente.


1
+1, tranne che sostituirei "più difficile" per Query Optimizer, con "quasi impossibile". :)
Jason

1
@Jason - Sono d'accordo e vorrei poter collegare ad alcuni esempi concreti. Sei a conoscenza di riferimenti che spiegano o dimostrano perché è così?
Nick Chammas,

1
Tutto quello che riesco a trovare è l'evidenza aneddotica che quando vengono utilizzate le viste nidificate, esse presentano problemi di prestazioni rispetto all'SQL "appiattito". sqlservercentral.com/blogs/2cents/archive/2010/04/05/… Il problema sembra dipendere dal fatto che il DB (in questo caso SQL Server) non applicherà alcuni filtri prima di unire le tabelle e pertanto rendere la query impiega più tempo di quanto dovrebbe.
Jason,

7
Non sono d'accordo sul problema di Query Optimizer, poiché la query risultante dopo aver risolto tutte le viste sarà la stessa, indipendentemente da quante trasformazioni di vista ha attraversato (tranne alcune colonne extra nei set di risultati intermedi, che l'ottimizzatore può eliminare bene). Questo lascia il debug; IMO semplifica il debug di avere viste nidificate in quanto posso vedere i risultati intermedi per vedere dove è andato storto.
Simon Richter,

1
Ho scritto un server di database incorporato e, per me, risolvere prima le viste e poi ottimizzare la query risultante è stato il percorso ovvio, poiché in realtà è abbastanza improbabile che tutte le query sulle viste restituiscano tutte le colonne. Non riesco nemmeno a pensare a un motivo per cui realizzare dati di visualizzazione nel mezzo di una query avrebbe guadagnato qualcosa, quindi per me è stato un gioco da ragazzi.
Simon Richter,

26

A volte le visualizzazioni nidificate vengono utilizzate per impedire la ripetizione di aggregati. Diciamo che hai una vista che conta i messaggi e li raggruppa per userid, potresti avere una vista su quella che conta il numero di utenti che hanno> 100 messaggi, quel tipo di cose. Ciò è più efficace quando la vista di base è una vista indicizzata: non è necessario creare necessariamente un'altra vista indicizzata per rappresentare i dati con un raggruppamento leggermente diverso, poiché ora si paga due volte per la manutenzione dell'indice in cui le prestazioni sono probabilmente adeguato rispetto alla vista originale.

Se si tratta solo di viste nidificate in cui stai effettuando select * ma cambiando l'ordine o in alto, sembra che questo sarebbe meglio incapsulato come una procedura memorizzata con parametri (o funzioni incorporate con valori di tabella) rispetto a un gruppo di viste nidificate. A PARER MIO.


4
"Questo è più efficace quando la vista di base è una vista indicizzata." Punto importante.
Nick Chammas,

7

Le versioni successive di SQL (2005+) sembrano migliori nell'ottimizzare l'uso delle viste. Le visualizzazioni sono ottimali per il consolidamento delle regole aziendali. Ad esempio: dove lavoro abbiamo un database di prodotti di telecomunicazione. Ogni prodotto è assegnato a un piano tariffario e tale piano tariffario può essere scambiato e le tariffe sul piano tariffario possono essere attivate / disattivate all'aumentare o alla modifica delle tariffe.

Per semplificare, possiamo creare viste nidificate. La prima vista unisce semplicemente i piani tariffari alle loro tariffe utilizzando le tabelle necessarie e restituendo tutti i dati necessari di cui avrebbero bisogno i prossimi livelli di visualizzazioni. La / e seconda / e vista / e può isolare solo i piani tariffari attivi e le loro tariffe attive. Oppure, solo le tariffe dei clienti. O tariffe dei dipendenti (per lo sconto dei dipendenti). O tariffe per clienti commerciali o residenziali. (i piani tariffari possono complicarsi). Il punto è che la vista di base garantisce che la nostra logica aziendale complessiva per piani tariffari e tariffe sia unita correttamente in un'unica posizione. Il prossimo livello di visualizzazioni ci consente di concentrarci maggiormente su piani tariffari specifici (tipi, attivo / inattivo, ecc.).

Concordo sul fatto che le visualizzazioni possono rendere il debug disordinato se si creano query e visualizzazioni contemporaneamente. Tuttavia, se si utilizza una vista di tipo affidabile, questo semplifica il debug. Sai che la vista è già passata attraverso la suoneria, quindi sai che molto probabilmente non sta causando il problema.

Tuttavia, possono sorgere problemi con le tue opinioni. "cosa succede se un prodotto è associato solo a un piano tariffario inattivo?" o "cosa succede se un piano tariffario ha solo tassi inattivi su di esso?" Bene, questo può essere catturato a livello di front-end con una logica che rileva gli errori dell'utente. "Errore, il prodotto è su un piano tariffario inattivo ... per favore correggi". Possiamo anche eseguire controlli delle query per ricontrollarlo prima di eseguire una fatturazione. (selezionare tutti i piani e unirsi a sinistra alla vista del piano tariffario attivo, restituire solo i piani che non ottengono un piano tariffario attivo come problemi che devono essere risolti).

La cosa positiva di questo è che le viste consentono di ridurre notevolmente le query per i rapporti, la fatturazione, ecc. È possibile avere una vista dell'account cliente, quindi una vista di 2 ° livello solo per i clienti attivi. Team che in vista dell'indirizzo del cliente. Team che in vista del (i) prodotto (i) (unito a quale prodotto (i) cliente (i) ha). Abbinalo per visualizzare il piano tariffario dei prodotti. Team che in vista delle caratteristiche del prodotto. Visualizza, visualizza, visualizza ogni prova-n-errata per garantire l'integrità. La tua query finale usando le viste è molto compatta.

modificare:

Come esempio di come la vista sarebbe stata migliore di una semplice query di tabelle ... abbiamo avuto un appaltatore temporaneo per apportare alcune modifiche. Gli dissero che c'erano punti di vista per le cose, ma decise di appiattire tutte le sue domande. La fatturazione stava eliminando alcune delle sue domande. Continuavano a ricevere piani tariffari multipli e tariffe sulle cose. Si scopre che le sue query mancavano di criteri per consentire alle tariffe di fatturare solo se si trovavano tra le date di inizio e fine in cui il piano tariffario avrebbe dovuto utilizzare quella / quelle tariffe durante. Ops. Se avesse usato la vista, avrebbe già tenuto conto di quella logica.

Fondamentalmente, devi valutare le prestazioni rispetto alla sanità mentale. Forse puoi fare tutti i tipi di cose fantasiose per aumentare le prestazioni di un database. Ma, se significa che è un incubo per una persona nuova da assumere / mantenere, ne vale davvero la pena? Vale davvero la pena che il nuovo ragazzo debba giocare a meraviglia dovendo trovare tutte le domande che devono cambiare la sua logica (e rischiare che lui le dimentichi / le faccia ingrassare) b / c qualcuno ha deciso che le viste sono "cattive" e non ha consolidato una logica di business principale in una che potrebbe essere utilizzata in centinaia di altre query? Dipende davvero dalla tua azienda e dal tuo team IT / IS / DB. Preferirei chiarezza e consolidamento a fonte singola rispetto alle prestazioni.


4

Il vero problema non sono le viste nidificate in se stesse. Il vero problema è la proliferazione di viste nidificate mentre gli sviluppatori sovrappongono ulteriori modifiche alle viste esistenti. Ho trovato query con una vista nidificata 4 livelli che si sono effettivamente uniti a una delle viste nella sua definizione. La nostra tendenza a prendere la via d'uscita piuttosto che analizzare e risolvere un problema è la radice del problema.


0

Nel mio ambiente, replichiamo molte tabelle dal server di produzione al server di report. Sul server di report sono disponibili numerose visualizzazioni basate su tabelle di produzione replicate e nidificate. Prima che inizi la replica, dobbiamo rimuovere tutte le viste per rendere possibile la replica (usiamo drop e create perché la struttura delle tabelle cambia spesso nella produzione). Al termine della replica, è necessario ricostruire tutte le visualizzazioni.

Ora ecco la parte divertente: poiché molte visualizzazioni sono nidificate, dobbiamo ricostruirle in un ordine specifico. Mentre si apportano modifiche alla definizione delle viste, è necessario prestare attenzione per mantenere l'ordine di ricostruzione corretto. È un casino totale. Sconsiglio vivamente di utilizzare le visualizzazioni nidificate se si utilizza la replica o semplicemente si rilascia e si ricostruiscono le tabelle, che sono fonte di visualizzazioni.

Le prestazioni sono un'altra cosa. Le visualizzazioni basate su altre visualizzazioni non sono altro che più query da eseguire. È più facile mettere insieme la query più grande, creare un lavoro e ricavarne una tabella. Più facile e migliora le prestazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.