数据库优化 - 将每一天存储在不同的列中以减少行数

时间:2012-01-23 17:00:18

标签: database optimization

我正在编写一个按用户和日存储不同类型记录的应用程序。这些记录按类别划分。

在设计数据库时,我们创建一个表User,然后为每个记录类型创建一个表RecordType和一个表Record

实施例:   要存储与用户事件相关的数据,我们有以下表格:

Event         EventType
-----         ---------
UserId        Id
EventTypeId   Name
Value
Day

我们的老板指出(有某种原因)我们要存储很多行(用户*天)并提出一个对我来说有点疯狂的想法:创建一个表格,每天都有一列一年,像这样:

EventTypeId | UserId | Year | 1 | 2 | 3 | 4 | ... | 365 | 366

这样我们每年每个用户只有1行,但我们会得到相当大的行。 由于大多数ORM(我们将使用rails3用于此项目)使用select *来获取数据库记录,我们不是要优化某些东西以“去优化”另一个吗?

社区对此有何看法?

3 个答案:

答案 0 :(得分:5)

这违反了First Normal Form。这是repeating groups across columns的一个例子。

这是坏的原因示例:编写查询以查找给定事件发生的日期。您需要一个包含366个术语的WHERE子句,以OR分隔。这写起来很乏味,而且无法索引。

即使您有很多行,关系数据库也可以很好地工作。假设您有10000个用户,平均每个用户每天生成10个事件。 10年后,您将拥有10000 * 366 * 10 * 10行或366,000,000行。这是一个相当大的数据库,但并不罕见。

如果您仔细设计索引以匹配针对此数据运行的查询,那么您应该能够长时间获得良好的性能。您还应该有一个分区或存档旧数据的策略。

答案 1 :(得分:0)

这打破了DataBase正常形式原则

http://databases.about.com/od/specificproducts/a/normalization.htm

如果它适用,为什么不用事件表中的DateTime列替换Day列,并使用默认值(GetDate()我们正在谈论SQL)

然后你可以按日期分组......

答案 2 :(得分:0)

我不会这样做。只要您花时间对表进行适当索引,数据库服务器就可以很好地处理具有大量行的表。如果它显着降低了数据库性能,我首先要确保您的查询不会强制进行大量的全表扫描。

我看到的其他一些潜在问题:

  • 这可能会伤害ORM的表现。
  • 这会在未来产生可维护性问题。您可能不希望使用一年中每天都有366个字段的对象,因此可能需要大量的样板粘合代码来跟踪。
  • 任何想要搜索一系列日期的查询都将是一个不圣洁的混乱。
  • 可能更浪费空间。这些行很大,您必须为每个客户创建的行数将是一天中每种不同类型事件发生的最大次数的总和。除非所有这些事件发生的速率非常稳定且常规,否则这些行可能基本上是空的。

如果有的话,我建议根据其他专栏对表格进行分片,如果你确实需要缩小表格大小的话。也许是UserId或者年份?