No creo que tengas un problema con las relaciones. Creo que, en cambio, el problema es que al usar claves sustitutas (es decir, Ids) para cada tabla, la base de datos resultante no puede evitar que se inserten trabajadores cuyo departamento es de una compañía mientras que la clasificación es de otra y viceversa. Una buena manera de entender esto es visualizar el esquema utilizando una herramienta de diagramación ER. Voy a utilizar el Oracle Data Modeler herramienta que se puede descargar gratuitamente.
Diagrama ER
Tal como están las cosas, podría tener 2 empresas, digamos IBM
y Microsoft
. IBM
puede tener un Software Development
departamento y Microsoft puede tener un Desktop Software
departamento. IBM puede tener una Software Engineer
clasificación y Microsoft puede tener una Software Developer
clasificación. Ahora, porque tiene una clave sustituta para Department
y Classification
, el hecho de que Software Development
es un IBM
departamento y Desktop Software
es un Microsoft
departamento se pierde para las futuras relaciones con los niños. Este es también el caso con Classification
. Por lo tanto, es fácil asignar accidentalmente Harlan Mills
, quién es un IBM
empleado en el Software Development
departamento, Software Developer
cuya clasificación es unMicrosoft
¡clasificación! Del mismo modo, el trabajador podría recibir la clasificación correcta y el departamento incorrecto. Aquí hay un diagrama que muestra el primer ejemplo:
Los 1 Ids representan IBM
y los 2 Ids representan Microsoft
. He resaltado en rojo el escenario donde Harlan Mills
y Bill Gates
están asignados a los departamentos incorrectos, que se visualiza mediante el ID de 10 departamentos asociado al ID de clasificación 200 y viceversa.
Opciones para resolver
Entonces, ¿cuáles son las opciones para evitar que suceda? Hay dos opciones inmediatas. El primero es darse cuenta de que al usar una clave sustituta para cada tabla, este problema existe e introducir programación adicional para verificar que no ocurra. Esto podría hacerse en la aplicación, pero si pueden ocurrir inserciones y actualizaciones fuera de la aplicación, entonces pueden ocurrir asociaciones incorrectas. Un mejor enfoque sería crear un disparador que se dispare al insertar y actualizar a un empleado para asegurarse de que el departamento asignado sea de la misma compañía que la clasificación asignada, y si no falla, inserte o actualice.
La segunda opción es no usar claves sustitutas para cada tabla. En su lugar, utilice las claves suplentes sólo para la Company
mesa, que es fundamental y no tiene padres, y luego crear la identificación de las relaciones a las Department
y Classification
los niños tablas. Las tablas Department
y Classification
ahora tienen un PK del Company Id
más un Número de secuencia o Nombre para distinguirlos. Luego, las relaciones desde Department
y Classification
hacia Worker
también se convierten identifying
y, por lo tanto, el PK de se Worker
convierte en Company Id
, más el Department Number
(estoy usando un número de secuencia en este ejemplo), más el Classification Number
. El resultado es que solo hay one
Company Id
en la Worker
tabla. Ahora es imposible asignar unWorker
a Department
uno en uno Company
y a a Classification
en otro Company
.
¿Por qué es esto imposible? Es imposible porque el esquema implementa integridad referencial entre Worker
y Department
y Classification
. Si se intenta insertar un Worker
para un Department
en uno Company
y Classification
otro de otro, la combinación que no existe en la tabla principal correspondiente desencadenará una violación de integridad referencial y el inserto no funcionará.
Aquí hay un diagrama actualizado de una implementación de la segunda opción:
Opción preferida
De las dos opciones, prefiero absolutamente la segunda, usando las relaciones de identificación y las teclas en cascada, por dos razones. Primero, esta opción logra la regla deseada sin programación adicional. Desarrollar un disparador no es trivial. Debe ser codificado, probado y mantenido. Asegurar que la lógica del disparador sea óptima para no afectar el rendimiento tampoco es trivial. El libro Matemáticas aplicadas para profesionales de bases de datos proporciona muchos detalles sobre la complejidad de dicha solución. En segundo lugar, las reglas implican que un Departamento y una Clasificación no pueden existir fuera del contexto del Company
, por lo que el esquema ahora refleja con mayor precisión el mundo real.
Esta es una gran pregunta porque muestra exactamente por qué simplemente asumir que cada tabla requiere una clave sustituta es una mala idea. Fabian Pascal tiene una excelente publicación de blog sobre este tema que muestra que una clave sustituta no solo puede ser una mala idea desde el punto de vista de la integridad de los datos, sino que también puede hacer que algunas recuperaciones sean más lentasen el nivel físico precisamente porque se requieren uniones que, si las claves se hubieran conectado en cascada correctamente, serían innecesarias. Otro tema interesante que revela esta pregunta es que una base de datos no puede garantizar que todos los datos insertados en ella sean precisos con respecto al mundo real. En cambio, solo puede garantizar que los datos insertados en él sean consistentes con las reglas que se le declaran. En este caso podemos hacer lo mejor posible mediante el uso del enfoque clave en cascada para garantizar el DBMS puede mantener los datos consistentes con respecto a la regla de que una Worker
de un determinado Company
necesario asignar una Classification
y una Department
del mismo Company
. Pero, si en el mundo real Microsoft
tiene un departamento llamado Desktop Software
pero el usuario de la base de datos afirma que el departamento esSoftware Development
el DBMS no puede hacer nada más que asumir que se le ha dado un hecho real.