Version corta
Tengo que agregar un número fijo de propiedades adicionales a cada par en una unión de muchos a muchos existente. Saltando a los diagramas a continuación, ¿cuál de las Opciones 1-4 es la mejor manera, en términos de ventajas y desventajas, de lograr esto extendiendo el Caso Base? ¿O hay una alternativa mejor que no haya considerado aquí?
Versión más larga
Actualmente tengo dos tablas en una relación de muchos a muchos, a través de una tabla de unión intermedia. Ahora necesito agregar enlaces adicionales a propiedades que pertenecen al par de objetos existentes. Tengo un número fijo de estas propiedades para cada par, aunque una entrada en la tabla de propiedades puede aplicarse a varios pares (o incluso puede usarse varias veces para un par). Estoy tratando de determinar la mejor manera de hacer esto, y estoy teniendo problemas para resolver cómo pensar en la situación. Semánticamente parece que puedo describirlo como cualquiera de los siguientes igualmente bien:
- Un par vinculado a un conjunto de un número fijo de propiedades adicionales
- Un par vinculado a muchas propiedades adicionales
- Muchos (dos) objetos vinculados a un conjunto de propiedades
- Muchos objetos vinculados a muchas propiedades.
Ejemplo
Tengo dos tipos de objetos, X e Y, cada uno con ID únicos, y una tabla de enlace objx_objy
con columnas x_id
y y_id
, que juntas forman la clave principal para el enlace. Cada X se puede relacionar con muchas Y, y viceversa. Esta es la configuración de mi relación existente de muchos a muchos.
Caso base
Ahora, además, tengo un conjunto de propiedades definidas en otra tabla, y un conjunto de condiciones bajo las cuales un par dado (X, Y) debe tener la propiedad P. El número de condiciones es fijo, y lo mismo para todos los pares. Básicamente dicen "En la situación C1, el par (X1, Y1) tiene la propiedad P1", "En la situación C2, el par (X1, Y1) tiene la propiedad P2", y así sucesivamente, para tres situaciones / condiciones para cada par en la unión mesa.
Opción 1
En mi situación actual hay exactamente tres de estas condiciones, y no tengo ninguna razón para esperar que para aumentar, por lo que una posibilidad es añadir columnas c1_p_id
, c2_p_id
y c3_p_id
que featx_featy
, especificando para un determinado x_id
y y_id
, que la propiedad p_id
de uso en cada uno de los tres casos .
Esto no me parece una gran idea, porque complica el SQL para seleccionar todas las propiedades aplicadas a una característica, y no escala fácilmente a más condiciones. Sin embargo, impone el requisito de un cierto número de condiciones por par (X, Y). De hecho, es la única opción aquí que lo hace.
opcion 2
Cree una tabla de condiciones cond
y agregue la ID de condición a la clave principal de la tabla de unión.
Una desventaja de esto es que no especifica el número de condiciones para cada par. Otra es que cuando solo estoy considerando la relación inicial, con algo como
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Luego tengo que agregar una DISTINCT
cláusula para evitar entradas duplicadas. Esto parece haber perdido el hecho de que cada par debería existir solo una vez.
Opción 3
Cree una nueva 'ID de par' en la tabla de unión, y luego tenga una segunda tabla de enlaces entre la primera y las propiedades y condiciones.
Esto parece tener la menor cantidad de desventajas, además de la falta de imposición de un número fijo de condiciones para cada par. Sin embargo, ¿tiene sentido crear una nueva ID que identifique nada más que las ID existentes?
Opción 4 (3b)
Básicamente lo mismo que la Opción 3, pero sin la creación del campo ID adicional. Esto se logra poniendo ambas identificaciones originales en la nueva tabla de unión, por lo que contiene x_id
y y_id
campos, en lugar de xy_id
.
Una ventaja adicional de este formulario es que no altera las tablas existentes (aunque todavía no están en producción). Sin embargo, básicamente duplica una tabla completa varias veces (o se siente así, de todos modos), por lo que tampoco parece ideal.
Resumen
Mi sensación es que las opciones 3 y 4 son lo suficientemente similares como para que yo pueda elegir cualquiera de ellas. Probablemente ya lo hubiera hecho si no fuera por el requisito de un número pequeño y fijo de enlaces a propiedades, lo que hace que la Opción 1 parezca más razonable de lo que sería de otra manera. Según algunas pruebas muy limitadas, agregar una DISTINCT
cláusula a mis consultas no parece afectar el rendimiento en esta situación, pero no estoy seguro de que la Opción 2 represente la situación tan bien como a las demás, debido a la duplicación inherente causada por la colocación los mismos pares (X, Y) en varias filas de la tabla de enlaces.
¿Es una de estas opciones mi mejor camino a seguir, o hay otra estructura que debería considerar?
DISTINCT
cláusula, que estaba pensando en una consulta como la que al final del # 2, que une x
y y
a través de xyc
, pero no se refiere a c
... Así que si he (x_id, y_id, c_id)
limitado UNIQUE
con filas (1,1,1)
y (1,1,2)
, a continuación SELECT x.id, y.id FROM x JOIN xyc JOIN y
, voy a volver dos idénticos filas (1,1)
, y (1,1)
.