我正在研究一个数据仓库类项目的数据库设计,它每天涉及大量的插入。数据档案将进一步用于生成报告。我将有一个用户列表(例如,200万用户),为此我需要监视与他们相关的日常社交活动。
例如,假设有一组100个用户,比如U1、U2、.、U100。
我需要将它们的每日状态计数插入我的数据库中。
考虑为用户U1获得的6月30日至7月6日期间的总状态计数如下
June 30 - 99
July 1 - 100
July 2 - 102
July 3 - 102
July 4 - 105
July 5 - 105
July 6 - 107数据库应该保存每个用户的每日状态计数,就像用户U1一样:
July 1- 1 (100-99)
July 2- 2 (102-100)
July 3- 0 (102-102)
July 4- 3 (105-102)
July 5- 0 (105-105)
July 6- 2 (107-105) 同样,数据库应该保存完整用户的日常详细信息。
在稍后阶段,我设想从这些数据中提取汇总报告,比如在每一天、每周、每个月等的得分,并将其与较早的数据进行比较。
我得从头开始。我对PHP作为服务器端脚本和MySQL很有经验。我在数据库方面感到困惑。既然我每天需要处理大约一百万次插入,那么应该处理的事情是什么呢?
在这方面,我对如何设计MySQL数据库感到困惑。要使用哪个存储引擎,应该遵循哪些设计模式,同时铭记数据以后可以有效地与聚合函数一起使用?
目前,我设想使用一个表来设计DB,该表存储所有用户的id,每天都有一个外键和单独的状态计数表。
MySQL是否符合我的要求?每天都要执行200万或更多的DB操作。在这种情况下,如何考虑服务器和其他事情?
所涉及的问题:
插入查询应该能够每天插入120万个插入。(我们这里没有最新消息。)
1.所有用户的状态之和。
2.地理位置下一组用户的状态之和。
3.将状态计数与天数/周/月进行比较。
请指点?
发布于 2014-07-30 09:47:32
这些都是一般性建议,因为您没有显示要执行的查询的全部范围(您计划进行哪种分析)。
假设您不需要实时结果,您应该在周期结束时对数据进行去或删除,在所有必要的时间框架-by日、按周、按月预先计算聚合结果一次,并且只使用汇总表。根据您打算执行的查询,您甚至可能不需要原始数据。
如果持久性不是问题(您可以像其他地方的原始数据一样重新计算统计数据),那么您可以使用缓存机制(外部的,或者MySQL 5.6包括memcache),这对于在内存上写入和读取键值数据非常有用。
使用分区(也可以手动完成),与这类应用程序一样,通常最频繁访问的行也是最近的。删除旧行或将旧行存档到其他表中,以有效地使用内存。
如果您想要持久、高并发写入,并且您最频繁访问的数据将被放入内存中,请使用Innodb。也有TokuDB-它可能不是raw更快,但它更好地处理巨大的高表上的插入,并允许磁盘上的压缩。也有像知音这样以分析为重点的引擎。
23次插入/秒在任何有坏磁盘的存储中都是可行的,但:
SUM()统计数据不会在普通的MySQL引擎上进行缩放。同样,索引可以提高性能,因为大多数操作都可以在内存上完成,但是每一行的一个条目仍然必须在一个线程中读取。我提到了设计备选方案(汇总表、缓存)和替代引擎(基于列)作为解决方案。但是,如果您不需要实时结果,而是需要类似于报表的查询,那么您不应该太担心这个问题。
我建议你用假数据做一个快速的负载测试。我有很多客户在社交网络的MySQL上进行分析,没有问题(至少在我帮助了他们之后:- ),但是您的决定可能取决于您实际的非功能性需求。
发布于 2014-09-02 21:38:15
除了Jynus所说的:首先要确保您的表是物理上聚集在Date上的。这将使范围扫描非常有效,因此聚集数周或几个月将是快速的。即使您选择在汇总表中实例化这些周或月级别的汇总,按日期进行聚类也会帮助您非常快速地进行更新。
这种情况--许多范围扫描--是您选择低基数字段而不是高基数字段(用户ID)的一个极好的例子。不过,您仍然需要UserID上的索引。
CREATE TABLE Activity
(
Date DATE NOT NULL,
UserID INT NOT NULL REFERENCES Users(UserID),
PRIMARY KEY (Date, UserID),
NumUpdates TINYINT UNSIGNED -- Assuming that a user cannot update more than 255 times per day; alternately, consider SMALLINT
)https://dba.stackexchange.com/questions/72709
复制相似问题