2009-07-27 12 views
21

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).Llaves externas múltiples a una sola columna

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 he configurado en el servidor SQL y no me ha dado ningún problema creando relaciones, pero aún no he intentado insertar ningún dato.

Además, estoy planeando utilizar nHibernate como ORM, ¿podría haber algún problema al hacer las relaciones de esta manera?

Respuesta

19

No, no puede tener un solo campo como una clave foránea 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 podría poner 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 identificación de usuario como clave principal.

+1

acuerdo. La normalización es la clave aquí. – jva

+1

@Guffa: -1 porque "No, no puede tener un solo campo como clave externa para dos tablas diferentes": esta afirmación es incorrecta (al menos en el servidor sql 2005). Darle un giro. – Liao

+2

@Liao: no creo que comprenda la situación ... Si, por ejemplo, tiene el valor de la clave foránea 42, ¿cómo sabría si es la clave de la tabla A o de la tabla B? – Guffa

3

Una clave externa solo puede hacer referencia a una sola clave principal, por lo que no. Sin embargo, se puede utilizar una mesa de bridge:

CustomerA <---- CustomerA_Orders ----> Order 
CustomerB <---- CustomerB_Orders ----> Order 

Así Orden no tiene aun una clave externa; si esto es deseable, aunque ...

1

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

0

Dos tipos distintos de cliente es un caso clásico de tipos y subtipos o, si lo prefiere, clases y subclases. Here es 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.

0

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 debe 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.

1

Heredé una base de datos de SQL Server donde esto se hizo (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 principal con los datos del cliente compartidos, 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.

0
  1. Crear una tabla de "cliente" incluye todas las columnas que tienen los mismos datos para ambos tipos de clientes.
  2. que crear la tabla "customer_a" y "customer_b"
  3. Uso "customer_id" de mesa "consumidor" como clave externa en "customer_a" y "customer_b"

       customer 
            | 
        --------------------------------- 
        |        | 
    cusomter_a      customer_b 
    
Cuestiones relacionadas