Могу ли я убедиться, что два столбца не имеют одинаковое значение

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помимо использования логики на уровне приложения или принудительного запуска триггера перед вставкой?

Nifle
источник

Ответы:

3

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

Конечно, это будет менее эффективно, чем встроенная поддержка проверочных ограничений, поэтому, если вы выполняете большой объем операций записи в эту структуру, обязательно проанализируйте разницу в производительности, вызванную триггером, на случай, если он нанесет слишком серьезный ущерб вашему приложению.

Дэвид Спиллетт
источник
8

Нет, ты не можешь. В большинстве СУБД (Postgres, SQL-Server, 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 ;

Кроме того, вы можете ограничить операции вставки и обновления с помощью (хранимых) процедур, которые заботятся об ограничении и не позволяют вставлять (или изменять) данные, которые не удовлетворяют его.

ypercubeᵀᴹ
источник
-1

Оба рассматриваемых столбца относятся к одной и той же столбчатой ​​таблице. Не могли бы вы разделить таблицу Бар на две части, чтобы они содержали идентификатор с различными наборами значений?

msi77
источник
1
Тогда, скажем , у нас есть три пары в Fooтаблице (1,2) (2,3) (3,1). Как мы должны разделить три значения?
ypercubeᵀᴹ
1
Я согласен, ошибочное предложение.
MSI77