存储大量日志数据的最佳方式

Tim*_*s83 1 mysql database postgresql database-design nosql

我需要有关存储统计数据的最佳方法的建议。Django 上有一个项目,它有一个数据库(mysql),里面有 30 000 个网络游戏。

每场比赛都有三个统计参数:

  • 观看次数,
  • 播放次数,
  • 点赞数

现在我需要每天存储这三个参数的历史数据,所以我想创建一个包含五列的单个数据库:

gameid, number of views, plays, likes, date (day-month-year data). 
Run Code Online (Sandbox Code Playgroud)

所以最后,每一场比赛的每一天都会被记录在一行中,所以一天后这张表将有 30000 行,10 天后它将有 300000 行,一年后它将有 10 950 000 行. 我不是 DBA 方面的大专家,但这告诉我,这很快就会成为一个性能问题。我不是在谈论 5 年后会发生什么。简单图形需要此表中收集的数据

(daily, weekly, monthly, custom range).
Run Code Online (Sandbox Code Playgroud)

也许您对如何存储这些数据有更好的想法?也许 noSQL 在这种情况下会更合适?真的需要你的建议。d

Clo*_*eto 5

postgresql 中的分区非常适合大日志。首先创建父表:

create table  game_history_log (
    gameid integer,
    views integer,
    plays integer,
    likes integer,
    log_date date
);
Run Code Online (Sandbox Code Playgroud)

现在创建分区。在这种情况下,每个月一个,90 万行,会很好:

create table game_history_log_201210 (
    check (log_date between '2012-10-01' and '2012-10-31')
) inherits (game_history_log);

create table game_history_log_201211 (
    check (log_date between '2012-11-01' and '2012-11-30')
) inherits (game_history_log);
Run Code Online (Sandbox Code Playgroud)

注意每个分区中的检查约束。如果您尝试插入错误的分区:

insert into game_history_log_201210 (
    gameid, views, plays, likes, log_date
) values (1, 2, 3, 4, '2012-09-30');
ERROR:  new row for relation "game_history_log_201210" violates check constraint "game_history_log_201210_log_date_check"
DETAIL:  Failing row contains (1, 2, 3, 4, 2012-09-30).
Run Code Online (Sandbox Code Playgroud)

分区的优点之一是它只会在正确的分区中进行搜索,无论数据存在多少年,都会大幅且一致地减少搜索大小。这里解释了搜索某个日期:

explain
select *
from game_history_log
where log_date = date '2012-10-02';
                                              QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
 Result  (cost=0.00..30.38 rows=9 width=20)
   ->  Append  (cost=0.00..30.38 rows=9 width=20)
         ->  Seq Scan on game_history_log  (cost=0.00..0.00 rows=1 width=20)
               Filter: (log_date = '2012-10-02'::date)
         ->  Seq Scan on game_history_log_201210 game_history_log  (cost=0.00..30.38 rows=8 width=20)
               Filter: (log_date = '2012-10-02'::date)
Run Code Online (Sandbox Code Playgroud)

请注意,除了父表,它只扫描了正确的分区。显然,您可以在分区上建立索引以避免顺序扫描。

继承 分区