数据库设计中的共享目的表(如何*实现问答设施)

时间:2008-11-25 03:28:22

标签: database-design

我一直认为,涉及共享表目的数据库的设计有点像臭代码的特征,并且逐渐增加了与臭代码相关的问题。

我的意思是,人们过度规范化,使用1个表,其中2个表可能更符合逻辑,人们刚刚发现了规范化并过度使用它们以至于他们虚拟地将数据库分层在数据库上,或者试图天真地使用分层数据来解决他们所有的问题。

问题是,当你有2组数据看起来是相同的,但它们有不同的目的时,你是否使用相同的表来表示它?你什么时候知道什么时候使用它是一个好主意和坏主意?

我一直认为,在同一查询中使用两次表格的不必要的自引用表格或结构在设计,长期性能和未来改进的便利性方面都是一个非常危险的困境

当然,直到我在这里看到RSS提要中的一两件事。现在我不会就SO如何运作进行元讨论,但这里似乎有一个隐含的设计考虑因素挑战了我的想法,并希望在这种逻辑风格上收集更具凝聚力的答案。

您会注意到通用问题的格式为:

 /question/1234/stuff-here-that-s-safe-to-leave-out

我一般认为这意味着问题在某处被数字排序。

但这就是困扰我的原因: 我将以question 316210为例。如果您查看此问题的rss feed,您会注意到该问题有一个条目,以及一系列答案条目,这些条目在功能上与问题条目完全相同,除了一些细微差别。现在注释在答案条目中也有链接引用,...到问题,但不是同一个问题,但是对于不同的问题,例如question 316218,当访问时,会将您重定向回原始问题。

现在我对他们在代码中实现 的方式不感兴趣,问题是你在这里,问题和答案似乎在共享同一个表(因此顺序问题ID) ,当用户引用答案ID时,你必须首先查询数据库,然后去“嘿!,哎呀!,这不是问题!”然后继续执行第二次查询以查找该问题的父级(在同一个表中),然后将您重定向到实际的问题页面,更不用说自加入查询所需的所有喧嚣(我一直认为是肮脏的)和整个地方的条件来调整行为。

少挖掘,真正的问题

问题是,在这里你有2组数据共享同一个表,当然,至少现在这个数据在表面上是相似的,但看起来有那么多技术债务参与。

长期考虑涉及实现可以应用于问题而不是答案的新功能,反之亦然,更不用说避免在某个不起眼的角落中将其解释为另一个。您无法在一个应用程序集中添加新列,而无需在另一个应用程序集中考虑结果效果。

当然,使用单数表有一个小小的好处,当你 制作一个在方面之间共享的功能时,你只需要编码一次,但这可能很容易通过使用祖先类的常用方法表示的子类,以及绑定到不同情况的特定表的子类。因此,至少在这种情况下,添加新功能对其他方案没有后续影响。

现在我在许多地方遇到过这种问题,当然,但是SO是最容易指出的例子。

当您像这样实现数据库时,您是共享表还是分叉?

何时,为什么?

3 个答案:

答案 0 :(得分:3)

我认为从SO的角度来看,问题和回答都是一样的 - 用户帖子。他们碰巧是相关的。如果帖子没有父母,那么这是一个问题。如果帖子确实有父母,那么这就是答案。我发现这完全合理,但我不确定我会做出同样的选择,因为存在一些显着的差异。也许这些存储在单独的表中。

我基本上在我的一个应用程序中做了同样的事情。我跟踪事件。如果事件没有父级,则事件是“主”事件。如果它有父,那么它必须是“主”事件的子事件。它们共享许多相同的基本属性,因此它们共享一个表。 “主”事件具有一些存储在单独表中的附加属性。通常,当我选择子事件时,我已经知道“主”事件,因此不需要单独的查询。

答案 1 :(得分:2)

我们的学生管理系统也有类似的东西,它将应用程序和注册存储在同一个表中。一个应用程序本质上是一个特殊的案例,即在一个尚未激活的课程上注册。在我的情况下,最好以这种方式使用它,因为应用程序很容易升级到注册。

真的,这取决于你最终会如何查询数据,我怀疑Q和A系统会有一个搜索工具,所以这将是想要搜索问题和答案,所以让它们进入是有意义的同桌。此外,问题和答案可能需要相同的额外数据,例如修改日期,发送者...只要确保在表的索引中有一个字段,如果你走这条路线则定义它是一个问题还是一个答案

当你不得不解决你的解决方案时,值得分析,但请记住,因为你最初将它作为一个表,因此通过以后将其分离来运行脚本相对容易。

答案 2 :(得分:1)

首先,

  

人们过度规范化,使用1个表,其中2个表可能更符合逻辑

我发现非规范化数据往往是在更少的表中,而不是更多。

<小时/> 至于“重复使用”表用于多个目的:只是说不!它从第1天开始招聘技术部门。

关系数据库的关键在于模式意味着数据的目的:与其相关的其他数据,其约束等。将两个相似的数据结构楔入一个表而不是制作OOP祖先没有意义类或接口两个类似值对象的类的超集。这与使用该工具相反。

组合它们可确保您为每个实体所需的唯一列创建1-1表,而不能强制进入公共表。您也不能使用R.I.,UNIQUE索引或其他约束,因为其中一个实体将始终破坏它。公共表的每个消费者都需要知道如何区分属于一个实体或另一个实体的行;任何人都无法根据模式对任何事情做出假设。

如果需要,将UNION两个表放在一起很容易,而且该查询甚至可以调整其“常用”模式的更改。