Errores de desarrollo de bases de datos cometidos por desarrolladores de aplicaciones [cerrado]


¿Cuáles son los errores comunes de desarrollo de bases de datos cometidos por los desarrolladores de aplicaciones?

Author: Charles Faiga, 2009-03-07

30 answers

1. No utilizar índices apropiados

Esto es relativamente fácil, pero todavía sucede todo el tiempo. Las claves foráneas deben tener índices en ellas. Si estás usando un campo en un WHERE deberías (probablemente) tener un índice en él. Tales índices a menudo deben cubrir varias columnas en función de las consultas que necesita ejecutar.

2. No hacer cumplir la integridad referencial

Su base de datos puede variar aquí, pero si su base de datos soporta referencial integridad meaning lo que significa que todas las claves foráneas están garantizadas para apuntar a una entidad que existe should debería estar usándola.

Es bastante común ver este fallo en bases de datos MySQL. No creo que MyISAM lo apoye. InnoDB lo hace. Encontrarás personas que están usando MyISAM o aquellas que están usando InnoDB pero no lo están usando de todos modos.

Más aquí:

3. Usando claves primarias naturales en lugar de sustitutivas (técnicas)

Las claves naturales son claves basadas en datos externamente significativos que son (ostensiblemente) únicos. Ejemplos comunes son códigos de productos, códigos estatales de dos letras (EE. UU.), números de seguro social, etc. Subrogada o primaria técnica las claves son aquellas que no tienen absolutamente ningún significado fuera del sistema. Se inventan puramente para identificar la entidad y suelen ser campos de auto-incremento (SQL Server, MySQL, otros) o secuencias (sobre todo Oracle).

En mi opinión deberías siempre usar llaves sustitutas. Este tema ha surgido en estas preguntas:

Este es un tema algo controvertido sobre el que no obtendrá un acuerdo universal. Si bien puede encontrar algunas personas que piensan que las claves naturales están bien en algunas situaciones, no encontrará ninguna crítica de las claves sustitutas que no sea posiblemente innecesaria. Eso es un pequeño inconveniente si me preguntas.

Recuerde, incluso los países pueden dejar de existir (por ejemplo, Yugoslavia).

4. Escribir consultas que requieren DISTINCT para funcionar

A menudo se ve esto en las consultas generadas por OR. Mira la salida de registro de Hibernate y verás que todas las consultas comienzan con:

SELECT DISTINCT ...

Este es un atajo para asegurarse de que no devuelva filas duplicadas y, por lo tanto, obtenga objetos duplicados. A veces se ver a la gente haciendo esto. Si lo ves demasiado es una verdadera bandera roja. No es que DISTINCT sea malo o no tenga aplicaciones válidas. Lo hace (en ambos casos), pero no es un sustituto o un recurso provisional para escribir consultas correctas.

De Por qué odio DISTINTO:

Donde las cosas comienzan a agriarse en mi opinión es cuando un desarrollador se construyendo consultas sustanciales, uniéndose mesas juntas, y de repente se da cuenta de que se ve como él ser obtener filas duplicadas (o incluso más) y su respuesta inmediata...su la "solución" a este "problema" es lanza la palabra clave DISTINTIVA y POOF todos sus problemas desaparecen.

5. Favorecer la agregación sobre las uniones

Otro error común de los desarrolladores de aplicaciones de base de datos es no darse cuenta de cuánto más costosa agregación (es decir, la cláusula GROUP BY) se puede comparar con las uniones.

Para darle una idea de lo extendido que está esto, He escrito sobre este tema varias veces aquí y he sido votado en contra mucho por ello. Por ejemplo:

From SQL statement - "join" vs "group by and having":

Primera consulta:

SELECT userid
FROM userrole
WHERE roleid IN (1, 2, 3)
GROUP by userid
HAVING COUNT(1) = 3

Tiempo de consulta: 0.312 s

Segunda pregunta:

SELECT t1.userid
FROM userrole t1
JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2
JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3
AND t1.roleid = 1

Tiempo de consulta: 0.016 s

Así es. La versión join I propuesto es veinte veces más rápido que la versión agregada.

6. No simplificar consultas complejas a través de vistas

