Quando è meglio scaricare il lavoro su RDBMS piuttosto che farlo nel codice?


12

Va bene, ci riuscirò: sono un programmatore migliore di quello che sono nei database e mi chiedo dove siano i pensieri sulle "migliori pratiche" sull'argomento di fare calcoli "semplici" nella query SQL rispetto a in il codice, come questo esempio di MySQL (non l'ho scritto, devo solo mantenerlo!) - Questo restituisce il nome utente e gli utenti invecchiano dall'ultimo evento.

SELECT u.username as user, 
       IF ((DAY(max(e.date)) - DAY(u.DOB)) < 0 ,   
       TRUNCATE(((((YEAR(max(e.date))*12)+MONTH(max(e.date)))
       -((YEAR(u.DOB)*12)+MONTH(u.DOB)))-1)/12, 0),  
       TRUNCATE((((YEAR(max(e.date))*12)+MONTH(max(e.date))) -            
       ((YEAR(u.DOB)*12)+MONTH(u.DOB)))/12, 0)) AS age   
FROM users as u
JOIN events as e ON u.id = e.uid
...

Rispetto al sollevamento "pesante" del codice:

Query:

SELECT u.username, u.DOB as dob, e.event_date as edate
FROM users as u
JOIN events as e ON u.id = e.uid

codice:

function ageAsOfDate($birth, $aod)
{    //expects dates in mysql Y-m-d format...
     list($by,$bm,$bd) = explode('-',$birth);
     list($ay,$am,$ad) = explode('-',$aod);

     //Insert Calculations here 
     ...
     return $Dy; //Difference in years
}

echo "Hey! ". $row['user'] ." was ". ageAsOfDate($row['dob'], $row['edate']) . " when we last saw him."; 

Sono abbastanza sicuro che in un caso semplice come questo non farebbe molta differenza (oltre alla strisciante sensazione di orrore quando devo apportare modifiche a domande come la prima), ma penso che chiarisca ciò che sto cercando.

Grazie!


1
Questa è una buona domanda: ho riscontrato lo stesso problema.
Michael K,

Ecco un buon esempio di quando non farlo: calendar.sql (Sì, questa è la mia mostruosità, sì, è stata una cattiva idea, e no, non è lenta.)
greyfade

Sfogliando gli dei ... Scommetto che l'MD5 sembra che "CthulhuFhtagn"
GeminiDomino

Risposte:


13

Si desidera eseguire tutte le operazioni basate su set nel database per motivi di prestazioni. Quindi funzioni di aggregazione, funzioni di ordinamento, join ecc.

Questo calcolo dell'età, lo farei nel codice. L'unico motivo per cui potrei mai fare qualcosa del genere in una query del database è se richiedesse molte colonne che altrimenti non selezionerei e che potrebbero effettivamente costituire una quantità sufficiente di dati per rallentare significativamente la mia query. La selezione di alcuni valori interi non farà una differenza significativa nelle prestazioni. E anche se fa una moderata differenza di prestazioni, sarò prevenuto nel mantenere questa logica nel codice dell'applicazione.


Sono d'accordo. Il codice che armeggia con valori a scopo di visualizzazione dovrebbe essere nel codice dell'app.
TehShrike

4

Ogni caso è diverso

La logica è ...

  • necessario ad altri clienti? SECCO: nel database
  • utilizzato per ulteriori elaborazioni? es. ordina per età decrescente: nel database
  • richiede impostazioni regionali? gg / mm / aaaa o mm / gg / aaaa: nel client
  • usato spesso? Perché calcolarlo ancora e ancora: utilizzare la colonna calcolata e persistente nel database

In questo caso, potrei usare una colonna calcolata e persistente nel database

Potrebbe essere peggio: potresti averlo nel database:

"Hey! ". u.username." was ". <datecalc>. " when we last saw him."

3

Fondamentalmente dovresti considerare due cose: l'utilizzo della CPU e il traffico di rete. Non dovresti generare risposte enormi, trasferirle sulla rete e quindi riassumere nel frontend, poiché il database può fare molto meglio.

Per manipolazione dei dati è un trade-of. Se il database spende una quantità comparabile di cicli cpu con il tuo codice frontend facendo la stessa cosa - dato che la quantità di dati trasferiti è approssimativamente equivalente), allora non importa dove. Quindi fallo dove hai il maggior numero di competenze di programmazione. Spesso, puoi fare MOLTO lungo con un'attenta selezione e questo potrebbe essere molto utile.


1

Ne hai menzionato uno: area di competenza. Forse la struttura del database non è troppo intensiva, quindi si decide di scaricare parte dello sviluppo della logica su un membro del team più incentrato sul database. Potrebbe non essere l'ideale, ma se hai poco tempo ...

L'hardware del database ha molte più risorse rispetto ad altri server e non è possibile modificarlo. Questo potrebbe non essere applicabile a questa situazione specifica, ma potrebbe essere necessario prendere in considerazione.

Esistono altre applicazioni che potrebbero richiedere la logica al di fuori del codice. Alcuni strumenti di scrittura dei report potrebbero non essere in grado di utilizzare un servizio Web o un'API. È possibile duplicare la logica o se si ritiene che i requisiti possano differire.


"L'hardware del database ha molte più risorse rispetto ad altri server e non è possibile modificarlo." - eh? Da dove vengono queste due affermazioni?
Peter Boughton,

Penso che Jeff stia parlando di server database autonomi. Probabilmente avrei dovuto specificare che lavoro principalmente su configurazioni LA [MP] P.
GeminiDomino,

1
Un'installazione LAMP non è un motivo per non avere un server di database autonomo, né un server di database autonomo è una garanzia di più risorse né non è in grado di cambiarlo.
Peter Boughton,

Hrm. Non sono sicuro allora.
GeminiDomino,

@Peter Boughton, DB e app nello stesso server hanno un ordine di grandezza in meno tempo per la connessione dell'interfaccia e una maggiore IO in tutto, ci sono ragioni reali per individuare questi due insieme.
Jé Queue,

0

Ho sempre sbagliato a mettere tanta elaborazione nel DB. La tua sintassi sopra potrebbe anche essere scritta con funzioni DB che sarebbero IMO una soluzione molto pulita.

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.