Чи можу я переконатися, що два стовпці не мають однакового значення


11

Якщо у мене є таблиця, яка виглядає приблизно так

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

Чи є спосіб переконатися, що aa != bbокрім використання логіки рівня програми або примушування тригера до виходу з ладу до ПЕРЕД ВСТАВКИ?

Відповіді:


3

MySQL не підтримує CHECKконтрастних напрямків безпосередньо, хоча, якщо у вас є досить недавня версія, вона підтримує тригери та підвищення помилок через SIGNAL, щоб ви могли визначити BEFORE INSERTта BEFORE UPDATEтригери, які перевіряють дані та підвищують помилки, якщо призначене обмеження не задовольняється.

Це, звичайно, буде менш ефективною, ніж нативна підтримка обмежень для перевірки, тому, якщо ви виконуєте велику кількість записів до цієї структури, не забудьте проаналізувати різницю продуктивності, викликану тригером, якщо це занадто шкодить вашій програмі.


9

Ні, ти не можеш. У більшості СУБД (Postgres, SQL-сервер, Oracle, DB2 та багато інших) ви можете просто додати CHECKобмеження:

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

Я не бачу жодного способу мати це в MySQL, використовуючи лише референтні обмеження. Окрім тригерів, ви можете дозволити двом стовпцям однакові значення та просто ігнорувати рядки, отримуючи доступ до таблиці завжди через вигляд:

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

Крім того, ви можете обмежити операції "Вставити та оновити" за допомогою (збережених) процедур, які піклуються про обмеження і не дозволяють вставляти (або змінювати) дані, які не задовольняють його.



-1

Обидва стовпця, про які йдеться, посилаються на одну і ту ж таблицю Bar. Чи можете ви розділити таблицю Bar на дві частини, щоб вони містили id з різними наборами значень?


1
Тоді, скажімо , у нас є три пари в Fooтаблиці (1,2) (2,3) (3,1). Як слід розділити три значення?
ypercubeᵀᴹ

1
Я згоден, помилкова пропозиція.
msi77
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.