Kann ich sicherstellen, dass zwei Spalten nicht den gleichen Wert haben?


11

Wenn ich einen Tisch habe, der so aussieht

CREATE TABLE foo (
   id INT NOT NULL AUTO_INCREMENT,
   aa INT NOT NULL,
   bb INT NOT NULL,
   PRIMARY KEY (id),
   UNIQUE KEY (aa, bb),
   CONSTRAINT aa_ref FOREIGN KEY (aa) REFERENCES bar (id),
   CONSTRAINT bb_ref FOREIGN KEY (bb) REFERENCES bar (id)
)

Gibt es eine Möglichkeit, um sicherzustellen, dass aa != bbneben der Verwendung von Logik auf Anwendungsebene oder dem Erzwingen eines Fehlschlags eines Triggers beim BEFORE INSERT?

Antworten:


3

MySQL unterstützt CHECKContrsaints nicht direkt. Wenn Sie jedoch über eine ausreichend aktuelle Version verfügen, werden Trigger und Fehlerauslöser über SIGNALunterstützt. Sie können also Trigger BEFORE INSERTund BEFORE UPDATETrigger definieren , die die Daten überprüfen und Fehler auslösen, wenn die beabsichtigte Einschränkung nicht erfüllt ist.

Dies ist natürlich weniger effizient als die native Unterstützung für Überprüfungsbeschränkungen. Wenn Sie also eine große Anzahl von Schreibvorgängen in diese Struktur ausführen, müssen Sie den durch den Trigger verursachten Leistungsunterschied analysieren, falls dies Ihrer Anwendung zu viel Schaden zufügt.


8

Nein, das kannst du nicht. In den meisten DBMS (Postgres, SQL-Server, Oracle, DB2 und vielen anderen) können Sie einfach eine CHECKEinschränkung hinzufügen :

ALTER TABLE foo 
  ADD CONSTRAINT aa_cannot_be_equal_to_bb_CHK
    CHECK (aa <> bb) ;

Ich sehe keine Möglichkeit, dies in MySQL zu haben, da nur referenzielle Einschränkungen verwendet werden. Neben Triggern können Sie zulassen, dass die beiden Spalten gleiche Werte haben, und die Zeilen einfach ignorieren, indem Sie immer über eine Ansicht auf die Tabelle zugreifen:

CREATE VIEW foo_correct AS
SELECT id, aa, bb
FROM foo
WHERE aa <> bb ;

Alternativ können Sie Einfüge- und Aktualisierungsvorgänge durch (gespeicherte) Prozeduren einschränken, die die Einschränkung berücksichtigen, und nicht zulassen, dass Daten eingefügt (oder geändert) werden, die diese nicht erfüllen.



-1

Die beiden fraglichen Spalten beziehen sich auf dieselbe Balkentabelle. Könnten Sie die Balkentabelle in zwei Teile teilen, damit sie eine ID mit den verschiedenen Wertesätzen enthält?


1
Dann sagen wir, wir haben drei Paare in der FooTabelle : (1,2) (2,3) (3,1). Wie sollen wir die drei Werte aufteilen?
Ypercubeᵀᴹ

1
Ich stimme zu, falscher Vorschlag.
msi77
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.