sql - 如何在数据库中实现完全不相交特化?

标签 sql database relational-database

假设有一个学生和教授的数据库(一个非常简单的数据库),关系数据库如下:

GradStudent (_id_, name, gradStuff)
UndergradStudent (_id_, name, underGradStuff)
Professor (_id_, name)
Teaches(_prof_id_, _stud_id_)

考虑到上面的关系数据库旨在表示完全不相交的特化,即没有表 Student 而是两个完全独立的表,当用 SQL 编写它以实现数据库时,如何我会获取 Teaches 表的学生 ID 吗? 我不知道如何从两个不同的表创建外键。

我写这个问题是假设 SQL 语言在所有平台上并不完全不同。如果需要澄清:我正在研究 Oracle SQL Developer。

编辑::附加信息/说明:

对于我想要实现的目标有一个更加图形化、简单化的 View :

我想在 SQL 代码中编写以下内容(但是我不知道这怎么可能,因此不知道如何做)

enter image description here

如果图片太简单,我很抱歉,如果需要,我可以添加更多属性和细节,请告诉我。

最佳答案

I cannot figure out how to make a foreign key from two different tables.

您的意思是,外键/引用两个不同的表。但本设计中没有这样的外键。

我们为表声明一个 SQL FOREIGN KEY 来表示(即告诉 DBMS)列列表的值也是对应列列表(可能是同一个列表)的值,这些列在一个表中是唯一的。表(可能是同一张表)。你这里没有这个。您的表有不同的约束。

如果您想要这些基表,那么您必须使用 SQL 中的触发器来强制执行约束。

您还可以进行以下设计:

  • 具有 NOT NULL UNIQUE 或 PRIMARY KEY id 的基表 Student
  • 来自 GradStudent (id)、UndergradStudent (id) 和 Teaches (stud_id) 的外键 REFERENCES Student (id)
  • 学生在 id 上的投影是 GradStudent 和 UndergradStudent 在 id 上的投影的不相交并集的约束

您可以通过触发器来表达后一个约束的一部分。表达脱节(但不是并集)的无触发方式是:

  • GradStudent、UndergradStudent 和 Student 中的类型鉴别器/标签列 student_type (例如),带有从 GradStudent 和 UndergradStudent 到 NOT NULL UNIQUE (id,student_type) 的附加外键( super )键 (id,student_type) )在学生
  • GradStudent CHECK(student_type = 'grad') 和 UndergradStudent CHECK (student_type = 'undergrad')

两个学生子类型基表中的行都是相同的(冗余),而学生中的行由其 ID 确定(冗余),但这就是在没有触发器的情况下的成本。列 Student_type 可以是计算列。

确实没有漂亮的 SQL 方法来强制每个父 ID 都是子 ID。仅具有上述子表而不是父表和子表的 LEFT JOIN 强制每个父表都是子表,但需要 NULL 列和进一步的约束。需要触发器来合理约束SQL数据库。人们可以使用习语来获得声明性约束。

有关子类型习语的更多信息,请参阅 this answer and its links 。谷歌“stackoverflow数据库sql表”加上子/父、 super /子表、 super /子类型、继承和/或多态性。还有多个/许多/两个 FK/关系/关联/引用/链接(尽管通常在这个问题中,所需的约束不是 FK,并且设计应该使用子类型)。我用谷歌搜索“stackoverflow 两个外键”并得到 this .

关于sql - 如何在数据库中实现完全不相交特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26091990/

相关文章:

mysql - 在实时机器上更新(或替换)整个数据库表的最佳方法是什么?

MySQL:两个 n:1 关系,但不是同时存在

php - 如何通过 PhpMyAdmin 存储外键?

mysql - MYSQL中的存储函数

SQL Server 2005的: Converting varchar value '1.23E-4' to decimal fails

sql - POWER 不会反转 LOG,反之亦然

ruby-on-rails - rails : storing encrypted data in database

mysql - 使用golang在mysql中创建数据库

sql - 具有两个日期参数的两个日期字段中的条件

mysql - SQL:GROUP BY 与 DISTINCT。在这种情况下最好的是什么?