Múltiples claves foráneas a una sola columna


Estoy definiendo una base de datos para un sistema de clientes/ pedidos donde hay dos tipos muy distintos de clientes. Debido a que 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).

Sus pedidos, sin embargo, 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 SQL server y no me ha dado problemas creando las relaciones, pero aún no he intentado insertar ningún dato.

Además, estoy planeando usar NHibernate como el OR, ¿podría haber algún problema introducido al hacer las relaciones como esta?

Author: Aaron Powell, 2009-07-27

7 answers

No, no puede tener un solo campo como clave foránea para dos tablas diferentes. ¿Cómo dirías dónde buscar la llave?

Al menos necesitará un campo que indique qué tipo de usuario es, o dos claves foráneas separadas.

También puede 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, de modo que tenga una sola tabla con el id de usuario como clave principal.

 22
Author: Guffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 08:01:53

Una clave foránea solo puede hacer referencia a una única clave primaria, por lo que no. Sin embargo, puedes usar una tabla bridge:

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

Así que Order ni siquiera tiene una clave foránea; sin embargo, si esto es deseable...

 4
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 07:45:35

Puede crear una clave foránea que haga referencia a varias tablas. Esta característica es para permitir la partioining vertical de su tabla y aún así 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 el PK y luego refernce su tabla OrderID a CustomerID.

Raj

 1
Author: Raj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 13:29:14

Heredé una base de datos SQL Server donde se hizo esto (una sola columna utilizada en cuatro relaciones de clave foránea con cuatro tablas no relacionadas), así que sí, es posible. Sin embargo, mi predecesor se ha ido, así que no puedo preguntar por qué pensó que era una buena idea.

Usó una columna GUID (tipo"uniqueidentifier") para evitar el problema de ambigüedad, y desactivó la comprobación de restricciones en las claves foráneas, ya que está garantizado que solo una coincidirá. Pero se me ocurren muchas razones por las que no debería, y no he pensado en ninguna razón por la que deberías.

El suyo suena como el problema clásico de "especialización", que normalmente se resuelve creando una tabla principal con los datos de clientes compartidos, y luego dos tablas secundarias que contienen los datos únicos de cada clase de cliente. Su clave externa estaría entonces contra la tabla de clientes padre, y su determinación de qué tipo de cliente se basaría en qué tabla secundaria tenía una entrada coincidente.

 1
Author: Dave G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-15 22:45:08

Como se ha señalado, si la clave es, digamos, 12345, ¿cómo sabrías en qué mesa buscarla? Usted podría, supongo, hacer algo para asegurarse de que los valores clave para las dos tablas nunca se superponen, pero esto es demasiado feo y doloroso de contemplar. Podrías tener un segundo campo que diga qué tipo de cliente es. Pero si vas a tener dos campos, ¿por qué no tener un campo para el tipo de cliente 1 id y otro para el tipo de cliente 2 id.

Sin saber más sobre su aplicación, mi primer pensamiento es que realmente debe tener una tabla de clientes general 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 stuff cosas básicas como el nombre y la dirección y el número de cliente al menos and y repetir columnas a través de las tablas apesta a lo grande. Las tablas adicionales podrían entonces remitirse a la tabla base. Como hay entonces una sola clave para la tabla base, la cuestión de las claves foráneas que tienen que saber a qué tabla hacer referencia se evaporan.

 0
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-29 17:39:46

Dos tipos distintos de cliente es un caso clásico de tipos y subtipos o, si lo prefiere, clases y subclases. Aquí hay una respuesta de otra pregunta.

Esencialmente, la técnica class-table-inheritance es como la respuesta de Arnand. El uso de la técnica de clave primaria compartida es lo que le permite sortear los problemas creados por dos tipos de clave foránea en una columna. La clave externa será customer-id. Que 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
Author: Walter Mitty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:42
  1. Crear una tabla "cliente" incluir todas las columnas que tienen los mismos datos para ambos tipos de cliente.
  2. Que crear la tabla "customer_a" y "customer_b"
  3. Use " customer_id "de la tabla" consumer "como clave foránea en" customer_a "y"customer_b"

                    customer
                        |
         ---------------------------------
         |                               |
    cusomter_a                      customer_b
    
 -1
Author: Anand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-16 12:10:53