【发布时间】:2020-05-08 03:32:51
【问题描述】:
想象一下,在我们的数据模型中,我们有一个实体(一种数据结构),它具有可选部分。我们可以将这些“部分”实现为对其他(子)实体的可空引用。换句话说,主实体的每个实例可能具有或不具有与其关联的其他(子)实体的单个实例,并且子实体的任何实例仅具有与其关联的主实体的一个实例。所以我们有 1 到 0..1 的关系。
例如,审计日志记录有共同的字段,如(时间戳、用户、操作)以及特定于操作的部分(扩展信息),对于不同的操作可能完全不同。我们可以使用单独的实体来表示每种类型的扩展信息,然后让主实体对每种可能的扩展信息类型都有可空引用。
我可以看到在关系数据库中实现它的两种方式:
1。对主记录中子实体的可空引用
对于每种类型的子实体,主记录表都有一个字段引用子(扩展)表中记录的 ID 作为外键。
这似乎是更直接的选择:要检索相关信息,我们只需遵循直接引用即可。在 SQL 查询中,我们将通过外键左连接子(扩展)表。外键的空值将为我们提供所有子表字段的空值。
2。子实体的记录引用主实体的记录
我们不在主实体表中存储任何引用。相反,子实体表的每条记录都通过 ID 引用主表中的一条记录作为外键。在 SQL 查询中,我们仍然将子表左连接到主表,并且对于没有对应子记录的所有子表的字段,我们得到空值。
???
哪种方法是正确的?第二个似乎更relational,我们不必在主表中创建额外的字段,但从技术上讲,它可能需要更多的工作来查找相关记录,因为我们不是直接引用我们必须在子表中搜索主 ID。或者数据库引擎是否优化这种连接以使其快速,例如使用索引?索引搜索比扫描快,但仍然比直接引用慢。 Plus 索引占用空间。我填补了数据库引擎如何工作的知识不足......或者我只是错过了一些明显的东西。帮助将不胜感激。
更新
在得到下面的答案后,也有了更多的思考,决定使用第二种方法。除了在接受的答案中所说的(更紧凑,从关系的角度来看更正确,不必处理 NULL),如果我需要删除所有对应的主记录,它还为我提供了使用级联删除的很好的可能性子记录。
【问题讨论】:
-
除非您定义它,否则工程中没有“更好”/“最佳”之类的东西。同样不幸的是,所有合理的实际定义都需要大量的经验,以及与对细节的混乱敏感度相互作用的大量因素。进行简单的设计。当您通过测量证明您可以想到的设计和所有替代方案都存在问题时(无论当时意味着什么),然后提出一个非常具体的问题。这也应该定义“更好”/“最好”。 Strategy for “Which is better” questions
-
@philipxy 感谢您的评论,尽管它没有帮助。我知道这可能看起来像是一个基于意见的问题,但实际上并非如此。我相信这样做有正确和不正确的方法,我只是不知道,这是正确的。我已编辑问题以删除“最佳实践”触发词。
-
您的帖子没有提出可回答的问题,因为它没有提供足够的细节或选择标准。你没有不知道答案的问题。您只是在一些观察中感到疑惑。
-
Philip 的 cmets 不正确,您可以忽略它们。你是对的,你用两个例子给出了一个问题。有很多方法可以解决或部分解决这个单一问题……但只有一种关系(科学上正确)的方法。然而问题是,不了解科学的人会认为这是一个“基于意见”的问题。比如菲利普的评论,以及结束问题的投票。
-
观察接受的答案帖子没有回答您提出的问题并表示无法回答,并重复我的评论“最佳”。
标签: database-design relational-database database-normalization