2013-08-02 27 views
6

我正在寻找一种有效的方式来存储事件期间一起发生的对象集合,以这种方式我可以每天在其上生成聚合统计信息。如何存储事件期间一起发生的对象集?

举个例子,让我们想象一个跟踪办公室会议的系统。对于每次会议,我们都记录了多长时间以及它发生在哪个房间。

我希望统计人员和房间的统计数据。我不需要跟踪个人会议(所以没有meeting_id或类似的东西),我只想知道每日聚合信息。在我的真实应用程序中,每天有成千上万的事件,因此单独存储每个事件是不可行的。

我希望能够回答这样的问题:

在2012年,多少分钟没有鲍勃,山姆和朱莉花费在每个会议室(不一定在一起)?

也许还不错,要做到这一点有3个查询:

>>> query(dates=2012, people=[Bob]) 
{Board-Room: 35, Auditorium: 279} 
>>> query(dates=2012, people=[Sam]) 
{Board-Room: 790, Auditorium: 277, Broom-Closet: 71} 
>>> query(dates=2012, people=[Julie]) 
{Board-Room: 190, Broom-Closet: 55} 

在2012年,没有萨姆和朱莉多少分钟花费在每个会议室TOGETHER会议?鲍勃,萨姆和朱莉一起怎么样?

>>> query(dates=2012, people=[Sam, Julie]) 
{Board-Room: 128, Broom-Closet: 55} 
>>> query(dates=2012, people=[Bob, Sam, Julie]) 
{Board-Room: 22} 

在2012年,多少分钟没有每个人在董事会室度过?

>>> query(dates=2012, rooms=[Board-Room]) 
{Bob: 35, Sam: 790, Julie: 190} 

在2012年,多少分钟是董事会室使用?

这实际上很困难,因为总结每个人花费的分钟数的天真策略会导致严重的重复计算。但是,我们或许可以通过存储数量分别解决这为元人任何人:

>>> query(dates=2012, rooms=[Board-Room], people=[Anyone]) 
865 

什么是我可以使用,使这种查询的一些良好的数据结构或数据库?由于我的应用程序的其他部分使用MySQL,我很想来定义保存每个人在会议(排序)的ID字符串列,但该表的规模将很快增长:

2012-01-01 | "Bob"   | "Board-Room" | 2 
2012-01-01 | "Julie"   | "Board-Room" | 4 
2012-01-01 | "Sam"   | "Board-Room" | 6 

2012-01-01 | "Bob,Julie"  | "Board-Room" | 2 
2012-01-01 | "Bob,Sam"  | "Board-Room" | 2 
2012-01-01 | "Julie,Sam"  | "Board-Room" | 3 

2012-01-01 | "Bob,Julie,Sam" | "Board-Room" | 2 

2012-01-01 | "Anyone"  | "Board-Room" | 7 

我还可以做些什么?

+1

因此,为了澄清,你有一个bajillion“会议”发生,所以你在一天之内汇总它们。这意味着你有十分钟的时间用于房间交叉路口人行天(我们称之为R U P U D)。您需要R U(P1路口P2路口P3)U D,您不必存储每次会议的方式...... – Temuz

+0

是的!如果我们存储了meeting_ids,我们可以抓住UNIQUE meeting_ids,然后查找每个会议的信息,但这将是MySQL聚合的大量记录。 –

+0

这些查询集是固定的还是可以更改的?我的意思是,当Julia和Bob不在这个会议的Borad会议室时,可以找到所有的时间。我认为会议ID在这里并不重要,因为我们可以通过组合时间和BoardRoom获得独特的会议。 – AKS

回答

0

您的问题有点不清楚,因为您说您不想存储每个单独的会议,但是您如何获取当前的会议统计信息(日期)?另外,即使有很多记录,任何给定正确索引的表格都可以非常快速。

您应该可以使用像log_meeting这样的表格。我想它可能包含这样的内容:

employee_id, room_id, date (as timestamp), time_in_meeting 

凡外键员工ID员工表和房间ID钥匙室的桌子

如果指数员工ID,房间ID,和日期,你应该有作为mysql多列索引左右移动的一个非常快速的查找,以便在搜索时获得索引(员工ID,员工ID +房间ID和员工ID +房间ID +时间戳)。这是在的多指标解释部分更多:

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

0

通过拒绝来存储会议(和相关对象)单独,你正在失去的原始信息来源。

除非您定期记住所有可能每天(或每月或每周或每月)可能需要质疑的综合清单的广泛列表,否则无法弥补数据的丢失!

相信我,这将是一场噩梦......

0

如果人数是恒定的,而不是非常大,那么你可以分配到每个人的存在或不存在一列,存放室,日期和时间在3列以上,这可以消除字符串拆分问题。

而且通过你的问题的性质,我觉得首先你需要分配ID一切的房间,人,等无需在DB长期重复字符串。还可以尝试减少任何字符串操作,并使用每列中的单个数据来获得更好的交集性能。你也可以在表中存储所有人的排列并为它们分配一个ID,然后在实际的日期和时间表中使用这些ID中的一个。但是,所有的技术都需要人们或房间不变的东西。

0

我不知道你是否知道在设计时的所有“问题”或有可能在开发/生产时间增加新的 - 这种方法需要保持所有数据的所有的时间。

那么,如果你会知道你所有的问题,这似乎是经典的“银行系统”,它重新计算每天的基础上的数据。

如何我想它。

  1. 好像你有有限的房间,人,天等
  2. 号收集每天的基础上记录数据,每天一个表。只需一个事件,一个数据库行,所有信息(字段)就是你需要的。
  3. 开始在“午夜”使用一些crone脚本来分析数据。
  4. 人,客房,更新统计等只是增加由鲍勃在某某房间等你的所有要求,需要什么花了几个小时数。
  5. 作为分析的数据是有限的和相对较小的为您分析(压缩)他们,你的系统还可以包含各种查询,指标将相对较小等

您可能能够使用可扩展的map/reduce算法。

0

你无法避免存放原子事实如下:(会议室,对人民,持续时间,日),这可能是只有当同一人相遇在同一个房间里多次弱势盘整同一天。也许这在你的办公室发生很多:)。

制作组可比较是一个有趣的问题,但只要你总是构成成员字符串相同,你可以用字符串比较。但这不是“正常”。为了规范化,你需要一个关系表(多对多),并从你的查询集合中构建一个临时表,以便快速加入,或者使用“IN”子句和计数聚合来确保每个人都在那里(你会看到我的意思是当你尝试它时)。

我认为你可以得出董事会会议室使用的会议记录,因为会议不应该重叠,所以一定会有效。

为了提高存储效率,使用整数键作为查找表的所有内容。在查询解析期间解引用整数,或者如果您感觉传统,则只使用优秀的旧联接。

这就是我将如何做到这一点:)。

相关问题