2010-04-24 20 views
5

Tengo que agregar funcionalidad a una aplicación existente y me encontré con una situación de datos que no estoy seguro de cómo modelar. Estoy restringido a la creación de nuevas tablas y códigos. Si necesito modificar la estructura existente, creo que mi cliente puede rechazar la propuesta ... aunque si es la única manera de hacerlo bien, esto es lo que tendré que hacer.Cómo modelar una relación mutuamente excluyente en SQL Server

Tengo una tabla de elementos que me permite vincular a cualquier número de tablas, y estas tablas pueden aumentar con el tiempo. El elemento solo puede vincularme a otra tabla, pero el registro en la otra tabla puede tener muchos elementos vinculados a ella.

Ejemplos de las tablas/entidades que se unen a son Person, Vehicle, Building, Office. Estas son todas tablas separadas.

Ejemplo de artículos son Pen, Stapler, Cushion, Tyre, A4 Paper, Plastic Bag, Poster, Decoration"

Por ejemplo, un Poster se pueden asignar a un Person o Office o Building. En el futuro, si agregan una tabla Conference Room, también se puede agregar a eso.

Mis pensamientos intital son:

Item 
{ 
    ID, 
    Name 
} 

LinkedItem 
{ 
    ItemID, 
    LinkedToTableName, 
    LinkedToID 
} 

El campo LinkedToTableName permitirá entonces me identifico a la tabla correcta establecer el vínculo en mi código.

No estoy demasiado feliz con esta solución, pero no puedo pensar en otra cosa. ¡Por favor ayuda! :)

Gracias!

+0

Sería de gran ayuda si han explicado un poco más sobre qué tipo de información almacena, y por qué; por ejemplo, ¿están los artículos entradas de blog, personas o artículos en un supermercado, etc.? ¿Qué representan las tablas de objetivos? Creo que su abstracción está rota, pero es casi imposible decir por qué, o sugerir un enfoque diferente sin conocer el problema que está tratando de resolver con él. –

+0

Gracias Rowland. Intenté agregar a mi pregunta. Vea Editado Q. Voy a editar nuevamente si todavía no hay suficiente información :) – littlechris

Respuesta

12

No es una buena práctica almacenar nombres de tabla como valores de columna. Este es un mal truco.

Hay dos formas estándar de hacer lo que está tratando de hacer. El primero se llama herencia de tabla única. Esto es fácil de entender por las herramientas ORM pero intercambia cierta normalización. La idea es que todas estas entidades (Person, Vehicle, lo que sea) estén almacenadas en la misma tabla, a menudo con varias columnas no utilizadas por entrada, junto con un campo discriminador que identifica de qué tipo es la entidad.

El campo discriminador suele ser un tipo entero, que se asigna a alguna enumeración en el código. También puede ser una clave externa para alguna tabla de búsqueda en su base de datos, identificando qué números corresponden a qué tipos (no nombres de tabla, solo descripciones).

La otra forma de hacer esto es herencia de múltiples tablas, que es mejor para su base de datos pero no tan fácil de mapear en el código. Para ello, tiene una tabla base que define algunas propiedades comunes de todos los objetos, quizás solo una identificación y un nombre, y todas sus tablas "específicas" (Person etc.) usan la ID base como clave externa única (generalmente también la clave principal).

En el primer caso, la exclusividad es implícita, ya que todas las entidades están en una tabla. En el segundo caso, la relación se encuentra entre Item y base ID de entidad, que también garantiza la exclusividad.

Tenga en cuenta que con la herencia de tablas múltiples, tiene un problema diferente: no puede garantizar que una base de datos use exactamente una tabla de herencia. Podría ser utilizado por varios, o no ser utilizado en absoluto. Es por eso que los esquemas de herencia de tablas múltiples generalmente también tienen una columna de discriminador, para identificar qué tabla es "esperada". Nuevamente, este discriminador no tiene un nombre de tabla, contiene un valor de búsqueda que el consumidor puede usar (o no) para determinar a qué otra tabla unirse.

La herencia de múltiples tablas es una coincidencia más cercana a su esquema actual, por lo que le recomiendo que vaya con eso a menos que necesite usar esto con Linq en SQL o en un ORM similar.

Consulte aquí para obtener un buen tutorial detallado: Implementing Table Inheritance in SQL Server.

0

su tabla de enlaces está bien.

el problema que tendrá es que tendrá que generar sql dinámico en tiempo de ejecución. el sql parametrizado típicamente no permite que los objetos en la lista FROM sean parámetros.

iyy desea evitar esto, es posible que pueda desnormalizar un poco - por ejemplo, creando una tabla para contener el ID (suponiendo que los identificadores son únicos en las otras tablas) y el type_id que representa de qué tabla es la fuente, y una descripción generada - por ejemplo el valor del nombre del registro inicial.

activaría la creación de esta lista desnormalizada cuando se modifique la información base, y podría usarla para consultas generalizadas, y luego recurrir a sus consultas dinámicas cuando sea necesario en tiempo de ejecución.

9

encontrar algo común a persona, vehículo, Edificio, Oficina. Por la falta de un término mejor, he usado Entidad. A continuación, implemente una relación de supertipo/subtipo entre la Entidad y sus subtipos. Tenga en cuenta que EntityID es PK y FK en todas las tablas de subtipos. Ahora, puede vincular la tabla de Artículo a la Entidad (propietario). En este modelo, un elemento puede pertenecer a una sola Entidad; uno Entidad puede tener (propio) muchos artículos.

model_mutually_exclusive_01

+1

¿Qué software usó para generar esa imagen er? – goat

+0

@chris, Visio 2007 –

Cuestiones relacionadas