Pregunta

Mi empleador, una pequeña empresa de suministros de oficina, está cambiando de proveedor y estoy revisando su contenido electrónico para encontrar un esquema de base de datos sólido;Nuestro esquema anterior fue elaborado prácticamente sin pensarlo en absoluto, y prácticamente condujo a un modelo de datos insoportable con información corrupta e inconsistente.

Los datos del nuevo proveedor son mucho mejores que los del antiguo, pero sus datos son lo que yo llamaría hipernormalizado.Por ejemplo, su estructura de categorías de productos tiene 5 niveles:Departamento Maestro, Departamento, Clase, Subclase, Bloque de Producto.Además, el contenido del bloque de productos tiene una descripción larga, términos de búsqueda y nombres de imágenes para los productos (la idea es que un bloque de productos contenga un producto y todas sus variaciones, p. ej.un bolígrafo en particular puede venir con tinta negra, azul o roja;Todos estos elementos son esencialmente lo mismo, por lo que se aplican a un solo bloque de productos).En los datos que me han proporcionado, esto se expresa como la tabla de productos (digo "tabla", pero es un archivo plano con los datos) que tiene una referencia al ID único del bloque de productos.

Estoy tratando de crear un esquema sólido que se adapte a los datos que me proporcionan, ya que necesitaré cargarlos relativamente pronto y los datos que me han proporcionado no parecen coincidir con el tipo de datos que me proporcionaron. proporcione una demostración en su sitio web de muestra (http://www.iteminfo.com).En cualquier caso, no estoy buscando reutilizar su estructura de presentación, por lo que es un punto discutible, pero estaba navegando por el sitio para obtener algunas ideas sobre cómo estructurar las cosas.

Lo que no estoy seguro es si debo mantener los datos en este formato o, por ejemplo, consolidar Maestro/Departamento/Clase/Subclase en una única tabla de "Categorías", utilizando una relación de autorreferencia y vincularla a un bloque de productos (el bloque de productos debe mantenerse separado ya que no es una "categoría" como tal, sino un grupo de productos relacionados para una categoría determinada).Actualmente, la tabla de bloques de productos hace referencia a la tabla de subclases, por lo que cambiaría a "category_id" si los consolido juntos.

Probablemente voy a crear una tienda de comercio electrónico haciendo uso de estos datos con Ruby on Rails (o ese es mi plan, en cualquier caso), así que estoy tratando de evitar que me enganchen más adelante o tener una aplicación inflada, tal vez Lo estoy pensando demasiado, pero prefiero prevenir que lamentar;Nuestros datos anteriores eran un verdadero desastre y le costaron a la empresa decenas de miles de dólares en ventas perdidas debido a datos inconsistentes e inexactos.También voy a romper un poco con las convenciones de Rails asegurándome de que mi base de datos sea sólida y aplique restricciones (también planeo hacerlo a nivel de aplicación), así que eso es algo que debo considerar también.

¿Cómo afrontarías una situación como ésta?Tenga en cuenta que ya tengo los datos que se van a cargar en archivos planos que imitan una estructura de tabla (tengo documentación que dice qué columnas son cuáles y qué referencias están configuradas);Estoy tratando de decidir si debo mantenerlos tan normalizados como están actualmente, o si debo buscar consolidarlos;Necesito ser consciente de cómo cada método afectará la forma en que programo el sitio usando Rails, ya que si consolido, habrá esencialmente 4 "niveles" de categorías en una sola tabla, pero eso definitivamente parece más manejable que tablas separadas para cada nivel, ya que aparte de la Subclase (que enlaza directamente con los bloques de productos) no hacer cualquier cosa excepto mostrar el siguiente nivel de categoría debajo de ellos.Siempre pierdo la "mejor" manera de manejar datos como este; conozco el dicho "Normalizar hasta que duela, luego desnormalizar hasta que funcione", pero nunca he tenido que implementarlo hasta ahora.

¿Fue útil?

Solución

Yo preferiría el enfoque "hypernormalized" sobre un modelo de datos denormal. La tabla de referencia que usted ha mencionado auto podría reducir el número de tablas de abajo y simplificar la vida en algunos aspectos, pero en general este tipo de relación puede ser difícil de tratar. consultas jerárquicas se convierten en un dolor, como lo hace el mapeo de un modelo de objetos a esto (si decide ir por ese camino).

Un par de adicional se une no va a doler y mantendrá la aplicación más fácil de mantener. A menos que el rendimiento se degrada debido al excesivo número de combinaciones, optaría a dejar las cosas como están. Como un beneficio adicional si cualquiera de estos niveles de tablas necesaria funcionalidad adicional agregada, usted no tenga problemas, ya que todos ellos se fusionaron en la tabla de auto referencia.

Otros consejos

Estoy totalmente en desacuerdo con las críticas sobre la estructura de las tablas de autorreferencia para jerarquías entre padres e hijos. La estructura de lista enlazada hace que la programación de interfaz de usuario y de negocios capa más fácil y más fácil de mantener en la mayoría de los casos, ya que las listas enlazadas y árboles son la forma natural de representar estos datos en lenguajes que las capas de interfaz de usuario y de negocios normalmente se implementan en.

La crítica acerca de la dificultad de mantener las restricciones de integridad de datos en estas estructuras es perfectamente válido, aunque la solución más sencilla es utilizar una mesa de cierre que aloja la más difícil de las restricciones de comprobación. La mesa de cierre es de fácil mantenimiento con disparadores.

La desventaja es un poco de complejidad adicional en la base de datos (tabla de cierre y disparadores) por mucho menos complejidad en el código de interfaz de usuario y la capa de negocio.

Si he entendido bien, usted quiere tomar sus mesas separadas y convertirlas en una jerarquía que se mantiene en una sola mesa con una referencia a sí misma FK.

Esto es generalmente un enfoque más flexible (por ejemplo, si desea agregar un quinto nivel), pero los modelos de datos SQL y relacionales no tienden a funcionar bien con las listas enlazadas de este tipo, incluso con la nueva sintaxis como MS SQL Servidores CTE. Es cierto, CTE hacen que sea mucho mejor, aunque.

Puede ser difícil y costoso para hacer cumplir las cosas, al igual que un producto debe estar siempre en el cuarto nivel de la jerarquía, etc.

Si usted decide hacerlo de esta manera, entonces definitivamente echa un vistazo a SQL de Joe Celko para Smarties , que creo que tiene una sección o dos en el modelado y el trabajo con jerarquías en SQL o mejor aún conseguir su libro que está dedicado al tema ( noreferrer árboles y jerarquías de Joe Celko en SQL para Smarties ).

Normalization implica integridad de los datos, es decir:. Cada forma normal reduce el número de situaciones en las que los datos no es coherente

Como regla general, denormalization tiene una meta de más rápido querying, pero se aumenta el espacio, el aumento de DML tiempo, y, por último pero no menos importante, el aumento de los esfuerzos para hacer que los datos consistentes.

Uno suele escribir código más rápido (escribe más rápido, no el código más rápido) y el código es menos propenso a errores si los datos son normalized.

autorreferenciados mesas casi siempre resultan ser mucho peor para consultar y realizar peor que tablas normalizadas. No lo haga. Puede parecer que le permite ser más elegante, pero no lo es y es una muy mala técnica de diseño de base de datos. Personalmente la estructura que usted describe suena muy bien para mí, no hypernormalized. Una base de datos correctamente normalizada (con limitaciones extranjeros clave, así como los valores predeterminados, disparadores (si es necesario para las reglas complejas) y restricciones de validación de datos) es también mucho más probable tener datos precisos y consistentes. Estoy de acuerdo en tener la base de datos hacer cumplir las reglas, es probable que esto es parte de la razón por la última aplicación tenía datos erróneos debido a que las reglas no se aplican en el lugar adecuado y la gente era capaz de llegar fácilmente a ellos. No es que la aplicación no debe comprobar también (no tiene sentido incluso el envío de una fecha no válida, por ejemplo, para la datbase a fallar en el inserto). Desde el rediseño youa, me gustaría poner más tiempo y esfuerzo en el diseño de las restricciones necesarias y la elección de los tipos de datos correctos (no almacenar fechas como datos de cadena, por ejemplo), que en tratar de hacer que la estructura normalizada perfectamente común un aspecto más elegante.

Me gustaría ponerlo en lo más cercano a su modelo como sea posible (y si es posible, me gustaría tener los archivos que coinciden con su esquema - no una versión aplanada). Si trae los datos directamente en su modelo, ¿qué ocurre si los datos que envían comienza a romper los supuestos en que la transformación de modelo de su aplicación interna?

Es mejor llevar sus datos en, ejecutar comprobaciones de validez y comprobar que las hipótesis no son violados. Entonces, si usted tiene un modelo específico de la aplicación, transformarla en que para un uso óptimo de su aplicación.

No desnormalizar. Tratando de acheive un buen diseño de esquema por desnormalización es como tratar de llegar a San Francisco por la conducción fuera de Nueva York. No te dice que camino por recorrer.

En su situación, usted quiere averiguar lo que le gustaría un esquema normalizado. Puede basar en gran medida de que el esquema de origen, pero hay que aprender lo que las dependencias funcionales (FD) en los datos son. Ni el esquema de origen ni los archivos aplanados están garantizados para revelar todos los FD en su caso.

Una vez que sepa lo que es un esquema normalizado se vería así, ahora tiene que encontrar la manera de diseñar un esquema que se adapte a sus necesidades. Es ese esquema es algo menos que totalmente normalizado, que así sea. Pero estar preparados para las dificultades en la programación de la transformación entre los datos de los archivos aplanados y los datos en el esquema desgined.

Usted ha dicho que los esquemas anteriores en su empresa cuestan millones debido a la inconsistencia y la inexactitud. Cuanto más normalizado su esquema, más protegido usted es de incoherencia interna. Esto deja libre para ser más vigilantes sobre la inexactitud. datos consistentes que es consistentemente equivocado puede ser tan engañosa como datos inconsistentes.

es su escaparate (o lo que sea que está construyendo, no está muy claro en eso) siempre va a ser a partir de datos de este distribuidor? puede ser que alguna vez cambiar de proveedor o añadir nuevos proveedores diferentes?

Si es así, el diseño de un esquema general de que cumple con sus necesidades, y el mapa de los datos de los proveedores a la misma. Personalmente prefiero sufrir las (muy pequeña) 'dolor' de una tabla de categorías (jerárquica) de autorreferencia que mantener cuatro (aparentemente semi-inútiles) niveles de variantes categoría y luego el próximo año se enteran de que han añadido un quinto, o introducido una línea de productos con sólo tres ...

Para mí, la verdadera pregunta es:? lo que se ajusta al modelo mejor

Es como comparar una tupla y una lista.

  1. Las tuplas son de un tamaño fijo y son heterogéneos -. Que son "hypernormalized"
  2. Las listas son un tamaño arbitrarty y son homogéneos.

Yo uso una tupla cuando necesito una tupla y una lista cuando necesito una lista; que fundamentalmente con fines de servidor diferente.

En este caso, como el estructura del producto ya está bien definido (y no asumen probable que cambie), entonces me gustaría seguir con el "enfoque Tupla". El poder real / uso de una lista (o patrón mesa recursiva) es cuando lo necesite a expanda a una profundidad arbitraria, por ejemplo para una lista de materiales o de un árbol genealógico.

Yo uso los dos enfoques en algunos de mi base de datos en función de la necesidad. Sin embargo, también existe el "costo oculto" de un patrón recurrente que es que no todos los ORM (no estoy seguro sobre AR) apoyar bien. Muchos DBs modernos tienen soporte para "unir-through" (Oracle), ID de jerarquía (SQL Server) u otros patrones recursivos. Otro enfoque es usar una jerarquía basada en conjunto (que generalmente depende de factores desencadenantes / mantenimiento). En cualquier caso, si el ORM utilizado no soporta bien las consultas recursivas, entonces puede ser el "costo" extra de utilizar el DB a la cuenta directamente - ya sea en términos de generación manual de consulta / vista o de gestión, tales como factores desencadenantes. Si no se utiliza un ORM cobarde, o simplemente utilizar un separador de la lógica como iBatis, entonces este problema se puede ni siquiera aplicar.

En cuanto a rendimiento, el nuevo Oracle o SQL Server (y otros probables) RDBMS, que debe ser muy comparable por lo que sería el menor de mis preocupaciones, pero echa un vistazo a las soluciones disponibles para su RDBMS y portabilidad preocupaciones.

Todo el que recomienda que no tiene una jerarquía introducido en la base de datos, teniendo en cuenta sólo la opción de tener una mesa de auto-referencia. Esta no es la única manera de modelar la jerarquía en la base de datos. Se puede usar un enfoque diferente, que le proporciona consulta más fácil y rápida sin necesidad de utilizar las consultas recursivas. Digamos que usted tiene un gran conjunto de nodos (categorías) en su jerarquía:

  

= Set 1 (nodo 1 Nodo2 Nodo3 ...)

Cualquier nodo en este conjunto también puede ser otro conjunto por sí mismo, que contiene otros nodos o conjuntos anidados:

  

nodo 1 = (Nodo2 Nodo3 = (Nodo4 Nodo5 = (Nodo6) Node7))

Ahora, ¿cómo podemos modelar eso? Vamos a tener cada nodo de tener dos atributos, que establecen los límites de los nodos que contiene:

  

Nodo = {Id: int, Min: int, Max: int}

Para modelar nuestra jerarquía, simplemente asignamos los valores mín / máx en consecuencia:

  

Nodo1 = {Id = 1, Min = 1, Max = 10}
  Nodo2 = {id = 2, Min = 2, Max = 2}
  Nodo3 = {Id = 3, Min = 3, Max = 9}
  Node4 = {id = 4, Min = 4, Max = 4}
  Nodo5 = {id = 5, Min = 5, Max = 7}
  Nodo6 = {id = 6, Min = 6, Max = 6}
  Node7 = {Id = 7, Min = 8, Max = 8}

Ahora, para consultar todos los nodos bajo el Conjunto / Nodo5:

  

Seleccione el n. * Desde nodos como n, como nodos s
  donde s.Id = 5 y s.Min

La única operación que consume muchos recursos sería si desea insertar un nuevo nodo, o mover algún nodo dentro de la jerarquía, como se verán afectados muchos registros, pero esto está muy bien, ya que la jerarquía misma no cambia muy a menudo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top