直接加入或存储

时间:2012-09-30 14:39:00

标签: sql database database-design rdbms

我有一个表A,其中包含我经常处理的条目并将结果存储在表B中。现在我想确定A中每个条目的最新处理日期在B中。

我当前的实现是加入两个表并检索最新日期。然而,另一种可能不太灵活的方法是直接将日期存储在表A中。

我可以考虑两种情况的优缺点(性能,可伸缩性......),但还没有这样的情况,并且想看看stackoverflow上的某个人是否有类似的情况并且有一个建议其中一个是出于特定原因。

快速架构设计。

Table A
id, some-data, [possibly-here-last-process-date]

Table B
fk-for-A, data, date

由于

4 个答案:

答案 0 :(得分:2)

根据您的描述,听起来表B是您的历史(或存档)表格,并且它是按批次填充的。

我会单独留下表A,只介绍id和date的索引。如果历史表很大,请为表B引入自动增量PK,并有一个单独的表将B-Pkid映射到A-pkid。

我不喜欢仓库桌上的UPDATE,这就是为什么我不推荐使用CURRENT_IND,但这是另一种选择。

答案 1 :(得分:1)

这是一个相当典型的问题;有很多合理的答案,但只有一种正确的方法(在我看来)。

你基本上问“我应该对我的架构进行非规范化吗?”。我相信你应该只在你确实需要时才对你的架构进行非规范化。您知道必须的方式是因为您可以证明 - 在当前或预期的情况下 - 您在实际查询中遇到性能问题。

在现代硬件上,使用经过良好调整的数据库,通过连接查找表B中的最新记录几乎肯定不会产生明显的性能影响,除非您拥有大量数据。

所以,我的建议是:创建一个测试系统,用系统所需的两倍数据填充两个表,然后运行生产环境中的查询。检查查询计划,看看是否可以优化查询和/或索引。如果你真的无法使其工作,请对表进行反规范化。

虽然这可能看起来很多工作,但非规范化是一个大问题 - 根据我的经验,在一个中等复杂的系统上,非规范化的数据模式是许多愚蠢错误的核心。它使新开发人员更难以引入,这意味着应用程序级别的额外复杂性,额外的代码意味着更多的维护。在您的情况下,如果更新表A的代码失败,您将在不知道它的情况下产生虚假结果;未检测到的错误可能会影响大量数据。

答案 2 :(得分:0)

我们的项目跟踪系统也有类似情况,项目的最新状态存储在projects(Cols: project_id, description etc.,)中,项目历史记录存储在project_history中表格1}}。每当项目有新的更新时,我们都需要找到最新的更新编号并添加1以获取下次更新的序列号。我们可以通过将(Cols: project_id, update_id, description etc.,)列上的project_history表分组并获得project_id来完成此操作,但考虑到项目更新的数量(数百个),成本会很高成千上万)和更新的频率。因此,我们决定将值MAX(update_id)表中的值存储在projects列中,并在给定项目的新更新时继续更新它。 HTH。

答案 3 :(得分:-1)

如果我理解正确,你有一个表,其每行是一个参数,另一个表以历史的方式记录每个参数值的时间序列。如果这是正确的,我目前在我正在构建的产品中具有相同的情况。我的参数表包含度量列表(29K recs),历史参数值表每1小时具有该参数的值 - 因此该表当前具有4M行。在任何给定的时间点,对于最新值的请求将比历史记录要多得多,因此除了它在参数值表的最后一个记录中之外,我还在参数表中存储了最新值。虽然这可能看起来像重复数据,但从性能的角度来看,它非常有意义,因为

  1. 要获取所有参数及其CURRENT VALUE的列表,我不必进行连接,更重要的是
  2. 我不必从这么大的表中获取每个参数的最新值
  3. 所以是的,在你的情况下,我肯定会将最新的值存储在父表中,并在每次新数据进入时更新它。对于编写新数据来说会慢一点但读取速度会快得多