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 classificationcon id = 20, id_company = 1. Y un departmentque 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

classificationes 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
DEPARTMENTyCLASSIFICATION. Este nuevo tipo de entidad:POSITIONproporciona la información que está implícita en su modelo, que un departamento en particular tiene un conjunto de trabajos de varias clasificaciones.Agregar
POSITIONa su modelo como una entidad explícita tiene algunas ventajas.WORKERposibilidad de ser asignado a departamentos y clasificaciones en diferentes empresas.WORKERs 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
DEPARTMENTyCLASSIFICATION, 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
POSITIONregistros 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
IBMyMicrosoft.IBMpuede tener unSoftware Developmentdepartamento y Microsoft puede tener unDesktop Softwaredepartamento. IBM puede tener unaSoftware Engineerclasificación y Microsoft puede tener unaSoftware Developerclasificación. Ahora, porque tiene una clave sustituta paraDepartmentyClassification, el hecho de queSoftware Developmentes unIBMdepartamento yDesktop Softwarees unMicrosoftdepartamento 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 unIBMempleado en elSoftware Developmentdepartamento,Software Developercuya 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
IBMy los 2 Ids representanMicrosoft. He resaltado en rojo el escenario dondeHarlan MillsyBill Gatesestá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
Companymesa, que es fundamental y no tiene padres, y luego crear la identificación de las relaciones a lasDepartmentyClassificationlos niños tablas. Las tablasDepartmentyClassificationahora tienen un PK delCompany Idmás un Número de secuencia o Nombre para distinguirlos. Luego, las relaciones desdeDepartmentyClassificationhaciaWorkertambién se conviertenidentifyingy, por lo tanto, el PK de seWorkerconvierte 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 hayoneCompany Iden laWorkertabla. Ahora es imposible asignar unWorkeraDepartmentuno en unoCompanyy a aClassificationen otroCompany.¿Por qué es esto imposible? Es imposible porque el esquema implementa integridad referencial entre
WorkeryDepartmentyClassification. Si se intenta insertar unWorkerpara unDepartmenten unoCompanyyClassificationotro 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
Workerde un determinadoCompanynecesario asignar unaClassificationy unaDepartmentdel mismoCompany. Pero, si en el mundo realMicrosofttiene un departamento llamadoDesktop Softwarepero el usuario de la base de datos afirma que el departamento esSoftware Developmentel 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