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?

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.


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ą.



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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.