Czy mogę się upewnić, że dwie kolumny nie mają tej samej wartości

11

Jeśli mam stół, który wygląda tak

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)
)

Czy istnieje sposób, aby upewnić się, że aa != bboprócz korzystania z logiki poziomu aplikacji lub wymuszania niepowodzenia wyzwalacza PRZED WPROWADZENIEM?

Nifle
źródło

Odpowiedzi:

3

MySQL nie obsługuje CHECKbezpośrednio contrsaints, ale jeśli masz wystarczająco najnowszą wersję, obsługuje wyzwalacze i zgłaszanie błędów przez SIGNAL, więc możesz zdefiniować BEFORE INSERTi BEFORE UPDATEwyzwalacze, które sprawdzają dane i zgłaszają błędy, jeśli zamierzone ograniczenie nie jest spełnione.

Będzie to mniej wydajne niż natywna obsługa ograniczeń sprawdzania, więc jeśli wykonujesz dużą liczbę zapisów do tej struktury, koniecznie przeanalizuj różnicę wydajności spowodowaną przez wyzwalacz, na wypadek, gdyby zbyt mocno zaszkodził twojej aplikacji.

David Spillett
źródło
9

Nie możesz. W większości DBMS (Postgres, SQL-Server, Oracle, DB2 i wiele innych) możesz po prostu dodać CHECKograniczenie:

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

Nie widzę żadnego sposobu, aby mieć to w MySQL, używając tylko ograniczeń referencyjnych. Oprócz wyzwalaczy, możesz pozwolić, aby dwie kolumny miały równe wartości i po prostu zignorować wiersze, uzyskując dostęp do tabeli zawsze przez widok:

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

Alternatywnie można ograniczyć operacje wstawiania i aktualizacji za pomocą (przechowywanych) procedur, które zajmują się ograniczeniem i nie pozwalają na wstawianie (lub zmianę) danych, które go nie spełniają.

ypercubeᵀᴹ
źródło
-1

Obie kolumny, o których mowa, odnoszą się do tej samej tabeli słupkowej. Czy możesz podzielić tabelę Bar na dwie części, aby zawierały id z różnymi zestawami wartości?

msi77
źródło
1
Następnie, że mamy trzy pary w Footabeli: (1,2) (2,3) (3,1). Jak powinniśmy podzielić trzy wartości?
ypercubeᵀᴹ
1
Zgadzam się, błędna sugestia.
msi77