¿Cuándo es mejor descargar el trabajo al RDBMS en lugar de hacerlo en código?

12

De acuerdo, lo abordaré: soy un mejor codificador que en las bases de datos, y me pregunto dónde están las ideas sobre "mejores prácticas" sobre el tema de hacer cálculos "simples" en la consulta SQL vs. el código, como este ejemplo de MySQL (¡no lo escribí, solo tengo que mantenerlo!) - Esto devuelve el nombre de usuario y la edad de los usuarios desde el último 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
...

En comparación con hacer el levantamiento "pesado" en el código:

Consulta:

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

código:

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."; 

Estoy bastante seguro de que en un caso simple como este no habría mucha diferencia (aparte de la sensación de horror cuando tengo que hacer cambios en consultas como la primera), pero creo que aclara lo que yo ' Estoy buscando.

¡Gracias!

GeminiDomino
fuente
1
Esta es una buena pregunta: me he encontrado con el mismo problema.
Michael K
He aquí un buen ejemplo de cuando no hacerlo: calendar.sql (. Sí, esa es mi monstruosidad, sí, que era una mala idea, y no, no es lento)
greyfade
Ye volteando dioses ... Apuesto a que el MD5 para esa cosa resulta ser "CthulhuFhtagn"
GeminiDomino

Respuestas:

13

Desea realizar todas las operaciones basadas en conjuntos en la base de datos por motivos de rendimiento. Entonces funciones de agregación, funciones de clasificación, uniones, etc.

Este cálculo de edad, lo haría en código. La única razón por la que podría hacer algo como esto en una consulta de base de datos es si requiriera muchas columnas que de otro modo no seleccionaría y que en realidad podrían ser suficientes datos para ralentizar significativamente mi consulta. Seleccionar algunos valores enteros no hará una diferencia significativa de rendimiento. E incluso si hace una diferencia de rendimiento moderada, estaré predispuesto a mantener esta lógica en el código de la aplicación.

Jeremy
fuente
Estoy de acuerdo. El código que juega con los valores para fines de visualización debe estar en el código de su aplicación.
TehShrike
4

Cada caso es diferente

Es la lógica ...

  • necesitado por otros clientes? DRY: en la base de datos
  • utilizado para su posterior procesamiento? por ejemplo, ordenar por edad descendente: en la base de datos
  • requiere ajustes regionales? dd / mm / aaaa o mm / dd / aaaa: en el cliente
  • usado a menudo? Por qué calcularlo una y otra vez: use la columna calculada y persistente en la base de datos

En este caso, podría usar una columna calculada y persistente en la base de datos

Podría ser peor: podría tener esto en la base de datos:

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

Básicamente, debe observar dos cosas: uso de CPU y tráfico de red. No debe generar respuestas enormes, transferirlas a través de la red y luego resumirlas en la interfaz, ya que la base de datos puede hacerlo mucho mejor.

Para la manipulación de datos es un intercambio de. Si la base de datos gasta una cantidad comparable de ciclos de CPU en su código frontend haciendo lo mismo, dado que la cantidad de datos transferidos es más o menos equivalente), entonces no importa dónde. Luego, hágalo donde tenga la mayor experiencia en programación. Con frecuencia, puede obtener un camino MUY largo con una selección cuidadosa y eso podría ser muy útil.


fuente
1

Usted mencionó uno: área de especialización. Quizás la estructura de la base de datos no sea demasiado intensa, por lo que decide descargar parte del desarrollo de la lógica a un miembro del equipo que esté más centrado en la base de datos. Puede que no sea lo ideal, pero si tienes poco tiempo ...

El hardware de la base de datos tiene significativamente más recursos que otros servidores y no puede cambiar esto. Esto puede no aplicarse a esta situación específica, pero puede ser necesario considerarlo.

Hay otras aplicaciones que pueden necesitar la lógica fuera de su código. Es posible que algunas herramientas de redacción de informes no puedan utilizar un servicio web o una API. Puede duplicar la lógica o si cree que los requisitos pueden diferir.

JeffO
fuente
"El hardware de la base de datos tiene muchos más recursos que otros servidores y no puede cambiar esto". - eh? ¿De dónde vienen esas dos declaraciones?
Peter Boughton el
Creo que Jeff podría estar hablando de servidores de bases de datos independientes. Probablemente debería haber especificado que trabajo principalmente en configuraciones LA [MP] P.
GeminiDomino
1
Una configuración de LAMP no es motivo para no tener un servidor de base de datos independiente, y tampoco es un servidor de base de datos independiente una garantía de más recursos o no poder cambiar esto.
Peter Boughton el
Hrm. No estoy seguro entonces.
GeminiDomino
@Peter Boughton, DB y la aplicación en el mismo servidor tienen un orden de magnitud menos tiempo para la conexión de la interfaz y magnitudes IO mayores en todo momento, hay razones reales para ubicar estos dos juntos.
Jé Queue
0

Siempre me equivoco al poner tanto procesamiento en la base de datos. Su sintaxis anterior también podría escribirse con funciones DB que serían IMO, una solución muy limpia.

Jé Queue
fuente