Domanda

Sto cercando di creare una relazione in cui è possibile includere una delle quattro parti diverse, ma qualsiasi raccolta delle stesse parti deve essere gestita come unica.

Esempio: Un incarico deve avere una società assegnata, può eventualmente avere una posizione, un gruppo di lavoro e un programma assegnati. Un incarico potrebbe non avere un gruppo di lavoro senza una posizione.

Supponiamo di avere aziende A, B, C; posizioni X, Y, Z; gruppi di lavoro I, J, K e programmi 1, 2, 3.

Quindi potrebbero essere incluse relazioni valide A - X - I - 1 A - Z - 2 B - Y C C - 3 B - Z - K

Ma includerebbe relazioni non valide A - K (gruppo di lavoro senza posizione) Y - K - 1 (Nessuna azienda)

Quindi, per creare la mia tabella, ho creato

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)

Immagino che questo gestisca tutte le mie relazioni oltre alla necessità di un incarico di avere una posizione se c'è un gruppo di lavoro (che posso felicemente fare programmaticamente o con trigger, penso)

Tuttavia, quando provo questo schema, mi permette di inserire il seguente ...

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

... senza lamentele. Immagino che (1, null, null, null) non sia uguale a se stesso poiché sono inclusi i null. In questo caso, esiste un modo per gestire questa relazione?

Qualsiasi aiuto sarebbe apprezzato!

È stato utile?

Soluzione

Questa è una caratteristica (anche se non è quella che mi aspettavo).

Questa discussione suggerisce di rendere la tua chiave una chiave primaria per ottenere il comportamento che ti aspettavi:

  

Questa è una caratteristica - un valore NULL è un   valore indefinito, quindi due NULL   i valori non sono gli stessi. Può essere un   poco confuso ma ha senso quando   ci pensi.

     

Un indice UNICO lo garantisce   i valori non NULL sono univoci; potresti   specifica che la tua colonna non accetta   Valori NULL.

Altri suggerimenti

L'unico modo in cui posso pensare di gestirlo senza trigger / programmazione aggiuntivi sarebbe quello di avere un unico "Nessuno dei precedenti" valore in ciascuna delle tabelle referenziate, in modo che il test sia simile

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

Dove gli identificatori NO_ * sono del tipo / lunghezza corretti per le colonne del tuo ID. Ciò fallirebbe, come ti aspetteresti.

In MySQL NULL! = NULL o altro. Questo è ciò che UNIQUE non funziona. Dovresti usare un altro valore predefinito per gli spazi, come zero

Penso che sia importante notare che esiste un modo adeguato per interpretare e gestire i valori NULL, e il comportamento mostrato dall'OP è esattamente ciò che si intende. Puoi ignorare quel comportamento e puoi gestire la tua domanda come vuoi senza obiezioni da parte mia, ma potrebbe essere bene " Accetta " una risposta che descrive una qualche forma di Best Practices, piuttosto che una preferenza personale non standard.

O se non sei d'accordo con la Best Practice di consenso, non puoi semplicemente accettare alcuna risposta.

Non è una corsa per ottenere una risposta accettata il più rapidamente possibile. La delibera e la collaborazione intendono anche far parte del processo, credo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top