【问题标题】:How to enforce a unique constraint across multiple tables?如何在多个表中强制执行唯一约束?
【发布时间】:2021-01-06 01:25:48
【问题描述】:

我创建了以下两个表格来映射学生和教师:

CREATE TABLE students(
    student_id SERIAL PRIMARY KEY,
    first_name NOT NULL VARCHAR(50),
    last_name NOT NULL VARCHAR(50),
    phone VARCHAR(15) UNIQUE NOT NULL CHECK (phone NOT LIKE '%[^0-9]%'),
    email VARCHAR(30) UNIQUE NOT NULL CHECK (email NOT LIKE '%@%'),
    graduationYear SMALLINT CHECK (graduationYear > 1900)
);

CREATE TABLE teachers(
    teacher_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    departament VARCHAR(40) NOT NULL,
    email VARCHAR(30) UNIQUE NOT NULL CHECK (email NOT LIKE '%@%'),
    phone VARCHAR(15) UNIQUE NOT NULL CHECK (phone NOT LIKE '%[^0-9]%')
);

如您所见,两个表都有phoneemail 的列。我希望这两个对于每个人来说都是独一无二的

我如何引入一个约束来检查在students 表中引入的电话号码/电子邮件是否不存在于teachers 表中? 是否有任何类型的关键字可以像 UNIQUE 但在多个表上使用,或者我应该采取其他方法吗?

编辑:正如@a​​_horse_with_no_name 所指出的,LIKE 不支持正则表达式。我应该使用SIMILAR TO

【问题讨论】:

  • 与您的问题无关,但LIKE 不支持正则表达式。如果您想坚持使用标准 SQL,您要么需要 similar to,要么需要 posix regex

标签: sql postgresql database-design constraints unique-constraint


【解决方案1】:

我将创建一个表person,其中包含两者共有的所有属性,包括标识教师和学生的type 列。然后,您可以在电话和电子邮件列上创建唯一约束(或索引)。

要存储“类型特定”属性(毕业年份、部门),您可以在person 表中设置可空列,并且只根据类型输入值。如果您不希望除了这两个之外还有更多“特定于类型”的属性,那么这可能是最简单的解决方案

如果您期望更多“特定于类型”的属性,也可以使用包含这些属性的附加表(studentteacher)。这是在关系数据库中建模继承的传统方式。由于 Postgres 支持表继承,您还可以创建 teacherstudent 表以从 person 表继承。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多