una - sql tabla muchos a muchos
Relación muchos a muchos: ¿utiliza una tabla asociativa o valores delimitados en una columna? (9)
Actualización 2009.04.24
El punto principal de mi pregunta no es la confusión del desarrollador y qué hacer al respecto.
El punto es entender cuándo los valores delimitados son la solución correcta.
He visto datos delimitados utilizados en bases de datos de productos comerciales (Ektron lol).
SQL Server incluso tiene un tipo de datos XML, por lo que podría usarse con el mismo propósito que los campos delimitados.
/ fin de actualización
La aplicación que estoy diseñando tiene algunas relaciones de muchos a muchos. En el pasado, a menudo usaba tablas asociativas para representarlas en la base de datos. Esto ha causado cierta confusión a los desarrolladores.
Aquí hay un ejemplo de estructura de DB:
Document
---------------
ID (PK)
Title
CategoryIDs (varchar(4000))
Category
------------
ID (PK)
Title
Hay una relación muchos a muchos entre Documento y Categoría.
En esta implementación, Document.CategoryIDs es una gran lista delimitada por tuberías de CategoryID.
Para mí, esto es malo porque requiere el uso de la coincidencia de subcadenas en las consultas, que no pueden hacer uso de los índices. Creo que esto será lento y no se escalará.
Con ese modelo, para obtener todos los Documentos para una Categoría, necesitaría algo como lo siguiente:
select * from documents where categoryids like ''%|'' + @targetCategoryId + ''|%''
Mi solución es crear una tabla asociativa de la siguiente manera:
Document_Category
-------------------------------
DocumentID (PK)
CategoryID (PK)
Esto es confuso para los desarrolladores. ¿Hay alguna solución alternativa elegante que me falta?
Supongo que habrá miles de filas en el documento. La categoría puede ser como 40 filas más o menos. La principal preocupación es el rendimiento de las consultas. ¿Estoy sobreingeniería?
¿Hay algún caso en el que se prefiera almacenar listas de ID en columnas de bases de datos en lugar de enviar los datos a una tabla asociativa?
Considere también que podemos necesitar crear relaciones de muchos a muchos entre los documentos. Esto sugeriría una tabla asociativa Document_Document. ¿Es ese el diseño preferido o es mejor almacenar los ID de documento asociados en una sola columna?
Gracias.
Esto es confuso para los desarrolladores.
Consigue mejores desarrolladores. Ese es el enfoque correcto.
Mi solución es crear una tabla asociativa de la siguiente manera: Esto es confuso para los desarrolladores
De Verdad? esta es la base de datos 101, si esto les resulta confuso, entonces tal vez necesiten alejarse de su código generado por el asistente y aprender la normalización básica de DB.
¡Lo que propones es la solución correcta!
Casi siempre es un gran error usar ID separados por comas.
RDBMS están diseñados para almacenar relaciones.
El ''esto es confuso para el diseño de los desarrolladores'' significa que tienes desarrolladores con poca educación. Es el mejor diseño de base de datos relacional; debe usarlo si es posible.
Si realmente desea utilizar la estructura de la lista, utilice un DBMS que los entienda. Ejemplos de tales bases de datos serían el DBMS U2 (Unidata, Universe), que son (o fueron, hace mucho tiempo) basados en Pick DBMS. Es probable que haya otros proveedores similares de DBMS.
El mapeo de muchos a muchos que está haciendo está bien y está normalizado. También permite agregar otros datos más adelante si es necesario. Por ejemplo, supongamos que desea agregar un momento en que la categoría se agregó al documento.
Sugeriría tener una clave primaria sustituta en la tabla document_category también. Y una restricción Única (documentid, categoryid) si tiene sentido hacerlo.
¿Por qué los desarrolladores están confundidos?
Este es el problema clásico de mapeo relacional de objetos. Los desarrolladores probablemente no son estúpidos, simplemente inexpertos o no están acostumbrados a hacer las cosas bien. Gritando "3NF!" una y otra vez no los convencerá de la manera correcta.
Sugiero que solicite a sus desarrolladores que le expliquen cómo obtendrían un recuento de documentos por categoría utilizando el enfoque delimitado por tuberías. Sería una pesadilla, mientras que la tabla de enlaces lo hace bastante simple.
La tabla Document_Category en su diseño es sin duda la forma correcta de abordar el problema. Si es posible, sugeriría que eduque a los desarrolladores en lugar de idear una solución subóptima (y obtener un impacto en el rendimiento, y no tener integridad referencial).
Sus otras opciones pueden depender de la base de datos que está utilizando. Por ejemplo, en SQL Server puede tener una columna XML que le permita almacenar su matriz en un esquema predefinido y luego hacer combinaciones basadas en el contenido de ese campo. Otros sistemas de bases de datos pueden tener algo similar.
La razón principal por la que mis desarrolladores prueban este enfoque de "valores delimitados por comas en una columna de base de datos" es que tienen la percepción de que agregar una nueva tabla para abordar la necesidad de valores múltiples llevará demasiado tiempo para agregar al modelo de datos y al base de datos.
La mayoría de ellos saben que su trabajo es malo por todo tipo de razones, pero eligen este método subóptimo porque simplemente pueden hacerlo . Pueden hacer esto y tal vez nunca ser atrapados, o quedarán atrapados mucho más tarde en el proyecto cuando sea demasiado costoso y arriesgado repararlo. ¿Por qué hacen esto? Porque su desempeño se mide únicamente en velocidad y no en calidad o cumplimiento.
También podría ser, como en uno de mis proyectos, que los desarrolladores tenían una tabla para poner los valores múltiples, pero tenían la impresión de que la duplicación de esos datos en la tabla principal aceleraría el rendimiento. Estaban equivocados y fueron llamados a participar.
Entonces, si bien necesita una respuesta sobre cómo manejar estos trucos costosos, arriesgados y dañinos para la confianza empresarial , también debe tratar de encontrar la razón por la cual los desarrolladores creen que tomar este curso de acción es mejor a corto y largo plazo. para el proyecto y la compañía. Luego arregle tanto la percepción como las estructuras de datos.
Sí, podría ser simplemente pereza, intento malicioso o despiste, pero estoy apostando a que la mayoría de las veces los desarrolladores hacen esto porque constantemente se les dice "simplemente hazlo". Nosotros, en el modelo de datos y en el diseño de la base de datos, necesitamos asegurarnos de no enviar el mensaje equivocado sobre cuán receptivos podemos ser a las solicitudes para cumplir con un requisito comercial para una nueva entidad / tabla / información.
También deberíamos ver que los datos necesitan ser monitoreados constantemente en la parte "tal como está construida" de nuestras arquitecturas de datos.
Personalmente, nunca autorizo el uso de valores delimitados por comas en una base de datos relacional porque en realidad es más rápido construir una nueva tabla que construir una rutina de análisis para crear, actualizar y administrar múltiples valores en una columna y tratar con todos los elementos anomalías introducidas porque a veces los datos también tienen comas incrustadas.
En pocas palabras, no haga valores delimitados por comas, pero descubra por qué los desarrolladores quieren hacerlo y solucione ese problema.
Su sugerencia es la solución elegante, potente y de mejores prácticas.
Como no creo que las otras respuestas dijeran lo siguiente con fuerza, lo haré.
Si sus desarrolladores 1) no pueden entender cómo modelar una relación de muchos a muchos en una base de datos relacional, y 2) insisten fuertemente en almacenar sus ID de categoría como datos de caracteres delimitados,
Entonces deberían perder inmediatamente todos los privilegios de diseño de la base de datos. Por lo menos, necesitan un profesional con experiencia para unirse a su equipo, que tiene la autoridad para evitar que hagan algo así de imprudente y puede proporcionarles la formación en diseño de bases de datos de la que carecen por completo.
Por último, no debe volver a referirse a ellos como "desarrolladores de bases de datos" hasta que estén correctamente actualizados, ya que esto es leve para aquellos de nosotros que en realidad somos desarrolladores y diseñadores competentes.
Espero que esta respuesta sea muy útil para ti.
Actualizar
El punto principal de mi pregunta no es la confusión del desarrollador y qué hacer al respecto.
El punto es entender cuándo los valores delimitados son la solución correcta.
Los valores delimitados son la solución incorrecta, excepto en casos extremadamente raros. Cuando los valores individuales alguna vez serán consultados / insertados / eliminados / actualizados, esto demuestra que fue una decisión equivocada, porque usted tiene que analizar y tocar todos los demás valores para trabajar con el deseado. Al hacer esto, estás violando la primera (¡) normal forma (esta frase debería sonar como un improperio increíblemente vil). Usar XML para hacer lo mismo también está mal. Almacenar valores delimitados o XML multivalor en una columna podría tener sentido cuando se trata como una "bolsa de propiedades" indivisible y opaca que NO es consultada por la base de datos pero que siempre se envía completa a otro consumidor (tal vez un servidor web o un Receptor EDI).
Esto me lleva de vuelta a mi comentario inicial. Los desarrolladores que piensan que violan la primera forma normal es una buena idea, los desarrolladores son muy inexpertos en mi libro.
Garantizaré que existen algunas implementaciones de almacenamiento de datos no relacionales bastante sofisticadas usando bolsas de propiedades de texto (como Facebook (?) Y otros sitios de usuarios multimillonarios que se ejecutan en miles de servidores). Bueno, cuando su base de datos, base de usuarios y transacciones por segundo sean lo suficientemente grandes como para necesitar eso, tendrá el dinero para desarrollarlo. Mientras tanto, sigue las mejores prácticas.