No todos los proveedores de bases de datos admiten vistas, pero para aquellos que lo hacen, pueden simplificar en gran medida las consultas si se usan juiciosamente. Por ejemplo, en un proyecto utilicé un generic Party model para CRM. Esta es una técnica de modelado extremadamente potente y flexible, pero puede conducir a muchas uniones. En este modelo había:

  • Partido : personas y organizaciones;{[35]]}
  • Papel del partido : cosas que hicieron esos partidos, porque ejemplo Empleado y Empleador;
  • Relación de roles de Partido: cómo se relacionaron esos roles entre sí.

Ejemplo:

  • Ted es una Persona, siendo un subtipo de Partido; {[35]]}
  • Ted tiene muchos roles, uno de los cuales es Empleado; {[35]]}
  • Intel es una organización, siendo un subtipo de Partido;
  • Intel tiene muchos roles, uno de los cuales es Empleador;
  • Intel emplea a Ted, lo que significa que hay una relación entre sus respectivos rol.

Así que hay cinco mesas unidas para vincular a Ted con su empleador. Usted asume que todos los empleados son Personas (no organizaciones) y proporciona esta vista de ayuda:

CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id

Y de repente tiene una vista muy simple de los datos que desea, pero en un modelo de datos altamente flexible.

7. No desinfectar la entrada

Este es enorme. Ahora me gusta PHP, pero si no sabes lo que estás haciendo es muy fácil crear sitios vulnerables a los ataques. Nada lo resume mejor que la historia de little Bobby Tables .

Los datos proporcionados por el usuario a través de URLs, datos de formulario y cookies siempre deben ser tratados como hostiles y desinfectados. Asegúrate de obtener lo que esperas.

8. No utilizar declaraciones preparadas

Las sentencias preparadas son cuando compila una consulta menos los datos utilizados en inserts, updates y cláusulas WHERE y luego los suministra más tarde. Para ejemplo:

SELECT * FROM users WHERE username = 'bob'

Vs

SELECT * FROM users WHERE username = ?

O

SELECT * FROM users WHERE username = :username

Dependiendo de su plataforma.

He visto bases de datos puestas de rodillas al hacer esto. Básicamente, cada vez que una base de datos moderna encuentra una nueva consulta, tiene que compilarla. Si encuentra una consulta que ha visto antes, le está dando a la base de datos la oportunidad de almacenar en caché la consulta compilada y el plan de ejecución. Al hacer la consulta mucho, le está dando a la base de datos la oportunidad de averiguarlo y optimice en consecuencia(por ejemplo, fijando la consulta compilada en memoria).

El uso de instrucciones preparadas también le dará estadísticas significativas sobre la frecuencia con la que se utilizan ciertas consultas.

Las instrucciones preparadas también lo protegerán mejor contra los ataques de inyección SQL.

9. No normalizar lo suficiente

La normalización de la base de datos es básicamente el proceso de optimización del diseño de la base de datos o cómo organiza sus datos en tabla.

Justo esta semana me encontré con un código donde alguien había implosionado una matriz y lo insertó en un solo campo en una base de datos. Normalizar eso sería tratar el elemento de esa matriz como una fila separada en una tabla secundaria (es decir, una relación de uno a muchos).

Esto también surgió en El mejor método para almacenar una lista de ID de usuario :

He visto en otros sistemas que la lista se almacena en una matriz PHP serializada.

Pero la falta de la normalización viene en muchas formas.

Más:

10. Normalizar demasiado

Esto puede parecer una contradicción con el punto anterior, pero la normalización, como muchas cosas, es una herramienta. Es un medio para un fin y no un fin en sí mismo. Creo que muchos desarrolladores olvidan esto y comienzan a tratar un "significa" como un "fin". Las pruebas unitarias son un buen ejemplo de esto.

Una vez trabajé en un sistema que tenía una gran jerarquía para los clientes que era algo así como: {[18]]}

Licensee ->  Dealer Group -> Company -> Practice -> ...

De tal manera que tuvo que unir unas 11 tablas antes de poder obtener datos significativos. Es un buen ejemplo de normalización llevada demasiado lejos.

Más al grano, la desnormalización cuidadosa y considerada puede tener enormes beneficios de rendimiento, pero hay que tener mucho cuidado al hacer este.

Más:

11. Usando arcos exclusivos

Un arco exclusivo es un error cuando se crea una tabla con dos o más claves foráneas donde una y solo una de ellas puede ser no nula. Gran error. Por un lado, se vuelve mucho más difícil mantener la integridad de los datos. Después de todo, incluso con integridad referencial, nada impide que se establezcan dos o más de estas claves foráneas (a pesar de las restricciones de verificación complejas).

