考虑时间维度时,基数在 ER 图中如何工作?

How does cardinality work in an ER diagram when considering the dimension of time?

我将使用包含两个实体的问题片段来解释我的问题:

飞机

位置

以及与 link 这些实体的关系:

发送

逻辑 1:

一架飞机最少发送1个位置,最多发送多个位置(不同时刻),因此基数为一对多 (1,N).

Airplane ——— (1,N) ——— Send ——— (1,N) ——— Location 


逻辑二:

一架飞机至少发送 1 个位置,但它不能同时发送多个位置,因此,最小值为 1而且最大值是 1,所以基数是一对一 (1,1)。

Airplane ——— (1,N) ——— Send ——— (1,1) ——— Location


不仅在 ER 中,而且在数据库中。这些逻辑哪个是正确的?

Many-to-Many

你的业务问题可能不是很清楚,那么我们来看书和作者的典型例子。一本书可以有多个作者,每个作者都可以为多本书做出贡献。所以我们有一个经典的Many-to-Many。

关系数据库不直接处理 many-to-many 关系。为此,我们添加了第三个 table 来桥接原来的两个。命名第三个 table 可能有点令人费解,因为它通常代表 not-so-concrete 业务关系。在这种情况下 authorship 是合适的。

书籍与作者

[book]-1-----0-1-M-[authorship]-M-1-0------1-[author]

表格:

  • book
    • pkey(主键,每本书的唯一标识)
    • title
    • planned_publish_date
  • authorship
    • pkey(可选,因为有些人使用组合键中的其他两列作为此 table 的主键)
    • fkey_book(保存作者贡献的书籍的主键值)
    • fkey_author(保存为本书做出贡献的作者的主键值)
  • author
    • pkey(主键,每个作者的唯一标识符)
    • name
    • phone_number

这里的基数是:

  • 一本书可以有任意数量的 authorship 行相关:基数 0、1、M(M 表示不止一个)。
    • 一本计划中的书在 authorship 中可以有零行,因为它还没有与任何作者相关联。稍后,当招募作者时,我们会在作者身份中添加一行。
    • 一本只有一位作者的书有一行 authorship 行,链接到一位作者。
    • 一本有一对作者的书将有两行 authorship 行,每行都有一个外键链接到 author 行。
  • author-authorship 关系也是如此:0、1、M 的基数。
    • 已被招募但尚未承诺任何书籍的作者将在 author table 中有一行,但在 authorship.
    • 中没有行
    • 只写过一本书的作者将在 authorship 中占一行。
    • 一位多产的作者在 authorship 中会有很多行,每一行对应 he/she 贡献的每一本书。
  • 必须将 authorship 行分配给一本书并分配给作者:基数 1 与 book 和 1 与 author
    • 我们不允许任何 authorship 行被“孤立”,以使用 parent-child 一些像我这样的人在描述 table 关系时使用的语言。换句话说,在每个 authorship 行上,pkey_book 字段必须有一个有效值,pkey_author 字段必须有一个有效值。

时间

添加时间维度是一个棘手的问题。

一个例子……要跟踪每个作者的图书合同开始和停止的时间段,我们将在 authorship table 上添加一对 DATE 列,标题为contract_start & contract_stop.

  • authorship
    • pkey(这个table的主键)
    • fkey_book(保存作者贡献的书籍的主键值)
    • fkey_author(保存为本书做出贡献的作者的主键值)
    • contract_start(类型 DATE
    • contract_stop

查询 当前有效的合同 会将今天的日期比较为 greater-than-or-equal 和 contract_start AND less-than contract_stop .然后执行 join 以获取书名和作者姓名。

另一个例子……如果我们的出版公司有一个商业政策,即作者必须一次专注于一本书,并希望数据库强制执行作者的合同不能重叠……好吧,那是另一个问题。我不会解决这个问题有几个原因,其中之一是我不知道你的问题是否有这个问题。

Plane-Flight-Location

至于您的飞机问题,我猜 Send 您指的是航班。如果是这样,为了清楚起见,我将命名为 table flight。按位置,我想你的意思是机场。同样,为了清楚起见,我将命名为 table airport

如果这就是您的意思,那么您的基数与上面讨论的完全相同。

  • 加入机队的飞机可能从未飞过、飞过一次或飞过许多地方。所以,0-1-M。
  • 我们的系统可能会在我们将任何飞机飞到那里之前就知道某个机场,因此航班排数为零。稍后,当我们安排一架或多架飞机飞往该机场时,一个或多个航班排。所以,0-1-M.

flight table 包含 date-time 出发时间和持续时间的列。

  • flight
    • pkey(这个table的主键)
    • fkey_plane(持有飞机在date-time飞往该机场的主键值)
    • fkey_airport(保存主键值f 这架飞机起飞的机场是 date-time。)
    • departure(航班起飞时,类型TIMESTAMP WITH TIME ZONE
    • duration(这次飞行的时长,分钟数)。

[plane]-1-----0-1-M-[flight]-M-1-0------1-[airport]

您的业务规则可能会有所不同。如果您计划飞行但尚未分配飞机,那么我们可以有 flight 行没有分配飞机。因此 1 的基数变为 0 or 1。但不是 M,因为一个特定的航班永远不会涉及多架飞机。在此业务规则的情况下,flight 行可以被孤立,缺少 plane parent 直到最终分配特定平面。

[plane]-1-0-----0-1-M-[flight]-M-1-0------1-[airport]