Tengo 4 tablas relacionadas como esta (es un ejemplo):
Company:
ID
Name
CNPJ
Department:
ID
Name
Code
ID_Company
Classification:
ID
Name
Code
ID_Company
Workers:
Id
Name
Code
ID_Classification
ID_Department
Supongamos que tengo un classification
con id = 20, id_company = 1
. Y un department
que tiene id_company = 2
(que representa a otra empresa).
Esto permitirá la creación de un trabajador que sea de dos compañías porque la clasificación y el departamento están vinculados a la compañía por separado. No quiero que eso suceda, así que creo que tengo un problema con mis relaciones y no sé cómo resolverlo.
database-design
constraint
777Anon
fuente
fuente
classification
es análogo al cargo, es decir, secretario, conserje, señor supremo, etc.Respuestas:
Su problema se debe al hecho de que falta un tipo de entidad en su modelo. Considere el siguiente ERD:
Tenga en cuenta que he agregado un tipo de entidad de intersección entre
DEPARTMENT
yCLASSIFICATION
. Este nuevo tipo de entidad:POSITION
proporciona la información que está implícita en su modelo, que un departamento en particular tiene un conjunto de trabajos de varias clasificaciones.Agregar
POSITION
a su modelo como una entidad explícita tiene algunas ventajas.WORKER
posibilidad de ser asignado a departamentos y clasificaciones en diferentes empresas.WORKER
s actualmente en la posición, lo cual es una información muy útil.Tenga en cuenta que para evitar el problema de que se defina un puesto para un departamento y una clasificación que se encuentra en diferentes compañías, he ampliado las claves de ambos
DEPARTMENT
yCLASSIFICATION
, lo cual es bueno por las razones por las que puede leer detenidamente en la respuesta de Todd Everett.CUIDADO El modelo anterior supone una simplificación. Específicamente, se supone que cada posición se registra solo una vez. Esto puede o no ser adecuado para las reglas de su negocio. Si necesita varios
POSITION
registros para el mismo departamento y clasificación dentro de una empresa, puede introducir una clave sustitutaPOSITION
.fuente
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
yMicrosoft
.IBM
puede tener unSoftware Development
departamento y Microsoft puede tener unDesktop Software
departamento. IBM puede tener unaSoftware Engineer
clasificación y Microsoft puede tener unaSoftware Developer
clasificación. Ahora, porque tiene una clave sustituta paraDepartment
yClassification
, el hecho de queSoftware Development
es unIBM
departamento yDesktop Software
es unMicrosoft
departamento se pierde para las futuras relaciones con los niños. Este es también el caso conClassification
. Por lo tanto, es fácil asignar accidentalmenteHarlan Mills
, quién es unIBM
empleado en elSoftware 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 representanMicrosoft
. He resaltado en rojo el escenario dondeHarlan Mills
yBill 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 lasDepartment
yClassification
los niños tablas. Las tablasDepartment
yClassification
ahora tienen un PK delCompany Id
más un Número de secuencia o Nombre para distinguirlos. Luego, las relaciones desdeDepartment
yClassification
haciaWorker
también se conviertenidentifying
y, por lo tanto, el PK de seWorker
convierte enCompany Id
, más elDepartment Number
(estoy usando un número de secuencia en este ejemplo), más elClassification Number
. El resultado es que solo hayone
Company Id
en laWorker
tabla. Ahora es imposible asignar unWorker
aDepartment
uno en unoCompany
y a aClassification
en otroCompany
.¿Por qué es esto imposible? Es imposible porque el esquema implementa integridad referencial entre
Worker
yDepartment
yClassification
. Si se intenta insertar unWorker
para unDepartment
en unoCompany
yClassification
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 determinadoCompany
necesario asignar unaClassification
y unaDepartment
del mismoCompany
. Pero, si en el mundo realMicrosoft
tiene un departamento llamadoDesktop 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.fuente
La forma en que entiendo la pregunta es que el campo ID_Clasificación de la tabla 'Trabajadores' solo debe permitir las clasificaciones definidas para la compañía del trabajador respectivo. Por lo tanto, validar (adjuntando una REGLA o mediante DISPARADORES) la información insertada / actualizada en el campo Workers.ID_Classification es adecuada para abordar este requisito.
fuente
Según mis lecturas, todavía no entiendo qué es esta Clasificación y por qué necesita tener la ID_Company . Si es como una posición como alguien mencionó aquí, creo que una tabla estática para contener todas las posiciones sería mejor.
Si está haciendo esto para encontrar fácilmente una clasificación / posición en una empresa, agregue una consulta / vista simple para conectar los departamentos de clasificación de trabajadores y recuperar la identificación de la empresa de la clasificación.
hoy en día, hay vistas o tecnologías más inteligentes, como vistas materializadas e índices de unión, por lo que si su problema es el rendimiento de la consulta, úselas.
fuente