De Una Guía Práctica para el Diseño de Bases de Datos Relacionales :

Hemos aconsejado fuertemente contra la construcción exclusiva del arco dondequiera posible, por la buena razón de que pueden ser incómodos para escribir código y plantean más dificultades de mantenimiento.

12. No hacer análisis de rendimiento en las consultas en absoluto

El pragmatismo reina, particularmente en el mundo de las bases de datos. Si te apegas a los principios hasta el punto de que se han convertido en un dogma, entonces es muy probable que hayas cometido errores. Tome el ejemplo de las consultas agregadas de arriba. El la versión agregada puede parecer "agradable", pero su rendimiento es lamentable. Una comparación de rendimiento debería haber terminado el debate (pero no lo hizo), pero más al grano: escupir tales puntos de vista mal informados en primer lugar es ignorante, incluso peligroso.

13. Dependencia excesiva de TODOS los SINDICATOS y en particular de las construcciones SINDICALES

Una UNIÓN en términos SQL simplemente concatena conjuntos de datos congruentes, lo que significa que tienen el mismo tipo y número de columnas. La diferencia entre ellos es que UNION ALL es una concatenación simple y debe preferirse siempre que sea posible, mientras que una UNIÓN implícitamente hará una DISTINCIÓN para eliminar las tuplas duplicadas.

Las uniones, como DISTINTAS, tienen su lugar. Hay aplicaciones válidas. Pero si te encuentras haciendo muchos de ellos, particularmente en subconsultas, entonces probablemente estás haciendo algo mal. Ese podría ser un caso de mala construcción de consultas o un modelo de datos mal diseñado que lo obligue a hacer tales cosas.

Uniones, particularmente cuando se usa en uniones o subconsultas dependientes, puede paralizar una base de datos. Trate de evitarlos siempre que sea posible.

14. Uso de condiciones OR en consultas

Esto podría parecer inofensivo. Después de todo, ANDs están bien. O debería estar bien demasiado bien? Equivocada. Básicamente, an AND condition restringe el conjunto de datos, mientras que an OR condition lo hace crecer, pero no de una manera que se preste a la optimización. Sobre todo cuando las diferentes condiciones intersecar forzando así al optimizador a una operación DISTINTA en el resultado.

Malo:

... WHERE a = 2 OR a = 5 OR a = 11

Mejor:

... WHERE a IN (2, 5, 11)

Ahora su optimizador SQL puede convertir efectivamente la primera consulta en la segunda. Pero puede que no. No lo hagas.

15. No diseñar su modelo de datos que se preste a soluciones de alto rendimiento

Este es un punto difícil de cuantificar. Se observa típicamente por su efecto. Si te encuentras escribiendo las consultas gnarly para tareas relativamente simples o que las consultas para encontrar información relativamente sencilla no son eficientes, entonces probablemente tenga un modelo de datos pobre.

De alguna manera, este punto resume todos los anteriores, pero es más una advertencia que hacer cosas como la optimización de consultas a menudo se hace primero cuando se debe hacer en segundo lugar. En primer lugar, debe asegurarse de tener un buen modelo de datos antes de intentar optimizar el rendimiento. Como Knuth dijo:

La optimización prematura es la raíz de todo mal{[18]]}

16. Uso incorrecto de las Transacciones de la Base de Datos

Todos los cambios de datos para un proceso específico deben ser atómicos. Es decir, si la operación tiene éxito, lo hace completamente. Si falla, los datos se dejan sin cambios. - No debería haber posibilidad de cambios "a medio hacer".

Idealmente, la forma más sencilla de lograr esto es que todo el diseño del sistema debe esforzarse por admitir todos los datos cambios a través de instrucciones INSERT/UPDATE/DELETE. En este caso, no se necesita ningún manejo especial de transacciones, ya que su motor de base de datos debería hacerlo automáticamente.

Sin embargo, si algún proceso requiere que se realicen múltiples declaraciones como una unidad para mantener los datos en un estado consistente, entonces es necesario un Control de Transacción apropiado.

  • Comience una Transacción antes de la primera declaración.
  • Confirme la transacción después de la última declaración.
  • En cualquier error, Revertir la Transacción. Y muy NB! No se olvide de omitir / abortar todas las instrucciones que siguen después del error.

