在像SO这样的网站上,我确信绝对有必要存储尽可能多的聚合数据,以避免在每次页面加载时执行所有那些复杂的查询/计算。例如,存储每个问题/答案的投票计数的运行记录,或存储每个问题的答案数量,或者查看问题的次数,以便不需要经常执行这些查询。
但这样做是否违反了数据库规范化或任何其他标准/最佳实践?这样做的最佳方法是什么,例如,如果每个表都有另一个聚合数据表,它应该存储在它所代表的同一个表中,何时应该更新聚合数据?
由于
答案 0 :(得分:5)
存储汇总数据本身并不违反任何普通表格。规范化仅涉及由于功能依赖性,多值依赖性和连接依赖性而导致的冗余。它不涉及任何其他类型的冗余。
答案 1 :(得分:4)
要记住的短语是“正常化直到它受伤,反正常直到它起作用”
这意味着:规范化所有域关系(至少为第三范式(3NF))。如果您衡量的是性能不足,那么调查(并测量)非规范化是否会提供性能优势。
所以,是的。存储汇总数据“违反了”标准化。
没有“一种最好的方式”去反规范化;这取决于你对数据做了什么。
非正规化的处理方式应与过早优化相同:除非您已经测量了性能问题,否则不要这样做。
答案 2 :(得分:-1)
太多的标准化会影响性能,所以在现实世界中你必须找到平衡点。
我以两种方式处理过这样的情况。
1)使用DB2我使用了一个MQT(物化查询表),它只是一个视图,它只是由查询驱动,你可以安排你想要刷新的频率;例如每5分钟一次。然后该表存储了计数值。
2)在软件包本身中,我将这样的信息设置为系统变量。因此在Apache中,您可以设置系统范围的变量并每5分钟刷新一次。然后它有点准确但你每五分钟只运行一次“count(*)”查询。您可以让守护程序运行它或让它由页面请求驱动。
我使用了一个包装类来做它所以它已经有一段时间了,但我认为在PHP中它很简单: $ _SERVER ['report_page_count'] =数组('timeout'=> 1234569783,'count'=> 15);
尽管如此,无论您存储该单个值,它都可以避免您在每次请求时运行它。