我正在编写一个按用户和日存储不同类型记录的应用程序。这些记录按类别划分。
在设计数据库时,我们创建一个表User
,然后为每个记录类型创建一个表RecordType
和一个表Record
。
实施例: 要存储与用户事件相关的数据,我们有以下表格:
Event EventType
----- ---------
UserId Id
EventTypeId Name
Value
Day
我们的老板指出(有某种原因)我们要存储很多行(用户*天)并提出一个对我来说有点疯狂的想法:创建一个表格,每天都有一列一年,像这样:
EventTypeId | UserId | Year | 1 | 2 | 3 | 4 | ... | 365 | 366
这样我们每年每个用户只有1行,但我们会得到相当大的行。 由于大多数ORM(我们将使用rails3用于此项目)使用select *来获取数据库记录,我们不是要优化某些东西以“去优化”另一个吗?
社区对此有何看法?
答案 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)
我不会这样做。只要您花时间对表进行适当索引,数据库服务器就可以很好地处理具有大量行的表。如果它显着降低了数据库性能,我首先要确保您的查询不会强制进行大量的全表扫描。
我看到的其他一些潜在问题:
如果有的话,我建议根据其他专栏对表格进行分片,如果你确实需要缩小表格大小的话。也许是UserId或者年份?