首页 > 解决方案 > 使表中的两列唯一

问题描述

我有一个看起来像这样的表:

ID 电子邮件 alt_email
1 abc@gmail.com 123@gmail.com
2 def@gmail.com ghi@gmail.com

每个用户都有一个电子邮件和备用电子邮件。我想让它在添加(或修改)用户时,PSQL 表不允许重复,即使在两列之间也是如此。例如,这是不允许的:

ID 电子邮件 alt_email
1 abc@gmail.com def@gmail.com
2 def@gmail.com ghi@gmail.com

因为def@gmail.com是重复的。我怎样才能做到这一点?

标签: sqlpostgresql

解决方案


最简单的选择 - 不改变数据模型 - 将是在触发函数中控制它:

将列独立声明为UNIQUE,以便在同一列中没有重复的电子邮件:

CREATE TABLE t (
  id int, 
  email text UNIQUE, 
  alt_email text UNIQUE
);

创建一个函数来检查电子邮件是否存在于另一列中:

CREATE OR REPLACE FUNCTION check_email() 
RETURNS TRIGGER AS $$
BEGIN  
  IF (SELECT EXISTS 
       (SELECT 1 FROM t WHERE alt_email = NEW.email OR email = NEW.alt_email)) THEN
    RAISE EXCEPTION 'E-mail already exists!';
  ELSE
    RETURN NEW;
  END IF;
END; $$ LANGUAGE plpgsql;

最后将触发器函数附加到表中

CREATE TRIGGER tgr_check_email
BEFORE INSERT OR UPDATE ON t
FOR EACH ROW EXECUTE PROCEDURE check_email();

演示:db<>fiddle


推荐阅读