我多次遇到以下情况,想知道关于这种情况的最佳实践是什么:
当用户完成一些操作时,行被插入到表格中。例如,每次用户访问网站的特定部分时,都会插入一行来指示他们的 IP 地址、用户名和引用 URL。在其他地方,我想显示有关这些操作的摘要信息。在我们的示例中,我希望允许管理员登录网站并查看特定用户的访问次数。
最自然的方法 (IMO) 是为每次访问插入一行,每次管理员请求总计时,为该用户计算相应表中的行数。但是,在这种情况下,每个用户可能有成千上万行。如果管理员频繁请求总数,则不断请求计数可能会给数据库带来相当大的负载。因此,正确的解决方案似乎是插入单独的行,但同时在插入数据时保留某种汇总数据和运行总计(以避免一遍又一遍地重新计算这些总计)。
对于这种情况,最佳实践或最常见的数据库模式设计是什么?您可以忽略我编造的具体示例,我真正的问题是如何处理这种处理大量数据和经常请求的数据总计或计数的情况。
最佳答案
这里有一些实践;您选择的那个将取决于您的具体情况:
相信您的数据库引擎 许多数据库引擎会自动缓存常用查询的查询计划(和结果)。即使基础数据发生变化,查询计划本身也将保持不变。索引的适当部分将保留在主内存中,从而几乎可以免费重新运行给定的查询。在这种情况下,您可能需要做的最多的事情就是调整数据库的参数。
非规范化您的数据库 虽然 3rd-Normal Form ( 3NF ) 仍然被认为是合适的数据库设计,但出于性能原因,可能有必要添加额外的表,其中包含汇总值通常会根据需要通过
SELECT ... GROUP BY ...
查询进行计算。这些其他表经常通过使用触发器、存储过程或后台进程来保持最新。有关 Denormalization 的更多信息,请参阅维基百科。 .数据仓库 用 Data warehouse ,目标是将实时数据的副本推送到辅助数据库(仓库)以供查询和特殊报告之用。这通常是使用数据库支持的任何复制技术通过后台进程完成的。这些仓库的索引经常比您的基础应用程序可能需要的索引更严格,目的是支持具有大量历史数据的大型查询。
关于数据库设计 : Running totals of row counts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3134735/