sql - primary - Múltiples llaves foráneas a una sola columna
llaves primarias y foraneas en sql server (7)
Estoy definiendo una base de datos para un sistema de cliente / orden donde hay dos tipos muy distintos de clientes. Porque son tan diferentes tener una sola tabla de clientes sería muy feo (estaría lleno de columnas nulas ya que son inútiles para un tipo).
Sin embargo, sus pedidos están en el mismo formato. ¿Es posible tener una columna CustomerId
en mi tabla de pedidos que tenga una clave externa para ambos tipos de clientes? Lo configuré en el servidor SQL y no me ha dado ningún problema para crear las relaciones, pero todavía tengo que intentar insertar cualquier dato.
Además, estoy planeando usar nHibernate como ORM, ¿podría haber algún problema al hacer las relaciones de esta manera?
- Cree una tabla de "clientes" que incluya todas las columnas que tengan los mismos datos para ambos tipos de clientes.
- Que crear la tabla "customer_a" y "customer_b"
Use "customer_id" de la tabla "consumer" como clave externa en "customer_a" y "customer_b"
customer | --------------------------------- | | cusomter_a customer_b
Como se señaló, si la clave es, por ejemplo, 12345, ¿cómo sabría en qué tabla buscarla? Supongo que podría hacer algo para asegurarse de que los valores clave de las dos tablas nunca se superpongan, pero es demasiado desagradable y doloroso de contemplar. Podría tener un segundo campo que indique el tipo de cliente que es. Pero si va a tener dos campos, ¿por qué no tener un campo para la identificación de tipo de cliente 1 y otra para la identificación de tipo de cliente 2?
Sin saber más acerca de su aplicación, mi primer pensamiento es que realmente debería tener una tabla general de clientes con los datos que son comunes a ambos, y luego tener dos tablas adicionales con los datos específicos para cada tipo de cliente. Creo que debe haber una gran cantidad de datos comunes a los dos, cosas básicas como el nombre y la dirección y el número de cliente como mínimo, y repetir las columnas en las tablas es una gran diferencia. Las tablas adicionales podrían referirse nuevamente a la tabla base. Como hay una sola clave para la tabla base, la cuestión de las claves externas que tienen que saber a qué tabla referirse se evapora.
Dos tipos distintos de clientes son casos clásicos de tipos y subtipos o, si lo prefiere, clases y subclases. Here hay una respuesta de otra pregunta.
Básicamente, la técnica de herencia de la tabla de clases es como la respuesta de Arnand. El uso de la técnica de clave primaria compartida es lo que le permite solucionar los problemas creados por dos tipos de clave externa en una columna. La clave externa será identificación del cliente. Eso identificará una fila en la tabla de clientes, y también una fila en el tipo apropiado de tabla de tipo de cliente, según sea el caso.
Heredé una base de datos de SQL Server donde se realizó esto (una sola columna utilizada en cuatro relaciones de claves externas con cuatro tablas no relacionadas), así que sí, es posible. Mi predecesor se ha ido, sin embargo, así que no puedo preguntar por qué pensó que era una buena idea.
Utilizó una columna GUID (tipo "uniqueidentifier") para evitar el problema de ambigüedad, y desactivó la restricción de las claves externas, ya que está garantizado que solo una coincidirá. Pero puedo pensar en muchas razones por las que no deberías, y no he pensado en ninguna razón por la que deberías.
El suyo suena como el problema clásico de "especialización", generalmente resuelto al crear una tabla padre con los datos compartidos del cliente, luego dos tablas secundarias que contienen los datos únicos para cada clase de cliente. Su clave externa estaría entonces en contra de la tabla de clientes principales, y su determinación de qué tipo de cliente se basaría en qué tabla secundaria tenía una entrada coincidente.
No, no puede tener un solo campo como clave externa para dos tablas diferentes. ¿Cómo dirías dónde buscar la llave?
Al menos necesitaría un campo que indique qué tipo de usuario es o dos claves externas separadas.
También puede colocar la información que es común para todos los usuarios en una tabla y tener tablas separadas para la información que es específica para los tipos de usuario, para que tenga una sola tabla con el ID de usuario como clave principal.
Puede crear una clave externa que haga referencia a varias tablas. Esta característica es para permitir la partición vertical de su tabla y mantener la integridad referencial. En su caso, sin embargo, esto no es aplicable.
Su mejor opción sería tener una tabla CustomerType con posibles columnas: CustomerTypeID, CustomerID, donde CustomerID es PK y luego remitir su tabla OrderID a CustomerID.
Raj
Una clave externa solo puede hacer referencia a una sola clave principal, por lo que no. Sin embargo, puede usar una tabla puente:
CustomerA <---- CustomerA_Orders ----> Order
CustomerB <---- CustomerB_Orders ----> Order
Entonces Order no tiene una clave foránea; si esto es deseable, sin embargo ...