考虑时间维度时,基数在 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]
我将使用包含两个实体的问题片段来解释我的问题:
飞机
位置
以及与 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]