sql - primary - ¿Clave externa que se refiere a claves principales en varias tablas?
llave foranea compuesta sql server (7)
Asumiendo que debe tener dos tablas para los dos tipos de empleados por alguna razón, ampliaré la respuesta de vmarquez:
Esquema:
employees_ce (id, name)
employees_sn (id, name)
deductions (id, parentId, parentType, name)
Datos en deducciones:
deductions table
id parentId parentType name
1 1 ce gold
2 1 sn silver
3 2 sn wood
...
Esto le permitiría tener deducciones apuntando a cualquier otra tabla en su esquema. Este tipo de relación no está respaldada por restricciones de nivel de base de datos, IIRC, por lo que deberá asegurarse de que su aplicación gestione correctamente la restricción (lo que lo hace más engorroso si tiene varias aplicaciones / servicios diferentes que llegan a la misma base de datos).
Tengo dos tablas, a saber, employees_ce y employees_sn, bajo los empleados de la base de datos.
Ambos tienen sus respectivas columnas de clave primaria únicas.
Tengo otra tabla llamada deducciones, cuya columna de clave externa quiero hacer referencia a las claves principales de employees_ce y employees_sn. es posible?
por ejemplo
employees_ce
--------------
empid name
khce1 prince
employees_sn
----------------
empid name
khsn1 princess
Entonces, ¿es esto posible?
deductions
--------------
id name
khce1 gold
khsn1 silver
En realidad, yo hago esto yo mismo. Tengo una tabla llamada ''Comentarios'' que contiene comentarios para registros en otras 3 tablas. Ninguna de las soluciones realmente maneja todo lo que usted probablemente quiera. En tu caso, harías esto:
Solución 1:
Agregue un campo tinyint a employees_ce y employees_sn que tenga un valor predeterminado que sea diferente en cada tabla (Este campo representa un ''identificador de tabla'', así que los llamaremos tid_ce & tid_sn)
Cree un índice único en cada tabla usando el PK de la tabla y el campo de identificación de la tabla.
Agregue un campo tinyint a su tabla ''Deductions'' para almacenar la segunda mitad de la clave externa (la ID de la tabla)
Cree 2 claves externas en su tabla ''Deducciones'' (No puede exigir integridad referencial, porque una de ellas será válida o la otra ... pero nunca ambas:
ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_ce] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_ce] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_ce] GO ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_sn] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_sn] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_sn] GO employees_ce -------------- empid name tid khce1 prince 1 employees_sn ---------------- empid name tid khsn1 princess 2 deductions ---------------------- id tid name khce1 1 gold khsn1 2 silver ** id + tid creates a unique index **
Solución 2: esta solución permite mantener la integridad referencial: 1. Cree un segundo campo de clave externa en la tabla "Deducciones", permita valores nulos en ambas claves foráneas y cree claves externas normales:
employees_ce
--------------
empid name
khce1 prince
employees_sn
----------------
empid name
khsn1 princess
deductions
----------------------
idce idsn name
khce1 *NULL* gold
*NULL* khsn1 silver
La integridad solo se verifica si la columna no es nula, por lo que puede mantener la integridad referencial.
Probablemente puedas agregar dos restricciones de clave externa (sinceramente: nunca lo intenté), pero luego insistiría en que la fila padre existe en ambas tablas.
En su lugar, probablemente desee crear un supertipo para sus dos subtipos de empleados y, a continuación, señalar allí la clave externa. (Suponiendo que tenga una buena razón para dividir los dos tipos de empleados, por supuesto).
employee
employees_ce ———————— employees_sn
———————————— type ————————————
empid —————————> empid <——————— empid
name /|/ name
|
|
deductions |
—————————— |
empid ————————+
name
type
en la tabla de empleados sería ce
o sn
.
Sé que este es un tema largo y estancado, pero en caso de que alguien busque aquí, es como trato con claves externas de múltiples tablas. Con esta técnica no tiene operaciones en cascada aplicadas por el DBA, así que asegúrese de tratar con DELETE
y tal en su código.
Table 1 Fruit
pk_fruitid, name
1, apple
2, pear
Table 2 Meat
Pk_meatid, name
1, beef
2, chicken
Table 3 Entity''s
PK_entityid, anme
1, fruit
2, meat
3, desert
Table 4 Basket (Table using fk_s)
PK_basketid, fk_entityid, pseudo_entityrow
1, 2, 2 (Chicken - entity denotes meat table, pseudokey denotes row in indictaed table)
2, 1, 1 (Apple)
3, 1, 2 (pear)
4, 3, 1 (cheesecake)
El ejemplo de SO Op se vería así
deductions
--------------
type id name
1 khce1 gold
2 khsn1 silver
types
---------------------
1 employees_ce
2 employees_sn
Sí, es posible. Deberá definir 2 FK para la 3ra mesa. Cada FK apunta al campo o campos obligatorios de una tabla (es decir, 1 FK por tabla externa).
Suponiendo que he entendido su escenario correctamente, esto es lo que llamaría la forma correcta de hacer esto:
¡Comience desde una descripción de nivel superior de su base de datos! Tiene empleados, y los empleados pueden ser empleados "ce" y empleados "sn" (cualquiera que sean). En términos orientados a objetos, hay un "empleado" de clase, con dos subclases llamadas "empleado ce" y "empleado sn".
Luego, traduce esta descripción de nivel superior a tres tablas: employees
, employees_ce
y employees_sn
:
-
employees(id, name)
-
employees_ce(id, ce-specific stuff)
-
employees_sn(id, sn-specific stuff)
Dado que todos los empleados son empleados (¡duh!), Cada empleado tendrá una fila en la tabla de employees
. Los empleados "ce" también tienen una fila en la tabla employees_ce
, y los employees_ce
"sn" también tienen una fila en la tabla employees_sn
. employees_ce.id
es una clave foránea para employees.id
, tal como lo es employees_sn.id
.
Para referirse a un empleado de cualquier tipo (ce o sn), consulte la tabla de employees
. Es decir, ¡la clave externa con la que tuvo problemas debería referirse a esa tabla!
Técnicamente posible. Es probable que se refiera a los empleados en las deducciones y en los employees_sn. Pero ¿por qué no fusionas employees_sn y employees_ce? No veo ninguna razón por la que tengas dos mesas. No hay una relación entre muchos. Y (no en este ejemplo) muchas columnas.
Si hace dos referencias para una columna, un empleado debe tener una entrada en ambas tablas.