upper una separar quitar left extraer ejemplos caracteres cadena sql-server associations normalization polymorphic-associations

una - ¿Cuál es la mejor manera de implementar la Asociación Polimórfica en SQL Server?



substring sql (9)

El enfoque 1 con múltiples columnas de claves externas es el mejor. Porque de esa manera puede tener conexiones predefinidas con otras tablas y eso hace que sea mucho más fácil para los scripts seleccionar, insertar y actualizar datos.

Tengo toneladas de instancias en las que necesito implementar algún tipo de Asociación Polimórfica en mi base de datos. Siempre pierdo un montón de tiempo pensando en todas las opciones una vez más. Aquí están los 3 que se me ocurren. Espero que haya una mejor práctica para SQL Server.

Aquí está el enfoque de múltiples columnas

Aquí está el enfoque sin clave extranjera

Y aquí está el enfoque de la mesa base.


El enfoque 1 es mejor, pero la asociación entre algo y object1, object2, object3 debería ser uno a uno.

Me refiero a que FK en la tabla secundaria (objeto1, objeto2, objeto3) debe ser una clave única no nula o Clave primaria para la tabla secundaria.

object1, object2, object3 puede tener valor de objeto Polimórfico.


He usado lo que supongo que llamarías el enfoque de la tabla base. Por ejemplo, tenía tablas para nombres, direcciones y números de teléfono, cada uno con una identidad como PK. Luego tuve una entidad de tabla de entidad principal (ID de entidad) y una tabla de enlace: attribute (entityKey, attributeType, attributeKey), en donde la attributeKey podría apuntar a cualquiera de las tres primeras tablas, dependiendo del attributeType.

Algunas ventajas: permite tantos nombres, direcciones y números de teléfono por entidad como queramos, fácil de agregar nuevos tipos de atributos, normalización extrema, fácil de explotar atributos comunes (es decir, identificar personas duplicadas), algunas otras ventajas de seguridad específicas de la empresa

Desventajas: las consultas bastante complejas para crear conjuntos de resultados simples dificultaron la administración (es decir, tuve problemas para contratar personas con suficientes t-SQL Tops); El rendimiento es óptimo para casos de uso MUY específicos en lugar de generales; la optimización de consultas puede ser complicada

Habiendo vivido con esta estructura durante varios años con una carrera mucho más larga, dudaría en volver a usarla a menos que tuviera las mismas restricciones de lógica de negocios y patrones de acceso extraños. Para uso general, recomiendo encarecidamente que las tablas escritas hagan referencia directamente a sus entidades. Es decir, Entidad (ID de entidad), Nombre (ID de nombre, ID de entidad, Nombre), Teléfono (ID de teléfono, ID de entidad, Teléfono), Correo electrónico (ID de correo electrónico, ID de entidad, Correo electrónico). Tendrá alguna repetición de datos y algunas columnas comunes, pero será mucho más fácil de programar y optimizar.


He utilizado el primer enfoque. Bajo cargas extremas, la tabla "Algo" se convierte en un cuello de botella.

Tomé el enfoque de tener una plantilla DDL para mis diferentes objetos con las especializaciones de atributos que se adjuntan al final de la definición de la tabla.

En el nivel de base de datos, si realmente necesitaba representar mis diferentes clases como un juego de registros de "Algo", pongo una vista por encima de ellas.

SELECT "Something" fields FROM object1 UNION ALL SELECT "Something" fields FROM object2 UNION ALL SELECT "Something" fields FROM object3

El desafío es cómo asignar una clave principal que no esté en conflicto, dado que tiene tres objetos independientes. Normalmente, las personas usan un UUID / GUID; sin embargo, en mi caso, la clave era un entero de 64 bits generado en una aplicación basada en un tiempo y una máquina para evitar choques.

Si adopta este enfoque, evitará el problema del objeto "Algo" que provoca el bloqueo / bloqueo.

Si desea alterar el objeto "Algo", esto puede ser incómodo ahora que tiene tres objetos independientes, todos los cuales requerirán que se altere su estructura.