También se recomienda prestar mucha atención a las sutilezas de cómo la capa de conectividad de la base de datos y el motor de la base de datos interactúan en este sentido.

17. No comprender el paradigma' basado en conjuntos '

El lenguaje SQL sigue un paradigma específico adaptado a tipos específicos de problemas. Varias extensiones específicas del proveedor no obstante, el lenguaje lucha por lidiar con problemas que son triviales en langues como Java, C#, Delphi, etc.

Esta falta de comprensión se manifiesta de varias maneras.

  • Imponer inapropiadamente demasiada lógica procesal o imperativa en la base de datos.
  • Uso inadecuado o excesivo de cursores. Especialmente cuando una sola consulta sería suficiente.
  • Asumiendo incorrectamente que los disparadores se activan una vez por fila afectada en varias filas actualizar.

Determinar una clara división de responsabilidades, y esforzarse por utilizar la herramienta adecuada para resolver cada problema.

 1003
Author: cletus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:37

Errores de programación y diseño de bases de datos clave cometidos por los desarrolladores

  • Diseño y uso egoísta de la base de datos. Los desarrolladores a menudo tratan la base de datos como su almacén de objetos persistentes personal sin tener en cuenta las necesidades de otros interesados en los datos. Esto también se aplica a los arquitectos de aplicaciones. El mal diseño de la base de datos y la integridad de los datos dificultan el trabajo de terceros con los datos y pueden aumentar sustancialmente los costos del ciclo de vida del sistema. Los informes y MIS tienden a ser un primo pobre en el diseño de aplicaciones y solo se hacen como una idea tardía.

  • Abusar de datos desnormalizados. Exagerar los datos desnormalizados y tratar de mantenerlos dentro de la aplicación es una receta para problemas de integridad de datos. Utilice la desnormalización con moderación. No querer añadir un join a una consulta no es una excusa para desnormalizar.

  • Miedo de escribir SQL. SQL no es ciencia espacial y en realidad es bastante bueno para hacer su trabajo. Las capas de asignación de O / R son bastante buenas para hacer el 95% de las consultas que son simples y encajan bien en ese modelo. A veces SQL es la mejor manera de hacer el trabajo.

  • Políticas dogmáticas de 'Procedimientos No Almacenados'. Independientemente de si cree que los procedimientos almacenados son malos, este tipo de actitud dogmática no tiene lugar en un proyecto de software.

  • No entiendo el diseño de la base de datos. La normalización es tu amiga y es no rocket ciencia. La unión y la cardinalidad son conceptos bastante simples: si está involucrado en el desarrollo de aplicaciones de base de datos, realmente no hay excusa para no entenderlos.

 110
Author: ConcernedOfTunbridgeWells,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:02
  1. No usar el control de versiones en el esquema de la base de datos
  2. Trabajando directamente contra una base de datos en vivo
  3. No leer y comprender conceptos de bases de datos más avanzados (índices, índices agrupados, restricciones, vistas materializadas, etc.)
  4. No se puede probar la escalabilidad ... los datos de prueba de solo 3 o 4 filas nunca le darán la imagen real del rendimiento real en vivo
 80
Author: Rad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 15:33:11

Uso excesivo y/o dependencia de procedimientos almacenados.

Algunos desarrolladores de aplicaciones ven los procedimientos almacenados como una extensión directa del código de nivel medio/front-end. Esto parece ser un rasgo común en los desarrolladores de Microsoft Stack, (soy uno, pero he crecido fuera de él) y produce muchos procedimientos almacenados que realizan la lógica de negocio compleja y el procesamiento de flujo de trabajo. Es mucho mejor hacerlo en otro lugar.

Los procedimientos almacenados son útiles cuando se ha demostrado realmente que factor técnico requiere su uso (por ejemplo, rendimiento y seguridad) Por ejemplo, mantener la agregación/filtrado de grandes conjuntos de datos "cerca de los datos".

Recientemente tuve que ayudar a mantener y mejorar una gran aplicación de escritorio Delphi de la cual el 70% de la lógica de negocio y las reglas se implementaron en 1400 procedimientos almacenados de SQL Server (el resto en controladores de eventos de interfaz de usuario). Esto fue una pesadilla, principalmente debido a la dificultad de introducir pruebas unitarias efectivas a TSQL, falta de encapsulación y herramientas pobres (Depuradores, editores).

