Pregunta

Estoy tratando de crear una relación en la que se puedan incluir cualquiera de las cuatro partes diferentes, pero cualquier colección de las mismas partes debe manejarse como única.

Ejemplo: Una asignación debe tener una compañía asignada, opcionalmente puede tener una ubicación, grupo de trabajo y programa asignados. Una asignación puede no tener un grupo de trabajo sin una ubicación.

Supongamos que tenemos empresas A, B, C; ubicaciones X, Y, Z; grupos de trabajo I, J, K y programas 1, 2, 3.

Entonces las relaciones válidas podrían incluir A - X - I - 1 A - Z - 2 B - Y do C - 3 B - Z - K

Pero las relaciones inválidas incluirían A - K (Grupo de trabajo sin ubicación) Y - K - 1 (Sin empresa)

Entonces, para crear mi tabla, he creado

companyID INT NOT NULL,
FOREIGN KEY companyKEY (companyID) REFERENCES company (companyID),
locationID INT,
FOREIGN KEY locationKEY (locationID) REFERENCES location (locationID),
workgroupID INT,
FOREIGN KEY workgroupKEY (workgroupID) REFERENCES workgroup (workgroupID),
programID INT,
FOREIGN KEY programKEY (programID) REFERENCES program (programID),
UNIQUE KEY companyLocationWorkgroupProgramKEY (companyID, locationID, workgroupID, programID)

Supongo que esto manejaría todas mis relaciones además de la necesidad de una asignación de tener una ubicación si hay un grupo de trabajo (lo que felizmente puedo hacer programáticamente o con disparadores, creo)

Sin embargo, cuando pruebo este esquema, me permite ingresar lo siguiente ...

INSERT INTO test VALUES (1, null, null, null), (1, null, null, null);

... sin quejas. Supongo que (1, nulo, nulo, nulo) no es igual porque los nulos están incluidos. Si este es el caso, ¿hay alguna forma de manejar esta relación?

¡Cualquier ayuda sería apreciada!

¿Fue útil?

Solución

Esta es una característica (aunque tampoco es lo que esperaba).

Este hilo sugiere hacer de su clave una Clave principal para obtener el comportamiento que esperaba:

  

Esta es una característica: un valor NULL es un   valor indefinido, por lo tanto dos NULL   Los valores no son lo mismo. Puede ser un   poco confuso pero tiene sentido cuando   piensas en ello.

     

Un índice ÚNICO asegura que   los valores no NULL son únicos; tú podrías   especifique que su columna no acepta   Valores NULL.

Otros consejos

La única forma en que puedo pensar en manejar esto sin disparadores / programación adicionales sería tener un solo "Ninguno de los anteriores". valor en cada una de las tablas referenciadas, para que su prueba se vea como

INSERT INTO test VALUES (1, NO_LOCATION, NO_WORKGROUP, NO_PROGRAM),
                        (1, NO_LOCATION, NO_WORKGROUP, NO_PROGRAM)

Donde los identificadores NO_ * son del tipo / longitud correctos para sus columnas de ID. Esto entonces fallaría, como es de esperar.

En MySQL NULL! = NULL, o cualquier cosa. Entonces eso es lo que UNIQUE no funciona. Debería usar otro valor predeterminado para espacios en blanco, como cero

Creo que es importante tener en cuenta que hay una forma adecuada de interpretar y manejar los valores NULL, y el comportamiento exhibido por el OP es exactamente lo que se pretende. Puede ignorar ese comportamiento, y puede manejar su consulta de la forma que desee sin objeción por mi parte, pero podría ser bueno "Aceptar". una respuesta que describe alguna forma de Mejores Prácticas, en lugar de una preferencia personal no estándar.

O si no está de acuerdo con las mejores prácticas de consenso, simplemente no puede aceptar ninguna respuesta.

No es una carrera para que una respuesta sea aceptada lo más rápido posible. La deliberación y la colaboración también están destinadas a ser parte del proceso, creo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top