Primary Key - Unique

socke999

Erfahrenes Mitglied
Hallo,
also ich habe eine Tabelle mit sagen wir zwei Spalten :
Code:
CREATE TABLE tabelle
(
a VARCHAR(100),
b VARCHAR(100),
PRIMARY KEY(a,b)
)


also kann ich in meine Tabelle nur einmal
a="Daniel", b = "Mark"
einfügen.

Ich möchte nun aber auch, dass
a="Mark" , b="Daniel"

als gleich wie a="Daniel", b = "Mark" gekennzeichnet wird,

also wenn
a="Daniel", b = "Mark"
dann darf
a="Mark" , b="Daniel"
nicht mehr eingefügt werden, da dieses "Datenpaar" schon einmal vorhanden ist.

Geht das irgendwie mit einem UNIQUE oder sonst irgendwie bei der CREATE TABLE definition.

Ich verwende übrigens eine MYSQL Datenbank.

Kann mir da jemand helfen?
 
Hi,

bei folgender Tabelle
SQL:
CREATE TABLE tabelle
(
a VARCHAR(100),
b VARCHAR(100),
PRIMARY KEY(a,b)
)
wird vereinfacht gesagt nur die Spalte a und die Spalte b aneinandergehängt und dann geschaut ob die Kombination bereits vorhanden ist.
Also ist "DanielManuel" != "ManuelDaniel".

Ich kann es dir zwar nicht 100%ig sagen obs wie folgt funktioniert, aber ich denke dass Trigger da der falsche Ansatz sind. Kommt mir ein bisschen wie Kannonen auf Spatzen vor.
SQL:
CREATE TABLE tabelle
(
a VARCHAR(100),
b VARCHAR(100),
PRIMARY KEY(a,b),
UNIQUE (b,a)
)

Bei dieser Anweisung sollte er die beiden obigen Möglichkeiten richtig erkennen und nichts in die Tabelle einfügen.

Gruß
BK
 
Zuletzt bearbeitet von einem Moderator:
Danke für die antworten,
also per SQL definition scheint das nicht zu funktionieren

Ich habe es jetzt mit einem trigger gelöst:
Code:
DELIMITER |
CREATE TRIGGER check BEFORE INSERT ON tabelle
FOR EACH ROW
BEGIN
DECLARE x INT;
SET x = (SELECT COUNT(*) FROM tablle WHERE a = NEW.b AND b = NEW.a);

IF (x>0) THEN
SET NEW = NULL;
END IF;

END;
|
DELIMITER;


Naja, jetzt hab ich halt doch eine SELECT Anweisung im Trigger, das ich ja eigentlich vermeiden wollte.

Da hätte ich ja auch gleich gekonnt eine
SELECT Abfrage machen und dann diese SELECT Abfrage auswerten
und dann gegebenenfalls ein INSERT machen.

Denn genau das mach ich im Prinzip auch bei meinem Trigger:
Code:
IF (x>0) THEN
SET NEW = NULL;
END IF;

x enthält die anzahl von SELECT COUNT(*) FROM tablle WHERE a = NEW.b AND b = NEW.a

Das heißt, wenn
a="Daniel", b = "Mark"
schon in der Tabelle vorhanden sind, dann macht die SELECT abfrgage beim INSERT INTO (a,b) VALUES ('Mark','Daniel');
x = 1

dann wird mit IF(x>0) THEN überprüft

Code:
SET NEW = NULL;
macht dann einen Fehler und der INSERT BEFEHL wird sozusagen abgebrochen.

Naja, nicht gerade die eleganteste Lösung, aber funktioniert soweit....

Vielen Dank für die Hilfe
 
Vielleicht solltest du vor dem Insert die Reihenfolge von a und b eindeutig festlegen, bspw. nimmst du immer den "kleineren" Wert als Spalte a und den größeren als b. Ggf. werden die Werte vor dem Insert getauscht.
Wenn die Werte Manuel und Daniel geliefert werden, werden sie als
a=Daniel und b=Manuel umgeformt, da "Daniel" kleiner als "Manuel".
Wenn die Werte Daniel und Manuel gelierfert werden, ist
a=Daniel und b=Manuel ok und es muß nicht getauscht werden.
Das sollte helfen.
 
Das ist wohl die beste Lösung, solange wie die Namen nicht geändert werden. Um diese Problem zu umgehen, solltest du die Namen "Mark" und "Daniel" in eine andere Tabelle auslagern und in der Verknüpfungstabelle deren Id verwenden, aber ich hoffe, das machst du sowieso schon.
Andererseits ist es meistens angemessener, die Daten einer solchen Verknüpfungstabelle als gerichtete von-zu-Relation zu sehen, d.h. den Eintrag "Mark"-"Daniel" ebenso in der Datenbank abzulegen wie den Eintrag "Daniel"-"Mark". Erstens kann es sein, dass z.B. Mark die Telefonnummer von Daniel hat, aber Daniel nicht die Telefonnummer von Mark. Zweitens kann es sein, dass du z.B. die Kontakte von "Mark" auflisten willst; wenn du es so machst wie oben angegeben, müsstest du zwei SELECTs machen, eines für jede Spalte, damit du nicht nur "Anton" findest, sondern auch "Rolf". Für solche Zwecke kann es nützlich sein, über die erste Spalte einen Index zu legen, der nicht unique ist; der zwei-Spalten-Schlüssel ist normalerweise nur dazu da, Doppeleinträge zu verhindern, wird aber nur selten für Suchanfragen benötigt.
 
Zurück