Domanda

Ho una query un po 'complessa con sotto-domande multiple (nidificate), che voglio rendere disponibile per gli sviluppatori di applicazioni. La query è generica e genera una vista con valori calcolati su una raccolta di set di dati e lo sviluppatore dovrebbe essere necessario solo alcuni record da ciò che la query restituisce (cioè limiteranno il risultato per un ID di entità o un intervallo di date o alcuni tale).

Riesco a vedere 3 modi per implementare questo:

  1. Lascia che gli sviluppatori incorporano la query in ogni applicazione e aggiungano la propria WHERE clausole se necessario.
  2. Crea una procedura memorizzata che accetta come parametri tutte le condizioni di cui mi aspetto che gli sviluppatori abbiano bisogno (per il bene dell'argomento diamo dire che posso prevedere cosa sarà necessario per il prossimo futuro) e la procedura eseguirà la complessa query e filtrarà secondo i parametri passati.
  3. Implementa la query come vista con diverse viste secondarie (perché MySQL non consente sotto-domande nelle visualizzazioni) e far sì che gli sviluppatori lo utilizzino come tabella e usi WHERE Per avere ogni applicazione applica i filtri di cui hanno bisogno. Attualmente sto esaminando 3 ulteriori sotto-visioni, soprattutto perché alcune sotto-domande vengono utilizzate più volte e le facendo come sotto-views impediscono la duplicazione-altrimenti avrebbe potuto essere peggio ;-).

Cosa sarà per quanto riguarda le prestazioni migliori? (Supponendo che tutta l'indicizzazione sia equivalente in tutti i casi) Se lo si può.

Cosa sarà meglio nei termini di manutenzione del codice, pensi?

È stato utile?

Soluzione

Mi piacciono le domande che definiscono "bene" - hai chiesto specificamente le prestazioni e la manutenibilità, che consentono alle risposte di parlare di quel compromesso.

Da un punto di vista delle prestazioni, non penso che ci sia alcuna differenza tra le 3 opzioni, purché le query e i dati si inseriscano negli scenari previsti. Metterei al test con 100 volte più dati e potenzialmente ampliando la clausola "dove" per vedere cosa succede, ma la struttura di indicizzazione ecc. Ha maggiori probabilità di influire sulle prestazioni rispetto al fatto che si esegue lo stesso SQL da un proc, attraverso un Visualizza o da un'applicazione client.

Il modo migliore per rispondere a questa domanda è testarlo: ci sono, ovviamente, molti dettagli specifici che potrebbero invalidare le risposte generali "Mi aspetterei risposte X, Y o Z" che noi overflowers possiamo dare. Se le prestazioni sono una preoccupazione fondamentale, utilizzare uno strumento di riempimento del database (Redgate Make On, ho usato DBMonster in passato) e provare tutte e 3 le opzioni.

Da un punto di manutenzione di, Visualizza, fornirei un'opzione 4, che - a mio avviso - è di gran lunga la migliore.

Opzione 4: crea una libreria di accesso ai dati che incapsula l'accesso ai dati. Chiedi ai metodi e ai parametri di esporre la libreria per perfezionare la selezione dei record. Prendi in considerazione l'utilizzo del modello di specifica (http://en.wikipedia.org/wiki/specification_pattern). Usa qualsiasi domanda sia meglio all'interno della biblioteca e non disturbare gli sviluppatori con i dettagli di implementazione.

Se ciò non funziona - Codice eterogeneo dell'applicazione, troppa modifica per un requisito semplice - valuterei le opzioni come segue:

  1. SQL incorporato: a seconda del numero di volte in cui questo SQL viene riutilizzato, questo può essere a posto. Se c'è solo una parte del codice che esegue SQL, è logicamente simile alla libreria di accesso ai dati. Se, tuttavia, lo stesso frammento deve essere riutilizzato in molti luoghi, è una probabile fonte di bug: una piccola modifica nell'SQL dovrebbe essere ripetuta in diversi luoghi.

  2. Procedura memorizzata: generalmente non mi piacciono le procedure memorizzate per motivi di manutenzione: tendono a diventare fragili con il caricamento eccessivo e creano un modo di pensare procedurale. Ad esempio, se si dispone di altri requisiti per l'utilizzo di questo calcolo SQL in una procedura memorizzata separata, molto rapidamente si finisce con un modello di programmazione procedurale, con Proc memorizzati che si chiamano a vicenda.

  3. Visualizzazioni: questa è probabilmente la scelta migliore. Mette la logica di dati specifica in un unico posto, ma promuove l'uso della logica basata su set perché il percorso di accesso è attraverso un'istruzione selezionata, piuttosto che eseguendo dichiarazioni procedurali. Le visualizzazioni sono facili da incorporare in altre domande.

Altri suggerimenti

Se ben implementato, una delle tre soluzioni andrebbe bene per la manteinanza, ma tieni presente come tratteresti ciascuno di essi in un processo di migrazione (codice o migrazione del database).

Se la query è grande, la procedura memorizzata ti darà un po 'di extra prestazione a causa di meno bandwith sopra la testa perché sta inviando una query di dimensioni più piccole. Puoi anche ottenere un po 'di sicurezza in più con questa soluzione.

Per un manteinanza Soluzione, preferirei la 1a e la seconda soluzione, perché è possibile apportare modifiche alla query senza apportare modifiche al database. Se scegli la prima soluzione, avvolgerei la chiamata di query all'interno di una funzione in modo da avere un solo posto per apportare modifiche.

Da un punto di vista dello sviluppatore, Sceglierei la soluzione di visualizzazione che beacuse è la più trasparente, intendo che è come una query solo una tabella normale, puoi controllare la struttura della tabella con un comando descrivi o semplicemente selezionare i campi e le condizioni necessari per interrogare o unirsi a un altro tavolo, ecc ...

Riguardo a dove flessibilità della clausola, puoi raggiungerlo con una delle soluzioni proposte. È possibile aggiungere un parametro dove nella funzione di avvolgimento (1), è possibile aggiungere un parametro dove la procedura memorizzata ma essere cauti con iniezioni (2) o lo sviluppatore può aggiungere una clausola dove al solito con la vista (3)

Tenendo presente che nelle viste MySQL non sono tabelle temporanee, Se la query è molto complessa Queste soluzioni non sarebbero le migliori se la query viene utilizzata molto e in modi diversi (disabilitare le prestazioni della cache). Considererei una tavola temporanea Soluzione (bancone) che aggiorna ogni periodo di tempo con un'attività / cron programmata (ad esempio un giorno, una settimana, ogni volta che è necessario) o viene aggiornato impostando i trigger di proper. Questa soluzione potrebbe migliorare un po 'le prestazioni.

Spero che questo aiuti, mi piace di più la soluzione di visualizzazione, ma forse è più complesso svilupparsi dal punto di vista del database.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top