【问题标题】:Adding a database-wide UNIQUE constraint in PostgreSQL在 PostgreSQL 中添加数据库范围的 UNIQUE 约束
【发布时间】:2020-07-20 06:53:47
【问题描述】:

想了解是否有一种方法可以在 PostgreSQL 数据库中的所有表中为公共特定列添加唯一约束?

例如,考虑一个名为“School”的 PostgreSQL 数据库。它有 2 个表,分别命名为“teachers”和“students”。

“teachers”表有teacher_id、first_name、last_name、homeroom_number、department、email和phone列。

“学生”有,student_id、first_name、last_name、homeroom_number、phone、email、graduation_year 列。

我想确保在将数据插入到各自的表中时,“教师”和“学生”中的电子邮件和电话列都是唯一的。

通常在添加 UNIQUE 约束时,它仅作为表约束(表范围)或列约束(仅适用于特定表中的特定列)添加。因此,如果将 UNIQUE 约束添加到“teachers”表中的 email 和 phone 列,则这些值仅在“teachers”表中是唯一的。如果对“students”表执行相同的操作,电子邮件和电话号码也将仅在“students”表中是唯一的。如何添加适用于“教师”和“学生”表中的电话和电子邮件列的唯一约束,以便每个电话号码和电子邮件地址对每个人都是唯一的,无论该人是教师还是学生?例如,如果在“教师”表中插入教师的电话号码为 123-456-789,则在“学生”表中为学生插入相同的电话号码 123-456-789 将引发错误。

【问题讨论】:

  • 您需要将电话号码移动到单独的表中,并从“student”和“teacher”表到“phone_number”表中创建一个外键

标签: postgresql


【解决方案1】:

感谢一些谷歌搜索和回复这篇文章的人提供的想法,我可以做到以下几点:

  1. 创建一个单独的表,对添加到“教师”和/或“学生”表中的所有电话号码进行整理,并对该表中的电话列实施 UNIQUE 约束:

CREATE TABLE phone_numbers (phone_id SERIAL PRIMARY KEY, phone VARCHAR(250) UNIQUE NOT NULL);

  1. 创建一个函数,每次将电话号码插入“教师”和/或“学生”表时,将电话号码插入新创建的“phone_numbers”表:

CREATE OR REPLACE FUNCTION phone_insert_trigger_func() RETURNS trigger AS $$ BEGIN INSERT INTO phone_numbers (phone) VALUES (NEW.phone); RETURN NEW; END; $$ LANGUAGE 'plpgsql';

  1. 最后,创建一个 TRIGGER,每次将电话号码插入“教师”和/或“学生”表时自动执行上述 FUNCTION:

CREATE TRIGGER teachers_insert_trigger AFTER INSERT ON teachers FOR EACH ROW EXECUTE PROCEDURE phone_insert_trigger_func();

CREATE TRIGGER students_insert_trigger AFTER INSERT ON students FOR EACH ROW EXECUTE PROCEDURE phone_insert_trigger_func();

如果上述操作正确完成,插入重复的电话号码(例如,插入的表格中不存在的电话号码(例如“students”)但存在于另一个表格中(例如“teachers”))将引发如下所示的错误反馈,并防止重复的电话号码(无论属于学生还是教师)被插入到“学校”数据库中:

ERROR: duplicate key value violates unique constraint "phone_numbers_phone_key" DETAIL: Key (phone)=(777-555-6519) already exists. CONTEXT: SQL statement "INSERT INTO phone_numbers (phone) VALUES (NEW.phone)" PL/pgSQL function phone_insert_trigger_func() line 3 at SQL statement SQL state: 23505

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2018-02-16
    • 2015-07-02
    • 1970-01-01
    • 2022-01-14
    相关资源
    最近更新 更多