【发布时间】:2020-10-27 03:15:29
【问题描述】:
我正在建立一个数据库,我希望在某些表之间建立多对多关系。这个数据库没有用户界面;我们将使用 R 脚本将数据放入表中,并使用 Python 脚本检索它。
所涉及的实体是项目和成本预测。多个项目可能使用相同的预测。对于每个预测,在未来几年的每一年中开发一个项目都会产生成本。我需要能够为每个单独的项目检索未来每一年的成本预测。
我认为下表是表示这些关系的一种相当标准的方式。请注意,“pk”表示“主键”,“fk”表示“外键”。
PROJECT
name
forecast_id (fk)
FORECAST
forecast_id (pk)
COST
forecast_id (fk)
year
cost
要检索特定项目的预测,我只需检索COST 中与forecast_id 匹配的所有行。我不需要 FORECAST 表做任何事情,除了作为 forecast_id 的家,它在 PROJECT 和 COST 之间建立了多对多关系。
所以我的主要问题是,我可以直接删除FORECAST 表并使用forecast_id 在PROJECT 和COST 之间建立直接的多对多关系吗?我知道这在物理上是可能的,但许多讨论使用的语言是“没有桥接表就不可能建立多对多关系”。但是,如果我可以在没有它的情况下执行所有查询并且它是我必须维护的另一个表,我为什么要添加桥表?
更进一步,许多关于多对多关系的讨论(包括下面@mike-organek 的评论)都提出了与此类似的结构:
PROJECT
project_id (pk)
name
PROJECT_COST
project_id (fk)
cost_id (fk)
COST
cost_id (pk)
year
cost
虽然这似乎是一种普遍首选的方法,但它更不适合我的需求。现在,每次我添加一个新项目时,我必须将一堆链接记录添加到 PROJECT_COST 表中,而不是仅仅分配与特定预测对应的forecast_id,每个未来一年一个。这也需要大量的管理,并允许潜在地创建我不想要的关系(例如,一个项目使用前两年的一个预测的成本,然后使用未来两年的不同预测的成本)。
所以我的第二个问题是,第二种方法是否比第一种方法或我的简化方法(仅使用 PROJECT 和 COST 表)更可取?
更新
我在这里问的内容似乎有些混乱。因此,我对问题进行了重大修改,以使其更清楚。请注意,我将 cost_group 重命名为 forecast 作为其中的一部分。
【问题讨论】:
-
这如何让你的生活变得更糟?项目跨越数年吗?如果是这样,那么您必须在
project和project_cost之间有一个多对多连接表。拥有该链接恰好还使您能够在项目之间共享预测(按年份)。你有更好的选择吗? -
是的,每个项目在 COST 表中可能有多个匹配的行(即对未来多个年份的预测)。我不确定您要问的是哪种规范化,但两者都让我的生活变得更糟,因为它们包含我必须创建并保持一致的额外表。为什么我不应该在 PROJECT 和 COST 中的外键之间实现直接的多对多关系,如第一个示例所示? (相当于拥有一个我从不费心创建的虚拟 COST_GROUP 表。)
-
我读错了吗?项目跨越数年。在给定的年份,一个项目与一个 cost_group 相关联。给定年份的 Cost_group 具有成本值。如果这是真的,那么您应该将 Project、Year、Cost_group 表作为您的独立实体。 project_year 连接表确定项目在一年内有效。 cost_group_year 连接表为 cost_group 建立一年的成本值。 project_year 到 cost_group_year 的连接表 (project_year_cost) 完善了您的模型,该模型将特定项目在特定年份使用的成本模型关联起来。
-
遵循已出版的有关信息建模、关系模型和数据库设计与查询的学术教科书。 (记录和使用设计的语言和工具手册不是这样的教科书。)(维基文章或网络帖子也不是。)数十种已出版的学术信息建模和数据库设计教科书以 pdf 格式在线免费提供。 (但是在 SO 之外寻求资源是题外话。)现在这要求我们用定制的教程重写一本教科书。关注一个并询问 1 个明确的特定非重复问题,了解您第一次遇到的问题。
-
@philipxy 感谢您的建议。另一个问题与我的方向不同,我希望得到比“阅读数据规范化教科书”更具体的问题。我认为我的问题归结为“如果链接表本身没有有用的数据,我可以删除它吗?如果没有,我为什么不应该?”我已将问题修改为更具体。
标签: sql database postgresql database-design database-normalization