Trabajando con un equipo de Java en el pasado, rápidamente descubrí que a menudo ocurre lo contrario en ese entorno. Un arquitecto de Java me dijo una vez: "La base de datos es para datos, no para código.".

En estos días creo que es un error no considerar procs almacenados en absoluto, pero deben ser utilizados con moderación (no por defecto) en situaciones en las que proporcionan beneficios útiles (ver las otras respuestas).

 46
Author: Ashley Henderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 17:24:49

Problema Número uno? Solo prueban en bases de datos de juguetes. Así que no tienen idea de que su SQL se arrastrará cuando la base de datos se haga grande, y alguien tiene que venir y arreglarlo más tarde (ese sonido que puedes escuchar es mi rechinar de dientes).

 41
Author: Bob Moore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 15:37:54

No se utilizan índices.

 31
Author: Christophe Herreman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 14:19:42

Rendimiento Deficiente Causado por Subconsultas Correlacionadas

La mayoría de las veces desea evitar subconsultas correlacionadas. Una subconsulta se correlaciona si, dentro de la subconsulta, hay una referencia a una columna de la consulta externa. Cuando esto sucede, la subconsulta se ejecuta al menos una vez por cada fila devuelta y podría ejecutarse más veces si se aplican otras condiciones después de aplicar la condición que contiene la subconsulta correlacionada.

Perdona el ejemplo artificial y la sintaxis de Oracle, pero digamos que quería encontrar todos los empleados que han sido contratados en cualquiera de sus tiendas desde la última vez que la tienda hizo menos de sales 10,000 de ventas en un día.

select e.first_name, e.last_name
from employee e
where e.start_date > 
        (select max(ds.transaction_date)
         from daily_sales ds
         where ds.store_id = e.store_id and
               ds.total < 10000)

La subconsulta en este ejemplo se correlaciona con la consulta externa por el store_id y se ejecutará para cada empleado en su sistema. Una forma de optimizar esta consulta es mover la subconsulta a una vista en línea.

select e.first_name, e.last_name
from employee e,
     (select ds.store_id,
             max(s.transaction_date) transaction_date
      from daily_sales ds
      where ds.total < 10000
      group by s.store_id) dsx
where e.store_id = dsx.store_id and
      e.start_date > dsx.transaction_date

En este ejemplo, la consulta en la cláusula from es ahora una vista en línea (de nuevo alguna sintaxis específica de Oracle) y solo se ejecuta una vez. Dependiendo de su modelo de datos, esta consulta probablemente se ejecutará mucho más rápido. Funcionaría mejor que la primera consulta a medida que aumentara el número de empleados. La primera consulta podría funcionar mejor si hubiera pocos empleados y muchas tiendas (y quizás muchas de las tiendas no tuvieran empleados) y la tabla daily_sales se indexara en store_id. Este no es un escenario probable, pero muestra cómo una consulta correlacionada podría posiblemente realizar mejor que una alternativa.

He visto desarrolladores junior correlacionar subconsultas muchas veces y por lo general ha tenido un impacto severo en el rendimiento. Sin embargo, al eliminar una subconsulta correlacionada, asegúrese de mirar el plan explain antes y después para asegurarse de que no está empeorando el rendimiento.

 28
Author: adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-13 15:48:46

En mi experiencia:
No comunicarse con DBA experimentados.

 21
Author: Kb.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 14:42:55

Usando Access en lugar de una base de datos "real". Hay un montón de grandes bases de datos pequeñas e incluso gratuitas como SQL Express, MySQL , y SQLite que funcionarán y escalarán mucho mejor. Las aplicaciones a menudo necesitan escalar de maneras inesperadas.

 17
Author: Nathan Voxland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-08 04:20:43

Olvidarse de establecer relaciones entre las tablas. Recuerdo tener que limpiar esto cuando empecé a trabajar en mi empleador actual.

 16
Author: TheTXI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 14:16:30

Usando Excel para almacenar (grandes cantidades de) datos.

He visto empresas que tienen miles de filas y utilizan varias hojas de trabajo (debido al límite de filas de 65535 en versiones anteriores de Excel).


Excel es muy adecuado para informes, presentación de datos y otras tareas, pero no debe ser tratado como una base de datos.

 14
