2008-12-05 167 views
0

这是一件让我一会儿怀疑,所以我认为这将是一个好主意,它张贴在这里找到一些见解,这是一个关系型数据库建模问题/疑问建模关系的实体问题

我有以下问题:

我有“疑问”,必须在特定的“状态”,并且必须审计所有状态变化。

我发现了两个解决方案,但我无法真正看出它们之间的区别,如果有任何...您有什么想法。

这里是两张图的图像。

编辑:

选项A:表 “问题” 不应该包含STATE_ID和Question_State不应包含 “id” 字段。对不起,错误。

EDIT2

感谢所有现实世界的例子和洞察力,但是这是一个学术问题,而不是现实世界相关的:)。

Diagrams http://i38.tinypic.com/2v27epl.png

回答

5

我想你问的要点是:如果问题的状态,根据在具有时间分量(A)的问题和状态之间的中间表上,或者该表格应该更加静态,但在侧面(B)上具有以日志为导向的历史表格。 (注意:如果你想做一个纯粹的(A)版本,那么Boofus是正确的,你也许不会把State_id放在Questions表中,因为它是多余的;但是这肯定会很不方便因为它会使得查询在特定状态下的问题变得更加困难,所以你在这里有一个混合版本。)

一般来说,如果保留关于状态的历史信息的要求只是出于审计目的 - 也就是说,如果它不会被应用程序本身定期查询 - 您可能会更好地使用选项B,因为它更简单一些(真正只有一个“问题”表,其中有一个参考表状态和以前状态的“日志”表)。我认为这会让你的意图更好一点。然后,如果应用语义更复杂(例如,如果您有像“在过去24小时内显示状态X中的​​所有问题......”的查询),那么像(A)这样的方法可能会更有意义。它本质上是将问题的状态变为与时间相关的事实。如果你这样做了,那么请注意它使事情变得复杂 - 要么你的所有查询都更加困难,而且必须考虑时间,否则你不得不担心保持问题的state_id与Questions表中的最新状态保持同步。如果你走这条路线,可能会把它称为“current_state”或其他问题,所以很明显这是一种衍生信息。

0

一旦你所有的关系画,它们是相同的。

我不明白你为什么在问题表中有state_id - 因为你有历史表,所以让问题表中的状态是多余的,并且可能会给你带来不同步的数据。

在我看来,如果你想在一个问题目前的状态,你做

SELECT STATE_ID从历史WHERE Question_id =? ORDER BY日期DESC LIMIT 1

(或其他方法,您的SQL味道使用限制到只有1行)

+0

这使得像“SELECT * FROM Questions WHERE status ='X'”这样的查询更难写。 – 2008-12-05 17:14:58

0

假设您在数据库和OO之间有很好的抽象层,您可以考虑将State表从数据库中取出并将其作为类中的枚举。这不一定是需要坚持的东西。

然后在问题表和审计表中有状态列。

+0

这不是问题,但无论如何感谢! – 2008-12-05 22:39:11

0

你说审计,这意味着你只是为了报告的目的而保留历史信息。在这种情况下,我建议图B更清晰,但您应该标记问题与历史,州与历史之间的一对多关系。

至于实用性,如果情况如上所述,我自己会将历史插入功能封装到问题的插入/更新触发器中,并且如果问题表的量和/或状态改变的数量正在很重要,我会考虑把历史表放在不同的数据库中。这稍后会简化数据库管理。通常我会对触发器保持警惕,因为过度热情的使用可能会导致难以维护的数据库(因为它不是很明显会发生什么),但这是一个明显的例子,它们非常合适,并且是使用应用逻辑。

顺便说一句,你的两个图表意味着一个问题只能进入每个状态一次(从你的PK) - 你应该考虑这是否正确,因为在大多数现实世界的应用程序中会犯错误并且状态会颠倒。

1

你可能想冲刷网络上的“时态数据库”的主题。基本上,存储任何变量的变化历史都会引发同样的问题,无论变量是捕获问题状态还是人的体重或其他问题。

其次,我认为你的问题涉及数据库设计,而不涉及概念数据建模。如果我正确地确定了你的位置,你会问哪个餐桌设计更好。

第三,我更喜欢选项B,但实际上取决于您要对数据做什么。

我问到数据库设计与概念建模的原因是我很久以前就采用了使用“实体和关系”进行与数据分析相关的概念数据建模的做法。在讨论逻辑数据库设计时,我使用术语“表格,列和行”。独立分析和设计在大型项目中非常有价值。听起来并不像听起来那么容易。

你真的应该在历史表和状态表之间的选项B的图表中添加一个箭头。图表的显示方式,它几乎看起来像历史表是一个不相交的表。在这个简单的例子中,这不是一个问题,但是如果在扩展到数十个数据库的数据库时保持相同的习惯,最终会让每个查看图表的人感到困惑。

0

我不明白,像#Boofus,在问题表中有一个state_id字段的兴趣。

在我们自己的应用程序中,我一直在使用这种“状态”概念。在最复杂的情​​况下,我们必须遵循一个完整的状态,历史和物件的情况可以有多个状态,我们使用下面的模型:

alt text

对于多状态的情况下,这个想法是检查end_date值是否为空(另一个想法是在表中有一个布尔型字段isActiveState)。不要低估拥有这种“多态”配置的兴趣。例如:

一个问题可以是

  • 闭合和解决

  • 封闭和没有解决。

这可以对应于任一2种不同的状态:

  • “闭合和解决” 状态

  • “闭合和没有解决”状态

但我认为最好的解决办法是同时拥有

  • A “开/关” 状态

  • A “解决/未解” 状态

并允许问题具有multipl e状态