Así que para resumir. La Opción Uno funcionará bien en la mayoría de los casos, sin embargo, bajo una carga muy pesada, es posible que observe bloqueos de bloqueo que requieren la división del diseño.


Los dos enfoques más comunes son Tabla por clase (es decir, una tabla para la clase base y otra tabla para cada subclase que contiene las columnas adicionales necesarias para describir la subclase) y Tabla por jerarquía (es decir, todas las columnas en una tabla, con una o más) Columnas para permitir la discriminación de subclases. Cuál es el mejor enfoque realmente depende de los detalles de su aplicación y estrategia de acceso a datos.

Tendría una tabla por clase en su primer ejemplo invirtiendo la dirección del FK y eliminando los identificadores adicionales del padre. Los otros dos son esencialmente variantes de tabla por clase.


No existe una mejor práctica única o universal para lograr esto. Todo depende del tipo de acceso que necesitarán las aplicaciones.

Mi consejo sería hacer un resumen del tipo de acceso esperado a estas tablas:

  1. ¿Utilizará una capa OR, procedimientos almacenados o SQL dinámico?
  2. ¿Qué cantidad de registros esperas?
  3. ¿Cuál es el nivel de diferencia entre las diferentes subclases? Cuantas columnas
  4. ¿Harás agregaciones u otros informes complejos?
  5. ¿Tendrá un almacén de datos para informar o no?
  6. ¿Necesitará a menudo procesar registros de diferentes subclases en un lote? ...

Basándonos en las respuestas a estas preguntas, podríamos encontrar una solución adecuada.

Una posibilidad adicional para almacenar propiedades específicas de las subclases es usar una tabla con pares Nombre / valor. Este enfoque puede ser particularmente útil si hay un gran número de subclases diferentes o cuando los campos específicos en las subclases se usan con poca frecuencia.


Según mi opinión, su primer tipo de enfoque es la mejor manera de definir los datos, así como sus clases, pero como todos los datos primarios deben estar disponibles para el niño.

Para que pueda comprobar su requerimiento y definir la base de datos.


Usé la siguiente solución para resolver un problema similar:

Diseño basado en Many-Many: Aunque la relación es 1-Many entre un ObjectN y Something, es equivalente a la relación Many-Many con una modificación de la PK de la tabla de relaciones.

Primero creo una tabla de relaciones entre un ObjectN y algo por objeto y luego uso la columna Something_ID como PK.

Este es el DDL de la relación Something-Object1 que es igual para Object2 y Object3 también:

CREATE TABLE Something ( ID INT PRIMARY KEY, ..... ) CREATE TABLE Object1 ( ID INT PRIMARY KEY, ..... ) CREATE TABLE Something_Object1 ( Something_ID INT PRIMARY KEY, Object1_ID INT NOT NULL, ...... FOREIGN KEY (Something_ID) REFERENCES Something(ID), FOREIGN KEY (Object1_ID) REFERENCES Object1(ID) )

Más detalles y ejemplos de otras opciones posibles en este boleto de multiple-foreign-keys-for-the-same-business-rule


Otro nombre común para este modelo es el modelo de supertipo, donde uno tiene un conjunto básico de atributos que se pueden expandir mediante la unión a otra entidad. En los libros de Oracle, se enseña como un modelo lógico y una implementación física. El modelo sin las relaciones permitiría que los datos se conviertan en estados inválidos y que los registros huérfanos validarían fuertemente las necesidades antes de seleccionar ese modelo. El modelo superior con la relación almacenada en el objeto base causaría nulos, y en el caso de que los campos se excluyeran mutuamente, siempre tendría un nulo. El diagrama inferior donde se aplica la clave en el objeto secundario eliminaría los nulos, pero también haría que la dependencia sea una dependencia suave y permitiría huérfanos si no se aplicaba la conexión en cascada. Creo que evaluar esos rasgos te ayudará a seleccionar el modelo que mejor se adapte. He usado los tres en el pasado.