Я думаю, вам придется использовать триггер, чтобы применить ограничение уникальности между столбцами. Если вы добавляете уникальные индексы для каждого столбца, а затем запускаете что-то вроде этого (непроверенное в верхней части кода моей головы):
CREATE FUNCTION no_dups_allowed() RETURNS trigger AS $$
DECLARE
r ROW;
BEGIN
SELECT 1 INTO r
FROM users
WHERE LOWER(email) = LOWER(NEW.email_new)
OR LOWER(email_new) = LOWER(NEW.email);
IF FOUND THEN
-- Found a duplicate so it is time for a hissy fit!
RAISE 'Duplicate email address found' USING ERRCODE = 'unique_violation';
END;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Вы бы хотели что-то подобное в качестве триггера BEFORE INSERT и BEFORE UPDATE. Этот триггер позаботится о перехвате дубликатов между столбцами, а уникальные индексы позаботятся о дубликатах в столбцах.
Некоторые полезные ссылки:
В любом случае вам потребуются отдельные индексы для ваших запросов, и использование половины индексов уникальности упрощает ваш триггер, оставляя его для работы только с частью столбца; если вы попытаетесь сделать все это в триггере, вам придется следить за обновлением строки, не меняя столбцы email
или email_new
.
Для половины запроса вы можете создать представление , в котором для объединения двух столбцов использовалось UNION
. Вы также можете создать функцию для объединения адресов электронной почты пользователя в один список. Трудно сказать, что было бы лучше без знания более подробной информации об этих других запросах, но я подозреваю, что исправление всех других запросов, чтобы узнать о email
и email_new
, было бы лучшим подходом; вам все равно придется обновить все остальные запросы, чтобы использовать представление или функцию, так зачем вообще создавать представление или функцию?