SQL:加入vs非规范化(大量数据)

时间:2011-10-11 00:44:13

标签: sql join bigdata

我知道,之前已经问过这个问题的变化。但我的情况可能有点不同: - )

所以,我正在建立一个跟踪事件的网站。每个事件都有id和value。它也由用户执行,具有id,年龄,性别,城市,国家和等级。 (这些属性都是整数,如果重要的话)

我需要能够快速获得两个查询的答案:

  • 获取具有特定个人资料的用户的活动数量(例如,来自俄罗斯莫斯科的18-25岁男性)
  • 获得具有特定个人资料的用户的事件值(也可能是平均值) -

此外,数据由多个客户生成,而这些客户又可以拥有多个source_id。

访问模式:数据主要由收集器进程编写,但在查询时(很少,通过web ui),它必须快速响应。

我期待很多数据,当然不止一个表或单个服务器可以处理。

我正在考虑每天将事件分组到不同的表中(即'events_20111011')。此外,我想为表名添加客户ID和源ID前缀,以便数据被隔离并且可以轻易地丢弃(清除旧数据)并相对容易地移动(将负载分配给其他机器)。 这样,每个这样的表都会有有限的行数,比如10M tops。

所以,问题是:如何处理用户的属性?

选项1,规范化:将它们存储在单独的表中并从事件表中引用。

  • (亲)不重复数据。
  • (骗)加入,这是昂贵的(或等等) 我听说)。
  • (con)这需要打开用户表和事件表 相同的服务器

选项2,冗余:在事件表中存储用户属性并将其编入索引。

  • (亲)更轻松的负载平衡(可以移动自包含的表)
  • (亲)更简单(更快?)查询
  • (con)用于重复用户属性和相应索引的大量磁盘空间和内存

3 个答案:

答案 0 :(得分:6)

您的设计应该规范化,您的物理架构可能因性能原因而最终被非规范化。

可以两者兼得吗? SQL Server附带Analysis Server的原因是有原因的。即使您不在Microsoft领域,也可以使用事务系统进行数据输入和日常处理,而报告系统可用于那些会在事务系统上造成重负荷的查询。

这样做意味着您可以充分利用这两个方面:日常操作的规范化系统和汇总查询的非规范化系统。

在大多数情况下,夜间更新适用于报告系统,但这取决于您的营业时间和其他最有效的因素。我发现大多数8-5个企业在晚上有足够的时间来更新报告系统。

答案 1 :(得分:3)

使用OLAP /数据仓库方法。也就是说,以标准规范化方式存储数据,但也存储将在单独的事实表中频繁查询的数据的聚合版本。用户查询不会是实时数据,但通常值得进行性能折衷。

此外,如果您使用的是SQL Server企业,我不会推出您自己的水平分区方案(将数据分成几天)。 SQL Server内置了一些工具可以自动为您执行此操作。

答案 2 :(得分:1)

请标准化

使用分区和索引来平衡负载