Author: ML--,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-02 17:18:26

Me gustaría añadir: Favoreciendo el código "elegante" sobre el código de alto rendimiento. El código que funciona mejor contra bases de datos es a menudo feo a los ojos del desarrollador de aplicaciones.

Creer que el sinsentido sobre la optimización prematura. Las bases de datos deben tener en cuenta el rendimiento en el diseño original y en cualquier desarrollo posterior. El rendimiento es el 50% del diseño de la base de datos (el 40% es integridad de los datos y el último 10% es seguridad) en mi opinión. Bases de datos que no se construyen de abajo hacia arriba para realizar funcionará mal una vez que los usuarios reales y el tráfico real se colocan contra la base de datos. Optimización prematura no significa ninguna optimización! Esto no significa que deba escribir código que casi siempre funcionará mal porque lo encuentre más fácil (cursores, por ejemplo, que nunca se deben permitir en una base de datos de producción a menos que todo lo demás haya fallado). Significa que no necesitas mirar exprimir ese último poco de rendimiento hasta que lo necesites. Se sabe mucho sobre lo que funcionará mejor en ignorar esto en el diseño y el desarrollo es, en el mejor de los casos, miope.

 14
Author: HLGEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 17:28:20

No se utilizan consultas parametrizadas. Son muy útiles para detener la inyección SQL.

Este es un ejemplo específico de no desinfectar los datos de entrada, mencionado en otra respuesta.

 13
Author: Ash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 16:52:46

Odio cuando los desarrolladores usan sentencias select anidadas o incluso funciones que devuelven el resultado de una sentencia select dentro de la porción "SELECT" de una consulta.

Estoy realmente sorprendido de no ver esto en ningún otro lugar aquí, tal vez lo pasé por alto, aunque @adam tiene un problema similar indicado.

Ejemplo:

