数据库:汇总过期数据
Posted
技术标签:
【中文标题】数据库:汇总过期数据【英文标题】:database: summarizing data which expires 【发布时间】:2010-10-23 00:59:06 【问题描述】:我正在努力为我的数据找到一种高效且灵活的表示形式。我们在两个具有任意生命周期的实体之间存在多对多关系。我们称它们为Voter
和Candidate
。每个关系都有一个衡量标准,我们想以各种方式对其进行总结。这些带有时间戳,并保证在两个相关实体的生命周期内。假设衡量标准是支持率,或者只是Rating
。
一个不寻常的要求是,如果我在总结一个没有测量值的时间段,我应该替换最新的有效测量值,而不是给出 NULL。
我们目前的解决方案是每天编制一份有效选民和候选人名单,然后制定一个多对多表,记录最新的有效措施。
你的解决方案是什么?
这让我可以通过一次查询来获得每日摘要:
select
avg(rating), valid_date, candidate_SSN, candidate_DOB
from
daily_rating natural join rating
group by
valid_date, candidate_SSN, candidate_DOB
这可能工作正常,但对我来说似乎效率低下。我们正在重复大量数据,尤其是在某一天没有发生任何事情的情况下。还不清楚如何在不编译更多表格的情况下进行每周/每月总结。由于我们要处理数百万行(我们实际上并不是在谈论选民投票......)我正在寻找更有效的解决方案。
【问题讨论】:
也许发布一些 SQL 来帮助说明您从哪里开始。表格、查询等 @p.campbell 我添加了一个图表。我们的真实系统更让人眼花缭乱,所以我想解决这个更简单的系统。 也许是一些示例数据,您期望的结果会有所帮助吗? @PerformanceDBA:答案是精心设计的,但没有给出我需要的向下钻取级别。我需要保留每个(有效)选民的历史信息。这是我的问题而不是答案的问题,所以我不确定如何继续。 没问题。我意识到这一点。进步取决于互动。请在功能方面发布您现在所做的确切示例,与您当前令人眼花缭乱的系统(伪代码很好)(a)当前值的计算(例如每日)和(b)相同的集合无关,到期后,出于历史目的。 【参考方案1】:我在这里使用了数据仓库技术,因此使用了 dim
和 fact
表名。
dimDate就是所谓的日期维度,一个日期一行。
dimCandidate 拥有所有候选数据,新旧记录。在数据仓库术语中,这称为类型 2 维度。一个候选人在这个表中可以有几行,其中只有一个有r_status
= 'current'。
字段
, r_valid_from date
, r_valid_to date
, r_version integer -- (1, 2, 3,..)
, r_status varchar(10) -- (expired, current)
描述记录(行)状态。每次候选状态发生变化时,都会插入一个新行并修改前一行的r_valid_to
和r_status
。
CandidateFullName
是业务(自然)密钥,必须唯一标识候选人。没有两个候选人可以拥有相同的CandidateFullName
。请注意,CandidateKey
唯一标识表中的一行,而CandidateFullName
唯一标识一个候选。
dimVoter 拥有选民数据、新旧记录——就像 dimCandidate 一样。
dimCampaign 描述活动详情,这是所谓的第一类维度,不保存历史数据。
factRating 有 Rating 度量。
通常这已经足够了,但是需要插入一天的缺失数据;为此,引入了一个聚合表 aggDailyRating。在一天结束时,计划的作业会汇总当天的评分。这项工作负责数据插值要求。
这样,聚合表对于每个 date-(valid) candidate-campaign
组合都有一行。请注意,选民不包括在组合中,数据是对所有选民进行汇总的。
任何报告都是在汇总表上完成的,例如
--
-- monthy rating for years 2009-2010
-- for candidate john_smith_256
--
select
CalendarYear
, MonthNumber
, avg(DailyRating) as AverageRating
from aggDailyRating as f
join dimDate as d on d.DateKey = f.DateKey
join dimCandidate as c on c.CandidateKey = f.CandidateKey
where CandidateFullName = 'john_smith_256'
and CalendarYear between 2009 and 2010
group by CalendarYear, MonthNumber
order by CalendarYear desc, MonthNumber desc ;
【讨论】:
@PerformanceDBA -- 是的,它们都可以从fullDate
派生,但是我们最终会在 WHERE 子句中得到函数 -- 这种技术的重点是避免这种情况。版本控制工作得很好,试试吧。始终使用业务密钥和r_status
检索最新记录。这是一种标准的、普通的仓储方式——Kimball star。
@PerformanceDBA -- 业务密钥唯一标识Candidate
(人) -- 就像在john_smith_256
中一样。业务键不是表的唯一键,john_smith_256
可以有很多行。
@PerformanceDBA -- 请注意该问题也被标记为data-warehouse
。
@Damir:标题是“数据库”,但是如果标签中包含DataWarehouse,我必须道歉。我将删除我的 cmets 并用更合适的东西替换它们,重新区分 DB 和 DW。
@Damir:漂亮、经典的 DW(但不是 DB)解决方案。 @Bukzor:您需要决定是否需要 DB 或 DW 解决方案;每个都有缺点/优点和固有的局限性。【参考方案2】:
是的,这是非常低效和浪费的。它只是一组文件,不能合理地与一组“表”或“数据库”相提并论;对它的扩展和增强将加剧重复和低效率。复制是数据库的对立面。在数据库方面,有更有效和更简单的方法来实现它。
假设
你的帖子没有提供太多信息,所以我不得不做出一些假设,但我认为如果其中任何一个不正确,你可以很容易地纠正我的提交。否则评论,我会更正我的提交。
选民是一个人;候选人是选民; (候选人 = 选民的子集)
活动与候选人相关(与投票活动无关)。
民意调查是对选民对候选人表现的反应的调查,从设定的日期开始,持续几天,并在设定的日期完成。
每次民意调查都会调查许多措施,例如 ApprovalRating。
所有选民的此类调查的衡量标准在投票级别汇总。
限制
到期要求不明确,所以我并不是说我已经实施了。如果模型没有为您提供(如果不是很明显),请提供详细信息,我将添加到模型中。当前模型为我理解的到期要求提供了排除/包含功能。
Poll::Measure 没有足够的信息来完全实施;我需要更多细节。提交是原始的,在该领域不受限制。
同样,任何 Poll::Campaign 关系或约束(“每个广告系列有很多投票,它们总是与广告系列相关”)尚未实施。
目前子表中key的排列是任意的:如果你确定了最常见的查询,可以重新排列,这样最多的查询速度最好。
提交
Campaign Poll Data Model
这只是一个关系(规范化;零重复)数据库,纯 IDEF1X,包括考虑到子表会很大的规定:将窄代理键迁移到子表中,避免迁移宽键.
它按原样提供“数据仓库”功能。事实上,如果它在单个查询中没有提供任何 BI 或 DSS 要求,那只是因为您缺乏详细信息;请提供,我会很乐意改变它。 (请注意,您的项目“单个查询”实际上是“单个文件”;连接在关系数据库中是行人。)
诸如 %Code 之类的键是 2 个、3 个和最多 4 个字符。这样的键与整数键一样快,并且在细读表时非常有用(有意义)(无需加入父级)。
任何和所有聚合,无论是加载历史行还是为当前值生成聚合,都应该可以在单个关系(面向集合)命令中实现;您不需要求助于串行(光标)处理。同样,如果您认为需要,请发表评论,我将提供面向集合的方法。
我们在 DB 中实现版本控制的方式与在 DW 中实现的方式完全不同,而且没有限制。请确定您是否需要(例如)候选人的版本控制,我会提供。
最后,Null 要求并不罕见。它在这里迎合。再说一次,如果你认为它不是......
【讨论】:
以上是关于数据库:汇总过期数据的主要内容,如果未能解决你的问题,请参考以下文章