¿Por qué no debería tener una tabla para múltiples relaciones?

12

Suponiendo que tengo múltiples relaciones en mi base de datos, por ejemplo, Tienda, Empleado y Venta, y quiero conectar pares con una relación binaria simple. Personalmente, crearía tablas llamadas Employee_Store y Employee_Sale con una clave natural compuesta por las claves externas.

Ahora, mi colega insiste en crear una tabla para múltiples relaciones. Para el ejemplo anterior, podría haber una tabla llamada EmployeeLinks:

EmployeeLinks(
    IdLink int PK, 
    IdEmployee int FK null,
    IdStore int FK null,
    IdSale int FK null,
    LinkType int not null
)

Por favor, ayúdenme con buenas razones por las cuales esta no es una buena idea. Tengo mis propios argumentos, pero me gustaría mantenerlos en privado y escuchar sus opiniones imparciales.

EDITAR:

Inicialmente, la tabla anterior no tendría clave primaria (!). Debido a que las claves externas permiten nulo, una clave sustituta es la única opción.

Tomasz Pluskiewicz
fuente
3
¡Es como OTLT o EAV pero peor porque prolifera columnas en lugar de filas!
cuando

Respuestas:

13

¿Qué propone su colega como la clave principal para esta tabla de enlaces?
Las columnas de clave principal no pueden ser NULL, por supuesto: la tabla anterior tiene valores nulos.

No hay ningún identificador de fila natural (que es lo que es un PK) en el ejemplo anterior (una columna IDENTIDAD no es una clave principal), por lo tanto, falla en cualquier proceso de modelado. Ni siquiera piense en crear tablas sin algún modelo (ERD, ORM, IDEF1X, lo que sea)

También necesitaría restricciones CHECK para asegurarse de que no tiene enlaces de 3 vías.

Finalmente, te estás desviando hacia el 4to y 5to territorio de forma normal pero por razones equivocadas

No puedo encontrar ningún ejemplo en Internet: eso muestra lo estúpido que es esto

gbn
fuente
44
+1 paraI can't find any examples on the internet: that shows how stupid this is
JNK
Lo dejé más claro sobre la clave primaria. Además, aparentemente mi colega se ha encontrado con ese diseño antes, o eso me dijeron
Tomasz Pluskiewicz,
@Tomasz Pluskiewicz: ¡Una clave sustituta no es la clave principal! Se elige para complementar la clave natural en el momento de la implementación. Consulte dba.stackexchange.com/a/13779/630. Además, su colega debe mostrarnos un artículo autorizado que demuestre esta técnica. He visto montones de basura completas en mi tiempo, pero no las repito ...
GBN
12

La primera razón práctica que se me ocurre es el rendimiento.

En un modelo "tradicional", puede tener un índice único en Idemployee, Idstorecualquiera de los campos y obtener un excelente rendimiento en las búsquedas. También es fácil de mantener para insertos. Los índices únicos hacen que las combinaciones de fusión sean más frecuentes, lo que puede hacer que muchos JOINs sean increíblemente rápidos.

En su modelo de ejemplo, para obtener un rendimiento decente necesitará tener un índice de campo único en cada campo FK en la tabla como mínimo, idealmente un índice de cobertura en todas las combinaciones a las que se hará referencia, es decir:

  • Empleado / Tienda
  • Empleado / Venta

No estoy seguro de qué tipo de enlace es, pero si lo hace referencia, probablemente debería indexarse.

Estos índices deberán mantenerse para cada fila de la tabla, ya sea que el campo esté lleno o no. Puede agregar un filtro, pero eso también se volverá complicado con tantas combinaciones.

También complicará tu lógica. Deberá realizar una búsqueda en el Id. De empleado, buscar una fila con un valor de tienda vacío y actualizar; o, simplemente inserte una nueva fila para cada nuevo enlace, lo que frustra el propósito de consolidar los campos.

Básicamente, usará MÁS espacio en disco, tendrá MÁS índices para mantener y complicará su lógica esencialmente sin ningún motivo. El único "beneficio" es que hay menos mesas con las que lidiar.

JNK
fuente
La columna LinkType es algo así como un discriminador. Solo digo qué par se relaciona realmente una fila. Solo agrega al artilugio si me preguntas.
Tomasz Pluskiewicz
@TomaszPluskiewicz Creo que la mejor manera de mostrarle por qué apesta es crear un conjunto de datos de muestra con ambos tipos de tablas y ejecutar algunas consultas. Su modelo será mucho más lento que un modelo tradicional
JNK
4

Poner varias relaciones en una tabla puede ser útil si esas relaciones tienen los mismos atributos y / o si desea agregar datos sobre varias relaciones.

Es necesario si el usuario define los tipos de relaciones en tiempo de ejecución. Sin embargo, esto rara vez es realmente el caso.

En su ejemplo, las relaciones no comparten atributos, las relaciones incluso hacen referencia a dos tablas diferentes. Esto dificulta la aplicación de restricciones y el diseño también es menos intuitivo.

Solo elegiría ese diseño si crear tablas literalmente cuesta dinero.

JMD Coalesce
fuente