SELECT
    (SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
    ,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
    MyTable c

En este escenario, si MyTable devuelve 10000 filas, el resultado es como si la consulta solo ejecutara 20001 consultas, ya que tenía que ejecutar la consulta inicial más la consulta cada una de las otras tablas una vez por cada línea de resultado.

Los desarrolladores pueden salirse con la suya trabajando en un entorno de desarrollo donde solo devuelven unas pocas filas de datos y las sub tablas generalmente solo tienen una pequeña cantidad de datos, pero en un entorno de producción, este tipo de consulta puede ser exponencialmente costoso a medida que se agregan más datos a las tablas.

Un ejemplo mejor (no necesariamente perfecto) sería algo como:

SELECT
     s.SomeValue As FirstVal
    ,o.OtherValue As SecondVal
FROM
    MyTable c
    LEFT JOIN (
        SELECT SomeDate, MAX(SomeValue) as SomeValue
        FROM SomeTable 
        GROUP BY SomeDate
     ) s ON c.Date = s.SomeDate
    LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria

Esto permite optimizadores de base de datos para barajar los datos juntos, en lugar de la solicitud en cada registro de la tabla principal y por lo general encuentro cuando tengo que arreglar el código donde se ha creado este problema, por lo general termino aumentando la velocidad de las consultas en un 100% o más, mientras que al mismo tiempo reduce el uso de CPU y memoria.

 12
Author: CStroliaDavis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-23 16:25:31

Para bases de datos basadas en SQL:

  1. No aprovechar los ÍNDICES AGRUPADOS o elegir la(s) columna (s) incorrecta (s) para AGRUPAR.
  2. No usar un tipo de datos SERIAL (autonumber) como CLAVE PRIMARIA para unirse a una CLAVE FORÁNEA (INT) en una relación de tabla padre/hijo.
  3. No ACTUALIZAR ESTADÍSTICAS en una tabla cuando se han INSERTADO o ELIMINADO muchos registros.
  4. No reorganizar (es decir, descargar, soltar, recrear, cargar y volver a indexar) tablas cuando se han insertado muchas filas o eliminadas (algunos motores mantienen físicamente las filas eliminadas en una tabla con un indicador eliminar.)
  5. No aprovechar FRAGMENT ON EXPRESSION (si es compatible) en tablas grandes que tienen altas tasas de transacción.
  6. ¡Elegir el tipo de datos incorrecto para una columna!
  7. No elegir un nombre de columna apropiado.
  8. No agregar nuevas columnas al final de la tabla.
  9. No crear índices adecuados para soportar consultas de uso frecuente.
  10. crear índices en columnas con pocas posibilidades valores y creación de índices innecesarios.
    ...más que añadir.
 12
Author: Frank Computer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-14 02:00:21
  • No tomar una copia de seguridad antes de solucionar algún problema dentro de la base de datos de producción.

  • Uso de comandos DDL en objetos almacenados (como tablas, vistas) en procedimientos almacenados.

  • Miedo de usar el proc almacenado o miedo de usar consultas OR donde sea más eficiente / apropiado usar.

  • Ignorar el uso de un generador de perfiles de base de datos, que puede decirle exactamente en qué se está convirtiendo su consulta OR y, por lo tanto, verificar la lógica o incluso para depuración cuando no se utiliza OR.

 9
Author: WhoIsNinja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-24 18:37:52

No haciendo el nivel correcto de normalización. Debe asegurarse de que los datos no se dupliquen y de que está dividiendo los datos en diferentes según sea necesario. También debe asegurarse de que no está siguiendo la normalización demasiado en la medida en que eso perjudicará el rendimiento.

 8
Author: Nathan Voxland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 14:22:35

Tratar la base de datos como un mecanismo de almacenamiento (es decir, biblioteca de colecciones glorificadas) y, por lo tanto, subordinada a su aplicación (ignorando otras aplicaciones que comparten los datos)

 8
Author: finnw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 16:02:56
  • Descartar un OR como Hibernar de la mano, por razones como "es demasiado mágico" o "no en mi base de datos".
  • Confiando demasiado en un OR como Hibernar y tratando de calzarlo en donde no es apropiado.
 8
Author: Adam Jaskiewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-02 18:33:48

1 - Usar innecesariamente una función en un valor en una cláusula where con el resultado de que no se usa ese índice.

Ejemplo:

where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate

En lugar de

where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1

Y en menor medida: No agregar índices funcionales a aquellos valores que los necesitan...

2 - No agregar restricciones de comprobación para garantizar la validez de los datos. Las restricciones pueden ser utilizadas por el optimizador de consultas, y realmente ayudan a garantizar que pueda confiar en sus invariantes. Hay simplemente no hay razón para no usarlos.

3 - Agregar columnas no normalizadas a las tablas por pura pereza o presión de tiempo. Las cosas generalmente no están diseñadas de esta manera, sino que evolucionan hacia esto. El resultado final, sin falta, es un montón de trabajo tratando de limpiar el desastre cuando te muerde la integridad de los datos perdidos en evoluciones futuras.

Piense en esto, una tabla sin datos es muy barata de rediseñar. Una mesa con un par de millones de registros sin integridad... no es tan barato rediseñar. Por lo tanto, hacer el diseño correcto al crear la columna o tabla se amortiza en picas.

4 - no tanto sobre la base de datos per se, pero de hecho molesto. No importa la calidad del código de SQL. El hecho de que su SQL se exprese en texto no hace que sea correcto ocultar la lógica en montones de algoritmos de manipulación de cadenas. Es perfectamente posible escribir SQL en texto de una manera que sea realmente legible por su compañero programador.

 8
Author: John Nilsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-04 11:05:17

Esto se ha dicho antes, pero: índices, índices, índices. He visto muchos casos de aplicaciones web empresariales de bajo rendimiento que se arreglaron simplemente haciendo un poco de perfil (para ver qué tablas se estaban golpeando mucho), y luego agregar un índice en esas tablas. Esto ni siquiera requiere mucho en el camino del conocimiento de escritura SQL, y la recompensa es enorme.

Evite la duplicación de datos como la plaga. Algunas personas abogan por que un poco de duplicación no hará daño, y lo hará mejorar el rendimiento. Oye, no estoy diciendo que tengas que torturar tu esquema en Tercera Forma Normal, hasta que sea tan abstracto que ni siquiera los DBA sepan lo que está pasando. Solo entienda que cada vez que duplique un conjunto de nombres, códigos postales o códigos de envío, las copias se desconectarán entre sí eventualmente. Sucederá. Y luego te estarás pateando mientras ejecutas el script de mantenimiento semanal.

Y por último: use un nombre claro, consistente e intuitivo convención. De la misma manera que una pieza de código bien escrita debe ser legible, un buen esquema SQL o consulta debe ser legible y prácticamente decirle lo que está haciendo, incluso sin comentarios. Te lo agradecerás en seis meses, cuando tengas que hacer mantenimiento en las mesas. "SELECT account_number, billing_date FROM national_accounts" es infinitamente más fácil de trabajar que "SELECT ACCNTNBR, BILLDAT FROM NTNLACCTS".

 7
Author: pbailey19,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-28 20:23:27

No ejecutar una consulta SELECT correspondiente antes de ejecutar la consulta DELETE (particularmente en bases de datos de producción)!

 6
Author: Jamol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-06 12:11:37

El error más común que he visto en veinte años: no planificar con anticipación. Muchos desarrolladores crearán una base de datos y tablas, y luego modificarán y expandirán continuamente las tablas a medida que construyen las aplicaciones. El resultado final es a menudo un desastre e ineficiente y difícil de limpiar o simplificar más adelante.

 5
Author: Skatterbrainz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-29 03:56:14

A) Valores de consulta de Hardcoding en cadena
b) Poner el código de consulta de la base de datos en la acción "OnButtonPress" en una aplicación de Windows Forms

