您将如何在关系数据库中对此进行建模?
Posted
技术标签:
【中文标题】您将如何在关系数据库中对此进行建模?【英文标题】:How would you model this in a relational database? 【发布时间】:2022-01-11 09:04:36 【问题描述】:我有三张桌子:Books、Sagas 和 Universes。 Books 有 idSaga 作为外键。 Sagas 有 idUniverse 作为外键。
它们都是一对多的关系。
一本书可以是一个传奇的一部分,而这个传奇是更大宇宙的一部分;比如:魔戒和魔戒是魔戒传奇的第一部,魔戒在传奇宇宙中。
我应该如何称呼像《霍比特人》这样的书?它不是任何传奇的一部分,而是传奇世界的一部分。
我不想在表 Books 中添加一个新字段(用于外键),它看起来像破坏规范化。 添加新表以及书籍和 Universe 之间的关系看起来有点过分。
【问题讨论】:
【参考方案1】:我不想向表 Books 添加一个新字段(用于外键),它看起来像破坏规范化。
这正是我会做的。我不确定您所说的“它看起来像破坏规范化”是什么意思,但对我来说这似乎很理想,因为 Book -> Universe 关系可能很有用。
例如,假设您有一个新功能,您想计算给定宇宙中的所有书籍。如果您在 books
表中没有外键,则必须查询 sagas
表以获取与 sagas 无关的信息。
通过排除此外键,您将限制将来使用此关系的选项。
总之,我会去:
Books M:1 Saga
Books M:1 Universe
Saga M:1 Universe
我也同意另一个答案,即一本书可能存在于多个宇宙中,但是否允许由您决定:)
【讨论】:
【参考方案2】:如果 a 书“不是 a Saga 的一部分”,这会破坏某种形式的逻辑——否则 Book 和 Saga 都需要暗示 Universe,然而一本书可能意味着与它所属的传奇不同的宇宙。
如果每本书都是一个传奇的一部分,即使只是一本书的传奇(霍比特人是《霍比特人》中唯一的一本书),这个核心问题就会得到解决霍比特人传奇.. 目前;-))。
在基本形式中,如当前描述的那样,它防止出现此类矛盾的可能性,并允许以一致的方式编写查询1,无论如何一个传奇里有很多书。
Books M:1 Saga
Saga M:1 Universe
使用此模型的另一个原因是,每本书都在a Saga 中,它也适用于尚未建立的第一本 Saga 书籍(也许后续书籍还没有甚至已经计划好了)。
当然,根据所需的细化分类,对于某些漫画书之类的跨界书,这可能不够灵活(阅读:太简单)。也许传奇中并非所有书都共享同一个宇宙。如果这样的怪事是可能的,那么一本书就需要与 Universe 建立非 Saga 关系。
1 虽然使用视图可以相对简单地处理查询复杂性,但避免矛盾会增加模型的复杂性。一种方法是要求书成为传奇或宇宙的一部分;不是两者兼而有之。
【讨论】:
以上是关于您将如何在关系数据库中对此进行建模?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 RavenDB 等面向文档的数据库系统中对分层和关系数据进行建模?