【问题标题】:How to implement total disjoint specialization in database?如何在数据库中实现完全不相交的专业化?
【发布时间】:2014-11-23 09:05:57
【问题描述】:

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

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

考虑到上面的关系数据库是为了代表完全不相交的专业化,即没有表Student,而是两个完全独立的表,当用SQL编写这个以实现数据库时,我将如何获取学生Teaches 表的 ID? 我不知道如何从两个不同的表中创建外键。

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

编辑 :: 附加信息/澄清:

关于我想要实现的目标的更直观、更简单的视图:

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

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

【问题讨论】:

  • Teaches 中需要有两个 id 字段,一个用于研究生,另一个用于本科,其中一个需要设置为 NULL,我们可以设置检查约束来满足条件。
  • 你知道是否有一种方法可以实现Student 表并且仍然是完全不相交的专业化(即没有既不是本科生也不是研究生的学生被放入数据库)?我对约束不太熟悉,所以我问。
  • “获取 Teaches 表的学生 ID”并没有说明您要表达的内容。
  • 很抱歉。我添加了一张图片以进行澄清。希望对您有所帮助。
  • 请用你想说的话代替废话。您的图表也添加了学生,但您的问题并没有表明您愿意拥有它,甚至说“没有学生表”。此外,标有“TOTAL”的线的线是难以理解的,我们只能猜测。请努力使用语言清楚地表达自己。而且确实需要努力。不要希望,行动吧。

标签: sql database relational-database


【解决方案1】:

我不知道如何从两个不同的表中创建外键。

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

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

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

您还可以设计:

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

您可以通过触发器来表达后一种约束。表达脱节(但不是联合)的无触发方式是:

  • GradStudent、UndergradStudent 和 Student 中的类型鉴别器/标记列 student_type(例如),从 GradStudent 和 UndergradStudent 到 NOT NULL UNIQUE (id,student_type) 的额外 FOREIGN(超级)键(id、student_type)在 Student 中李>
  • GradStudent CHECK(student_type = 'grad') 和 UndergradStudent CHECK (student_type = 'undergrad')

两个 student 子类型基表中的每一个中的行都是相同的(冗余),Student 中的行由它们的 id 确定(冗余),但这是没有触发器的情况下的成本。列 student_type 可以是计算列。

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

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

【讨论】:

  • 我想我正在寻找的是您刚刚解释的替代解决方案。非常感谢!是的,我也发现了那个帖子,但他们只讨论理论,而不是实际的数据库制作。也就是说,除非我跳过某些东西,有时我会这样做。编辑:没关系,他们做到了,自从这个例子起,我就跳过了很多,因为这个问题一开始看起来很混乱。对于那个很抱歉。再次感谢!
  • 另外,如果student_type 是唯一的,它是否允许student 表中的记录超过2 条?
  • student_type 在任何表中都不是唯一的;许多学生/行可以在一个表中具有相同的 student_type。但我不明白你的问题:如果它在哪个表中被设为唯一?为什么您认为学生表中的行数不能超过 2 行?可以有。但是给定 (id,student_type) 值的行不能超过两行。但是,我忘了添加 id 在 Student 中是唯一的:我添加了它。也许您的意思是 id 而不是 student_type,在 Student 中是唯一的?
  • 对不起,我混淆了信息。我现在明白你的解决方案的意思了。
  • 通过stackoverflow.com/questions/27602954/… 的链接来到这里。当(即告诉DBMS)表中唯一列集的值也是表中唯一列集的值时,“我们声明SQL FOREIGN KEY”中不应该只有一个“集唯一”。 “?如果你真的想要他们两个,请你扩展你对那个特定想法的阅读?
【解决方案2】:

如果通过“获取 Teaches 表的学生 ID”,您的意思是您希望 Teaches.stud_id 是一个引用“GradStudent 或 Undergradstudent as is the case”的 FK,您不能。 FK 的目标必须是不是视图的表的键。你没有这样的桌子,所以你也没有这样的钥匙。

我看到的唯一方法是编写一个触发器,该触发器在插入/更新到 Teaches 时进行检查。

【讨论】:

    猜你喜欢
    • 2022-07-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2023-01-13
    • 2021-12-11
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多