2012-05-03 12 views
8

Estoy trabajando con la nueva versión de una aplicación de terceros. En esta versión, la estructura de la base de datos cambia, dicen "para mejorar el rendimiento".¿Es este un diseño de base de datos "correcto"?

La versión anterior de la base de datos tenía una estructura general de esta manera:

TABLE ENTITY 
(
    ENTITY_ID, 
    STANDARD_PROPERTY_1, 
    STANDARD_PROPERTY_2, 
    STANDARD_PROPERTY_3, 
    ... 
) 

TABLE ENTITY_PROPERTIES 
(
    ENTITY_ID, 
    PROPERTY_KEY, 
    PROPERTY_VALUE 
) 

así que tuvimos una mesa principal con los campos para las propiedades básicas y una tabla separada para administrar las propiedades personalizadas añadidas por el usuario.

La nueva versión de la base de datos insted tiene una estructura como esta:

TABLE ENTITY 
(
    ENTITY_ID, 
    STANDARD_PROPERTY_1, 
    STANDARD_PROPERTY_2, 
    STANDARD_PROPERTY_3, 
    ... 
) 

TABLE ENTITY_PROPERTIES_n 
(
    ENTITY_ID_n, 
    CUSTOM_PROPERTY_1, 
    CUSTOM_PROPERTY_2, 
    CUSTOM_PROPERTY_3, 
    ... 
) 
lo tanto, ahora cuando el usuario añada una propiedad personalizada, se añade una nueva columna a la ENTITY_PROPERTY tabla actual hasta que el número máximo

de las columnas (administrado por la aplicación) se alcanza, luego se crea una nueva tabla.

Entonces, mi pregunta es: ¿Es esta una forma correcta de diseñar una estructura de base de datos? ¿Es esta la única forma de "aumentar el rendimiento"? La antigua estructura requería muchos join o sub-select, pero esta estructura no me parece muy inteligente (o incluso correcta) ...

Respuesta

10

He visto esto antes en el asumido (a menudo no comprobado) "gasto" de unir - básicamente está convirtiendo una tabla de datos de filas en una tabla de columnas pesadas. Se toparon con su propia limitación, como implica, creando nuevas tablas cuando se agoten las columnas.

I completamente no estoy de acuerdo con él.

Personalmente, me quedaría con la estructura anterior y volver a evaluar los problemas de rendimiento. Eso no quiere decir que la forma anterior es la correcta, es marginalmente mejor que la "mejora" en mi opinión, y elimina la necesidad de realizar una reingeniería a gran escala de las tablas de la base de datos y el código DAL.

Estas tablas me parecen bastante estáticas ... el almacenamiento en memoria caché sería una mejora del rendimiento aún mejor sin mutilar la base de datos y una que buscaría hacer primero. Realice la búsqueda "costosa" una vez y guárdela en algún lugar, luego olvídese de sus problemas (tenga en cuenta que no me refiero a la necesidad de administrar el caché, pero los datos estáticos son los más fáciles de administrar).

O esperar a que el día se encuentra con el número máximo de tablas por base de datos :-)

Otros han sugerido completamente diferentes tiendas. Esta es una posibilidad perfectamente viable y, si no tuviera una estructura de base de datos existente, la estaría considerando también. Dicho esto, no veo ninguna razón por la cual esta estructura no pueda encajar en un RDBMS. Lo he visto hecho en casi todas las aplicaciones a gran escala en las que he trabajado.Curiosamente, todos tomaron una ruta similar y todas fueron en su mayoría implementaciones "exitosas".

+2

"aguarde el día en que se encuentre con el número máximo de tablas por base de datos" ... pero puede crear una nueva base de datos ;-) +1 para ver la arquitectura general y desearía dar otro +1 por costo en cascada de la reingeniería DAL, pruebas unitarias, ... –

0

Creo que crear una nueva tabla para cada entidad para almacenar propiedades es un mal diseño ya que podría terminar acumulando la base de datos con tablas. El único profesional en aplicar el segundo método sería que no está atravesando todas las filas redundantes que no se aplican a la entidad seleccionada. Sin embargo, usar índices en su base de datos en la tabla original ENTITY_PROPERTIES podría ayudar mucho con el rendimiento.

Personalmente me quedaría con su diseño inicial, aplicar índices y dejar que el motor de la base de datos determine los mejores métodos para seleccionar los datos en lugar de separar cada propiedad de entidad en una nueva tabla.

1


Según lo que sé de las bases de datos (pero ciertamente no soy el más experimentado), parece una mala idea hacerlo en su base de datos. Si ya sabe cuántas propiedades personalizadas puede tener un usuario, le diría que es mejor que configure el número de columnas de la tabla con ese valor.

Por otra parte, no soy un experto, pero hacer nuevas columnas sobre la marcha no es el tipo de bases de datos de operaciones como. Te va a traer más problemas que nada.

