tipos tablas tabla solucion rompimiento relaciones relacion muchos intermedia entre crear sql tsql database-design

sql - tablas - Diseño de relación de muchos a muchos-Diseño de tabla de intersección



tabla de rompimiento sql (11)

Me pregunto qué es un mejor diseño para la mesa de intersección para una relación de muchos a muchos.

Los dos enfoques que estoy considerando son:

CREATE TABLE SomeIntersection ( IntersectionId UNIQUEIDENTIFIER PRIMARY KEY, TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL, TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL, CONSTRAINT IX_Intersection UNIQUE(TableAId, TableBId ) )

o

CREATE TABLE SomeIntersection ( TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL, TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL, PRIMARY KEY(TableAId, TableBId ) )

¿Hay beneficios para uno sobre el otro?
EDIT 2: **** Tenga en cuenta: planeo usar Entity Framework para proporcionar una API para la base de datos. Con eso en mente, ¿una solución funciona mejor con EF que la otra?

EDITAR: En una nota relacionada, para una tabla de intersección que las dos columnas hacen referencia a la misma tabla (ejemplo a continuación), ¿hay alguna manera de hacer que los dos campos difieran en un registro?

CREATE TABLE SomeIntersection ( ParentRecord INT REFERENCES TableA NOT NULL, ChildRecord INT REFERENCES TableA NOT NULL, PRIMARY KEY(TableAId, TableBId ) )

Quiero evitar lo siguiente

ParentRecord ChildRecord ================================= 1 1 --Cyclical reference!


Dado que la combinación TableAId-TableBId es única y que la tabla se utiliza únicamente para implementar una relación de varios a varios, iría con la segunda opción. Desde un punto de vista puramente lógico, la primera aplicación se reduce a la segunda. Desde una perspectiva estructural, sus bases de datos necesitan mantener tanto una clave / índice principal como una restricción en la primera implementación, mientras que en el segundo solo necesita maitainizar la clave / índice principal.


Desde la perspectiva de un desarrollador, prefiero el primero. Es más fácil escribir y probar cuando se trata de ello.

No necesito verificar dos claves para recuperar un registro único.


El segundo es mejor. Limita la caja de conexiones (cuadro de intersección) a no tener más de una apariencia del mismo par. Si no hay otras columnas en la caja de conexiones, no hará búsquedas de esta tabla de todos modos, excepto por medio de las dos claves externas.


Es un tema de debate. Prefiero el primer formulario porque considero que es mejor poder buscar la fila de asignación en un único valor, y me gusta aplicar una consistencia quizás absurda de tener una clave primaria de columna única disponible en todas las tablas sin falta. Otros piensan que tener esa columna es una pérdida estúpida de espacio.

Nos reunimos durante unas cuantas rondas de boxeo en un bar de Nueva Jersey cada dos meses.


La segunda versión es la mejor para mí, evita la creación de un índice adicional.


Lo que estás construyendo se llama una "Intersección".

Tengo un recuerdo muy claro de mi profesor de base de datos en la escuela diciendo que una relación de intersección es casi siempre una entidad en sí misma, por lo que normalmente vale la pena asignar espacio para ello como tal. Esto indicaría que el primero es más "correcto".

Dicho esto, yo personalmente prefiero el último. Realmente se trata de si alguna vez recuperarás uno de estos registros directamente o si solo usarás la tabla cuando te unas a una de las tablas originales.


Respondiendo tu segunda pregunta ...

Solo necesita agregar una restricción de verificación, como esta:

CREATE TABLE SomeIntersection ( ParentRecord INT REFERENCES TableA NOT NULL, ChildRecord INT REFERENCES TableA NOT NULL, PRIMARY KEY(TableAId, TableBId), CHECK (ParentRecord <> ChildRecord) )


Si no tiene ningún campo adicional en la tabla de intersección, realmente no necesita una identificación propia, y agregar uno no agrega ningún beneficio. Sin embargo, si va a incluir otros campos en esa tabla, y en muchos casos lo hará, debería tener su propia identificación como clave principal.

Regla de oro, por supuesto, pero ahí lo tienes.


Use la versión 1 si su "intersección" en realidad ES una entidad en sí misma, lo que significa:

  • tiene propiedades adicionales
  • puedes buscar esos objetos (y no navegar una relación)

Versión de usuario -2 si se trata de una tabla de relaciones puramente NM. En ese caso, también asegúrese de que:

  • tiene su PK (CLUSTERED) con la primera columna relacionada con la tabla de su búsqueda más a menudo: por ejemplo, si sus tablas son Person-Address, entonces asumiría que buscaría todas las direcciones de una persona con más frecuencia luego para todas las personas en esta dirección. Por lo tanto, debe poner su PK para incluir PersonID primero
  • aún puede tener otro identificador ÚNICO de una columna, pero solo:

    1. o bien no lo convierten en un PK
    2. o conviértalo en PK, pero especifique NON CLUSTERED, para que pueda usar CLUSTERED para el índice UNIQUE que cubre dos columnas de referencia
    3. a menos que use GUID según su diseño, puede adherirse al tipo de columna INT IDENTITY

En ambos casos, es posible que desee crear otro ÍNDICE que cubra las 2 columnas, pero en otro orden, si busca con frecuencia desde el otro lado de la relación.


si elige el primero, solo use una IDENTIDAD en el PK, no necesita desperdiciar el espacio (disco y caché de memoria) con un IDENTIFICADOR UNICO.


Beneficios del primero:

La capacidad de buscar la tabla de unión en un solo valor. Esto hace que algunas operaciones de búsqueda sean más simples en el lado del cliente.

Algunos ORM (NHibernate) también requieren identificadores en cada entidad para que la persistencia funcione correctamente.

Beneficios del segundo:

Modelo de datos más simple, sin necesidad de crear el índice adicional.

Se requiere menos memoria.