繁体   English   中英

数据库设计:如何 model 一个表可以属于其他两个表中的任何一个的关系?

[英]Database design: How to model a relationship where a table can belong to either of two other tables?

我有三个实体:

  1. 课程
  2. 部分

每个“课程”由几个“课程”组成。 课程中的“课程”可以分类为“部分”,也可以不分类。

因此,课程的内容可能如下所示:

Foo Course:
    Lesson 1
    Lesson 2
    Lesson 3
    Lesson 4

或者像这样:

Bar Course:
    Section 1:
        Lesson 1
        Lesson 2
    Section 2:
        Lesson 3
        Lesson 4

因此,换句话说,一门课程可以直接有“课程”,也可以有“部分”,而“部分”又可以有“课程”。

从另一个角度来看,“课程”可以直接属于“课程”,也可以属于“节”,而“节”又属于“课程”。

我正在努力解决如何在关系数据库中实现这种结构。

如果每个“课程”都必须属于一个“部分”,那很容易,我可以简单地有一个“课程”表,一个带有“CourseId”列的“部分”表,以及一个带有“课程”表的“SectionId”列。

但我的情况并不那么简单。 “部分”可能作为“课程”和几个“课程”之间的中间人存在,但它也可以不存在,在这种情况下,“课程”直接具有“课程”而没有“部分”。

对于如何在关系数据库的上下文中理想地实现这种结构的任何建议,我将不胜感激。

谢谢。

1 进度要求

一门课程可以直接有“课程”,也可以有“部分”,然后有“课程”。 “课程”可以直接属于“课程”,也可以属于“部分”,而“部分”又属于“课程”。

  1. 尽管您已经给出了一些规则,但还有一些是隐含的,而不是明确的。 我们需要使它们明确。
  2. 还有其他的考虑,需要评估和确定。 例如。 究竟什么是教训
    • 课程是否独立,可以在不止一门课程中使用,而不需要重复课程?
      Lesson [安全使用锤子]可能在
      Course [木制品] 以及
      CourseSection [木工,基础]`
    • 课程是否依赖于课程 [和部分],因此是该结构所独有的吗?
    • 我将假设前者。

这是一个临时的 model,显示了两种类型的课程,以及一个独立的课程,等待决策和进一步的数据建模。 重复的元素以红色显示。 非规范化表格,便于理解

2 关系数据 Model

如果我没有展示几个中间步骤(在要求的简单问答格式中不可能),请原谅我。 这是最终数据 model。

  • 规范化意味着数据库中没有空值

  • 可空外键是特别坏消息,严格禁止

  • “虚拟记录”不仅尴尬和可怕(影响每个访问表的SELECT ),它不是事实,完全没有必要

  • RecordIds是物理的; 反关系,每个都需要一个额外的列和索引。 关系的,规范化的

  • 这使用关系键(由数据组成),它提供关系完整性(不同于参照完整性)

    • CourseLesson.CourseLesson标识课程中的课程,使其在课程中有意义,独立于LessonNo
    • SectionLesson.SectionLesson标识该部分中的课程,使其在课程和部分中具有意义,独立于LessonNo
  • Course是独占子类型,以确保:

    • 一个简单的课程Course_TypeLesson直接有课程,并且
    • 分段课程Course_TypeSection有附加到该部分的课程,而不是课程。
  • Lesson是独立且完全定义的(一次)

    • Lesson is used in任一类型的Course
    • CourseLesson.AK防止Lesson在简单Course中重复
    • SectionLesson.AK防止Lesson在分段Course中重复。

更多的?

进度数据 model 解决了很多问题,希望能回答您的问题。 但它可能会暴露其他人,它可能需要进一步定义:数据建模是一项迭代任务。 请随意发表评论。

符号

  • 我所有的数据模型都在IDEF1X中呈现,这是自 1993 年以来用于建模关系数据库的标准。
  • 对于不熟悉关系 Model 或其建模方法的人来说,我的IDEF1X 简介是必不可少的读物。 请注意,IDEF1X 模型具有丰富的细节和精度,显示了所有必需的细节,而本土模型由于不了解标准的要求,因此定义要少得多。 这意味着,符号需要被完全理解。
  • 有关子类型的完整定义和使用注意事项,请参阅子类型定义

转变你的观点:如果所有Course都可以有讲座,但只有一些讲座属于一个部分,那会解决你的问题吗?

具体而言(如果您想学习,甚至不必费心阅读此内容:D):

Lesson属于course ,外键,不可为空。 Lesson有一个section的外键,可以为空。

现在,如果lessonssections可以属于其他课程,那就另当别论了。

最简单的方法是在Lesson上有两个外键:

CourseId null,
SectionId null

然后在表上放置一个CHECK约束

(CourseId IS NOT NULL AND SectionId IS NULL) OR (CourseId IS NULL AND SectionId IS NOT NULL)

这意味着任何一个都必须存在,但不能同时存在。 不要试图CourseId放在属于某个 Section 的 Lesson 上,因为这会在表中引入非规范化:如果 Section 移动到不同的 Course,那么您将需要更新所有子课程。


严格来说,你真的应该有一个更复杂的设计:
Lesson CourseLesson SectionLesson

但是,这使得无法强制将课程仅作为其中一个或另一个的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM