2009-01-09 7 views
14

Ich versuche, eine Beziehung zu erstellen, wo vier verschiedene Teile enthalten sein können, aber jede Sammlung der gleichen Teile sollte als einzigartig behandelt werden.MySQL-Frage - Eindeutiger Schlüssel Funktioniert nicht richtig, oder missverstehe ich?

Beispiel: Eine Zuweisung muss eine zugewiesene Firma haben, kann optional einen zugewiesenen Standort, eine Arbeitsgruppe und ein Programm haben. Eine Zuweisung darf keine Arbeitsgruppe ohne einen Standort haben.

Nehmen wir an, wir haben Unternehmen A, B, C; Orte X, Y, Z; Arbeitsgruppen I, J, K und Programme 1, 2, 3.

So könnte gültige Beziehungen umfassen A - X - I - 1 A - Z - 2 B - Y C C - 3 B - Z - K

Aber ungültige Beziehungen würden A enthält - K (Arbeitsgruppe ohne Ort) Y - K - 1 (Kein Unternehmen)

Also, an meinen Tisch zu erstellen, habe ich

erstellt

ich meine, das würde alle meine Beziehungen neben der neccessity einer Zuweisung behandeln einen Ort zu haben, wenn es eine Arbeitsgruppe ist (was ich gerne programmatisch tun kann oder mit Trigger, glaube ich)

Allerdings, wenn ich testen dieses Schema erlaubt es mir die folgende ...

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

... ohne Beschwerde ein. Ich vermute, dass (1, null, null, null) nicht gleich ist, weil Nullen enthalten sind. Wenn das der Fall ist, kann ich dann irgendwie mit dieser Beziehung umgehen?

Jede Hilfe wäre willkommen!

Antwort

17

Dies ist ein Feature (obwohl nicht das, was ich erwartet habe).

This thread schlägt machen Sie Ihren Schlüssel ein Primärschlüssel das Verhalten Sie erwarten zu bekommen:

Dies ist ein Merkmal

- ein NULL-Wert ist ein undefinierten Wert, also zwei NULL Werte nicht gleich sind. Kann ein wenig verwirrend sein, aber macht Sinn wenn Sie darüber nachdenken.

Ein UNIQUE-Index stellt sicher, dass Nicht-NULL-Werte eindeutig sind; Sie könnten angeben, dass Ihre Spalte keine NULL-Werte akzeptiert.

+0

Das Setzen der Spalten auf "NOT NULL" würde funktionieren, würde aber auch das Hinzufügen von Daten wie Rob erfordern und ich schlug vor, dass die Datenbank die aufgelisteten Anforderungen korrekt erfüllt - wenn NULL nicht erlaubt ist, brauchen Sie a 'NO FOO' Wert, der ein gültiger Eintrag in der FOO-Tabelle ist, auf die sich der FK bezieht. –

+1

Zum Erstellen des Index als Primärschlüssel: Das einzige Problem besteht darin, dass Sie keine AUTO_INCREMENT-Spalte erstellen können, wenn sie nicht Teil des Primärschlüssels ist. Das ist das Problem, das ich habe. –

+0

Ein weiteres Problem mit den NULL-fähigen Spalten des PK besteht darin, dass sie NOT NULL werden und stattdessen 0 oder eine leere Zeichenfolge als Standardwert erhalten. – Rafa

3

Der einzige Weg, ich Handhabung dies ohne zusätzliche Trigger denken kann/Programmierung eine einzelne „Keine des oben genannten“ Wertes in jedem der referenzierten Tabellen zu haben wäre, so dass Ihr Test würde aussehen wie

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

Die NO_* Bezeichner sind der richtige Typ/die richtige Länge für Ihre ID-Spalten. Dies würde dann scheitern, wie Sie es erwarten würden.

0

In MySQL NULL! = NULL, oder irgendetwas.Also das ist, was das UNIQUE nicht funktioniert. Sie sollten einen anderen Standardwert für Leerzeichen wie null verwenden.

0

Ich denke, es ist wichtig zu beachten, dass es eine ordnungsgemäße Möglichkeit für NULL-Werte interpretiert und behandelt wird, und das Verhalten des OP ist genau das, was beabsichtigt ist. Sie können dieses Verhalten ignorieren, und Sie können Ihre Abfrage so handhaben, wie Sie wollen, ohne dass Sie mich ablehnen, aber es könnte gut sein, eine Antwort zu akzeptieren, die eine Form von Best Practices beschreibt, anstatt einer nicht standardmäßigen persönlichen Präferenz.

Oder wenn Sie mit dem Konsens Best Practice nicht einverstanden sind, können Sie einfach keine Antwort akzeptieren.

Es ist kein Rennen, um eine Antwort so schnell wie möglich zu erhalten. Deliberation und Kollaboration sollen ebenfalls Teil des Prozesses sein, denke ich.