He visto ambos.

 4
Author: Benoit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 17:29:57

No prestar suficiente atención a la administración de conexiones de base de datos en su aplicación. Luego descubre que la aplicación, el equipo, el servidor y la red están obstruidos.

 4
Author: chefsmart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 17:32:34
  1. Pensando que son DBA y modeladores/diseñadores de datos cuando no tienen adoctrinamiento formal de ningún tipo en esas áreas.

  2. Pensando que su proyecto no requiere un DBA porque todo eso es fácil / trivial.

  3. No se puede discernir correctamente entre el trabajo que se debe hacer en la base de datos y el trabajo que se debe hacer en la aplicación.

  4. No validar copias de seguridad, o no hacer copias de seguridad.

  5. Incrustar SQL raw en su código.

 4
Author: jonesy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-05 13:55:11

Aquí hay un enlace al video llamado 'Errores clásicos de Desarrollo de Bases de datos y cinco formas de superarlos ' por Scott Walz

 3
Author: Charles Faiga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-07 17:07:29

No tener una comprensión del modelo de concurrencia de bases de datos y cómo esto afecta el desarrollo. Es fácil agregar índices y modificar consultas después del hecho. Sin embargo, las aplicaciones diseñadas sin la debida consideración para los puntos de acceso, contención de recursos y el funcionamiento correcto (Suponiendo que lo que acaba de leer sigue siendo válido!) puede requerir cambios significativos dentro de la base de datos y el nivel de aplicación para corregirlos posteriormente.

 3
Author: Einstein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-23 17:33:10

No entiendo cómo funciona un DBMS bajo el capó.

No se puede conducir correctamente una palanca sin entender cómo funciona un embrague. Y no puede entender cómo usar una base de datos sin entender que realmente solo está escribiendo en un archivo en su disco duro.

Específicamente:

  1. ¿Sabes lo que es un Índice Agrupado? ¿Lo pensaste cuando diseñaste tu esquema?

  2. ¿Sabe utilizar correctamente los índices? Cuan ¿reutilizar un índice? ¿Sabes lo que es un Índice de Cobertura?

  3. Genial, tienes índices. ¿Qué tan grande es 1 fila en su índice? ¿Qué tan grande será el índice cuando se tiene una gran cantidad de datos? ¿Eso encajará fácilmente en la memoria? Si no lo hace es inútil como índice.

  4. ¿Alguna vez has usado EXPLAIN en MySQL? Gran. Ahora sé honesto contigo mismo: ¿Entendiste siquiera la mitad de lo que viste? No, probablemente no lo hiciste.

  5. ¿Entiendes la Caché de Consultas? ¿Sabes qué hace que una consulta no sea accesible?

  6. ¿Estás usando MyISAM? Si NECESITAS buscar texto completo, Myisam's es una mierda de todos modos. Usa Sphinx. Entonces cambia a Inno.

 3
Author: Shane H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-13 15:42:34
  1. Usando un OR para hacer actualizaciones masivas
  2. Seleccionar más datos de los necesarios. Una vez más, normalmente se hace cuando se usa un {
  3. Disparando sql en bucle.
  4. No tener buenos datos de prueba y notar la degradación del rendimiento solo en datos en vivo.
 3
Author: Sriram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-13 17:36:29