在关系数据库中实现1到0..1关系的正确方法

问题描述 投票:0回答:1

想象一下,在我们的数据模型中,我们有一个实体(数据结构),它具有可选的部分。我们可以将这些“部分”实现为对其他(子)实体的可空引用。换句话说,主实体的每个实例可能具有或不具有与其关联的其他(子)实体的单个实例,并且子实体的任何实例都仅具有与其关联的主实体的一个实例。所以我们有1到0..1的关系。

例如,审核日志记录具有公共字段,如(时间戳,用户,操作)以及特定于操作的部分(扩展信息),对于不同的操作,它们可以完全不同。我们可以使用单独的实体表示每种类型的扩展信息,然后使主实体对每种可能的扩展信息类型具有可为空的引用。

我可以看到在关系数据库中实现它的两种方式:

1。对主记录中子实体的可空引用

对于每种类型的子实体,主记录表都有一个字段,该字段将子表(扩展)表中的记录的ID引用为外键。

这似乎是更简单的选择:要检索相关信息,我们只需遵循直接参考。在SQL查询中,我们将通过外键左联接子(扩展)表。外键的空值将为我们所有子表的字段提供空值。

2。子实体的记录参考主实体的记录

我们不在主实体表中存储任何引用。而是,子实体表的每个记录都将ID作为外键引用主表中的一条记录。在SQL查询中,我们仍然将子表连接到主表,而对于没有相应子记录的所有子表字段,我们将获得空值。

???

哪种方法是正确的?第二个似乎更多relational,并且我们不必在主表中创建额外的字段,但是从技术上讲,它可能需要更多的工作来找到相关记录,因为我们必须搜索而不是遵循直接引用子表中的主ID。还是DB引擎会快速优化这种连接,例如使用索引?索引搜索比扫描更快,但比直接参考慢。加号索引占用空间。我对DB引擎如何工作缺乏知识……或者也许我只是想念一些显而易见的东西。帮助将不胜感激。

database-design relational-database database-normalization
1个回答
0
投票

在这种情况下,我认为“最佳”解决方案取决于数据库的工作量,因为这两种解决方案都有其优点和缺点。

第二种解决方案在理论上更正确(规范化),但也有实际好处:它需要的空间较小(因此,对于某些类型的操作,该关系更紧凑,并且需要更少的时间进行操作)。另一方面,它需要联接才能访问详细数据(因此,这些操作需要一个额外的索引)。

第一种解决方案从概念上讲更简单,在访问详细数据的情况下不需要连接,但是需要更多空间,这会减慢某些类型的操作的速度。

这两种解决方案都在实际环境中使用。

我认为,只有通过知道必须在这样的数据库上部署的应用程序的典型工作量是什么,才能提供此难题的解决方案:某些查询相对于其他查询更频繁(或必须具有更少的延迟)?例如,使用仅查看常规数据的查询比需要详细数据的查询使用的频率更高?

最后,如果很难或不可能进行这种“理论”分析,则唯一的另一种方法是尝试一种解决方案,但是如果性能不令人满意,则准备好尝试另一种解决方案。例如,可以通过使用视图来完成此操作:

  1. 从第二个解决方案开始,并定义一个进行联接的视图。

  2. 通过在适当时使用基表或联接视图来编写应用程序。

  3. 如果性能不令人满意,请通过连接创建一个具有旧视图名称的新表,并通过联接创建新表,并定义一个仅对不为null的属性执行投影的新视图。 >

  4. 通过这种方式,应用程序只需要最少的修改集,就可以尝试其他方法。

© www.soinside.com 2019 - 2024. All rights reserved.