MySQL table 保存统计数据的最佳结构
Best structure for MySQL table to hold statistical data
我需要一个解决方案,使我能够跟踪 Web 应用程序 (PHP5 / MySQL5.7).最简单的解决方案显然是一个简单的 table :
CREATE TABLE stats_data (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
log_date DATETIME NOT NULL DEFAULT NOW(),
link VARCHAR(512) NOT NULL
)
我不知道这是如何提高性能的,因为预期的点击量 每天 很可能 超过 10000.
- 这是一个可靠的解决方案吗,比如说,在存储了 5 个月的数据之后?
- 哪些优化可以使该解决方案性能更好?
- 如果没有,什么是更好的解决方法?
主要取决于您的用例。您想 运行 对此数据集执行哪些查询?
我肯定会推荐一些面向文档的数据库(如 Redis 或 MongoDb),但正如我所说,这取决于您将如何使用数据。
如果您想坚持 MySQL,我有一些关于如何使该解决方案更可靠的建议。
- 不要将每次点击都保存到数据库中,而是将其存储到缓存中(例如 memcached),并且每小时保存一次到 MySQL
- 每个月自己制作 table,而不是在一大片 table 中进行搜索。并每月备份 table。
我想您可以将 link 放在单独的 table 中,并让您的 table 将其作为外键引用。应该可以让它更快,例如检查特定 link.
上的点击次数
根据您希望数据的准确性,您还可以将其聚合到另一个 table 中,例如每晚 运行 某种操作(预定的 sp 应该工作)。
这样你就可以有一个 table ,例如你可以在特定的时间间隔、一天或一个小时或任何适合你需要的时间间隔内点击 link 的次数。我在工作中使用了这种方法,我们在负载非常重的应用程序中存储有关 Web 服务调用的统计数据,并且它一直运行良好,没有任何性能问题。
您可以采取一些措施来确保性能:
- 索引
log_date
列因此查询可以运行更快按日期范围搜索结果(https://dev.mysql.com/doc/refman/5.5/en/column-indexes.html)
- 按
log_date
列创建分区 (https://dev.mysql.com/doc/refman/5.6/en/partitioning-types.html)
通过按日期列对数据进行分区,您可以 "separate" 按小时/天/周/月/年的数据......任何你想要的......
示例:
CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
)
因此,假设您按周分隔数据,当您搜索日期等于“2016-08-25”的日志时,将仅搜索日期在“2016-08-22”之间的日志' 和 '2016-08-28'。
希望对你有所帮助
我需要一个解决方案,使我能够跟踪 Web 应用程序 (PHP5 / MySQL5.7).最简单的解决方案显然是一个简单的 table :
CREATE TABLE stats_data (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
log_date DATETIME NOT NULL DEFAULT NOW(),
link VARCHAR(512) NOT NULL
)
我不知道这是如何提高性能的,因为预期的点击量 每天 很可能 超过 10000.
- 这是一个可靠的解决方案吗,比如说,在存储了 5 个月的数据之后?
- 哪些优化可以使该解决方案性能更好?
- 如果没有,什么是更好的解决方法?
主要取决于您的用例。您想 运行 对此数据集执行哪些查询?
我肯定会推荐一些面向文档的数据库(如 Redis 或 MongoDb),但正如我所说,这取决于您将如何使用数据。
如果您想坚持 MySQL,我有一些关于如何使该解决方案更可靠的建议。
- 不要将每次点击都保存到数据库中,而是将其存储到缓存中(例如 memcached),并且每小时保存一次到 MySQL
- 每个月自己制作 table,而不是在一大片 table 中进行搜索。并每月备份 table。
我想您可以将 link 放在单独的 table 中,并让您的 table 将其作为外键引用。应该可以让它更快,例如检查特定 link.
上的点击次数根据您希望数据的准确性,您还可以将其聚合到另一个 table 中,例如每晚 运行 某种操作(预定的 sp 应该工作)。 这样你就可以有一个 table ,例如你可以在特定的时间间隔、一天或一个小时或任何适合你需要的时间间隔内点击 link 的次数。我在工作中使用了这种方法,我们在负载非常重的应用程序中存储有关 Web 服务调用的统计数据,并且它一直运行良好,没有任何性能问题。
您可以采取一些措施来确保性能:
- 索引
log_date
列因此查询可以运行更快按日期范围搜索结果(https://dev.mysql.com/doc/refman/5.5/en/column-indexes.html) - 按
log_date
列创建分区 (https://dev.mysql.com/doc/refman/5.6/en/partitioning-types.html)
通过按日期列对数据进行分区,您可以 "separate" 按小时/天/周/月/年的数据......任何你想要的......
示例:
CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
)
因此,假设您按周分隔数据,当您搜索日期等于“2016-08-25”的日志时,将仅搜索日期在“2016-08-22”之间的日志' 和 '2016-08-28'。
希望对你有所帮助