Si yo fuera usted, corregiría el número de propiedades personalizadas, o me quedaré con el sistema anterior.

+0

experimentado, no experimentado (¿hablante?: o) –

+0

Francés ^^ cerrar en ese caso hehehe –

5

No, no lo es. Es terrible.

hasta que se alcanza el número máximo de columna (manejado por la aplicación), luego se crea una nueva tabla.

Esta frase lo dice todo. Bajo ninguna circunstancia debe una aplicación crear dinámicamente tablas. El enfoque "anterior" tampoco es ideal, pero ya que tiene el requisito de permitir a los usuarios agregar propiedades personalizadas, tiene que ser así.

Considera:

  • se pierde toda seguridad de tipos como usted tiene que almacenar todos los valores en la columna "valor_propiedad"
  • Dependiendo de sus usuarios, que podría tener que cambiar el esquema de antemano y luego Permitirles ejecutar algún tipo de trabajo por lotes de actualización de base de datos, por lo que al menos todas las propiedades se declararían en el tipo de datos correcto. Además, podría perder el elemento entity_id/key.
  • Mira esto: http://en.wikipedia.org/wiki/Inner-platform_effect. Esto ciertamente huele a
  • Tal vez un RDBMS no es lo correcto para su aplicación. Considere usar un almacén basado en clave/valor como MongoDB u otra base de datos NoSQL. (http://nosql-database.org/)
+0

Curiosamente en el caso de MS-SQL, conoce el tipo dentro un campo "sin tipo" por lo que cuando lee contra la tabla del código, de todos modos le dan buenos tipos. Por lo tanto, no necesariamente pierde toda la seguridad, al menos desde la perspectiva del código. –

+1

+1 por sugerir una tienda más apropiada para este tipo de datos. SQL no es el almacenamiento total de datos (ni tampoco es NoSQL ... cada uno tiene un conjunto de fortalezas y debilidades). Sin embargo, considere el costo para cambiar DAL vs. beneficio de rendimiento para una aplicación existente. –

0

No hay manera "correcta" para diseñar una base de datos - No estoy al tanto de un conjunto universalmente reconocido de normas distintas de la famosa teoría "normal form"; muchos diseños de bases de datos ignoran este estándar por motivos de rendimiento.

Sin embargo, existen formas de evaluar los diseños de la base de datos: rendimiento, facilidad de mantenimiento, inteligibilidad, etc. Con bastante frecuencia, tiene que comerciar entre sí; eso es lo que parece estar haciendo su cambio: mantener la capacidad de mantenimiento y la inteligibilidad frente al rendimiento.

Por lo tanto, la mejor manera de averiguar si ese fue un buen intercambio es ver si las ganancias de rendimiento se han materializado. La mejor manera de descubrirlo es crear el esquema propuesto, cargarlo con un conjunto de datos representativo y escribir consultas que necesitará ejecutar en producción.

supongo que el nuevo diseño no será perceptiblemente más rápido para consultas como "encontrar STANDARD_PROPERTY_1 de entidad en la STANDARD_PROPERTY_1 = 'banana'.

supongo que no será perceptiblemente más rápido cuando se recuperan todas las propiedades para una entidad determinada, de hecho podría ser un poco más lento, porque en lugar de unirse a ENTITY_PROPERTIES, el nuevo diseño requiere combinaciones en varias tablas.Volverá resultados "dispersos"; presumiblemente, no todas las entidades tendrán valores en las columnas de propiedad en todas las tablas ENTITY_PROPERTIES_n.

Donde el nuevo diseño puede ser significativamente más rápido es cuando necesita una cláusula compuesta donde en propiedades personalizadas. Por ejemplo, encontrar una entidad donde la propiedad personalizada 1 es verdadera, la propiedad personalizada 2 es banana y la propiedad personalizada 3 no está en ('kylie', 'mininocardos', 'jirafa') es e` (probablemente) más rápido cuando se puede especifique columnas en las tablas ENTITY_PROPERTIES_n en lugar de filas en la tabla ENTITY_PROPERTIES. Probablemente.

En cuanto a la capacidad de mantenimiento - yuck. Su código de acceso a la base de datos ahora necesita ser mucho más inteligente, saber qué tabla contiene qué propiedad y cuántas columnas son demasiadas. La probabilidad de errores de entretenimiento es alta: hay más partes móviles, y no puedo pensar en pruebas de unidades obvias para asegurarme de que la lógica de acceso a la base de datos está funcionando.

La inteligibilidad es otra preocupación: esta solución no está en la caja de herramientas de la mayoría de los desarrolladores, no es un patrón estándar de la industria. La solución anterior es bastante conocida, comúnmente conocida como "entidad-valor-atributo". Esto se convierte en un problema importante en proyectos de larga duración en los que no se puede garantizar que el equipo de desarrollo original se quede.

Cuestiones relacionadas