Php 每天存储数百万条可分组用于统计目的的数据记录的最佳方法?

Php 每天存储数百万条可分组用于统计目的的数据记录的最佳方法?,php,mysql,node.js,database-design,ip-geolocation,Php,Mysql,Node.js,Database Design,Ip Geolocation,我正在为营销活动开发一个自定义跟踪工具。这个工具位于广告和登陆页面之间。它负责保存来自用户的所有数据,例如用户代理中的信息、IP、登录页上的点击以及用户IP(国家/地区、ISP等)的地理编码数据 目前我有一些设计问题: 这些活动的流量非常高,因此我每天可能插入数百万行。这个系统可以有多个用户,所以我不能将所有这些数据存储在一个表中,因为这样会变得一团糟。也许我可以将数据拆分为多个表,每个用户一个表,但我不确定这个解决方案 数据保存过程必须尽快完成(几毫秒),因此我认为NodeJS在这方面比PH

我正在为营销活动开发一个自定义跟踪工具。这个工具位于广告和登陆页面之间。它负责保存来自用户的所有数据,例如用户代理中的信息、IP、登录页上的点击以及用户IP(国家/地区、ISP等)的地理编码数据

目前我有一些设计问题:

  • 这些活动的流量非常高,因此我每天可能插入数百万行。这个系统可以有多个用户,所以我不能将所有这些数据存储在一个表中,因为这样会变得一团糟。也许我可以将数据拆分为多个表,每个用户一个表,但我不确定这个解决方案
  • 数据保存过程必须尽快完成(几毫秒),因此我认为NodeJS在这方面比PHP好得多。特别是在速度和服务器资源方面。我不希望服务器因缺少RAM而崩溃
  • 我需要对这些数据进行分组以便于统计。例如,访问我的登录页的每个用户都有一行,但我需要对这些数据进行分组,以显示此特定登录页上的印象数。因此,所有这些查询都需要在有这么多行的情况下尽可能快地执行
  • 我需要对IP地址进行地理编码,因此我需要准确的信息,如国家、ISP、连接类型等,但如果我调用API服务,这会减慢数据保存过程。这必须实时完成,不能在以后完成
保存过程结束后,系统应重定向到登录页。时间对于不失去任何可能的潜在客户非常重要

基本上,我正在寻找以下方面的最佳解决方案:

  • 高效地管理非常大的数据库
  • 以尽可能短的时间(ms)保存来自用户的数据
  • 如果可能,在不阻塞执行的情况下,在尽可能短的时间内使地理编码成为ip
  • 优化架构和查询以生成统计信息

你有什么建议吗?提前谢谢。

每个用户一张桌子更糟糕;不要那样做

每天有数百万行--几十行,也许几百行,每秒?这可能需要某种形式的“暂存”——收集多行,然后批量插入它们。在进一步讨论之前,请详细说明数据流:单客户端与多客户端。UI与批处理流程。暂定
创建表
。等等

统计--计划创建和增量维护“汇总表”

您正在尝试将用户IP地址映射到国家/地区吗?这是一个单独的问题,已经得到了回答

必须为“实时”毫秒。面对现实,你必须做出一些权衡

更多信息:转到;从这里可以看到关于数据仓库技术的三个博客

如何按天存储

InnoDB以
主键的顺序存储数据。因此,要使一天中的所有行彼此相邻,必须以datetime开始PK。对于大型数据库,可以通过允许查询按顺序扫描数据来显著改进某些查询,从而最大限度地减少磁盘I/O

如果您已经有
id AUTO_INCREMENT
(如果您仍然需要它),则执行以下操作:

PRIMARY KEY(datetime, id),  -- to get clustering, and be UNIQUE
INDEX(id)  -- to keep AUTO_INCREMENT happy
如果您有一年的数据,而这些数据不适合RAM,那么这种技术对于小时间范围非常有效。但是,如果您的时间范围大于缓存,那么您将受制于I/O速度

使用更改的数据维护汇总表

这是可能的;我需要更好地了解数据和变化

无论缓存、调优和其他优化如何,都无法在亚秒的时间内扫描一百万行。使用汇总表可以更快地生成所需的数据

收缩数据

  • 如果
    INT
    (4个字节)足够,不要使用
    BIGINT
    (8个字节);如果
    MEDIUMINT
    (3个字节)可以,请不要使用
    INT
    。等等
  • 在适当的情况下使用未签名的
  • 规范化重复的字符串

较小的数据将使其更易于缓存,因此在您必须访问磁盘时运行得更快。

在这种情况下,您可以使用ELK stack。利用服务器日志;将原始数据存储在单个表中;使用后台任务处理地理编码的IP查找;在使用PHP时,不要认为它速度慢且内存不足,我已经用PHP记录了每天百万次点击率的站点,但这并不是一个偶然现象,你的问题是StackOverflowHi@Rahul的扩展方式,你能解释一下我如何使用ELK stack吗?不,我没有建议;创建一组针对数据结构和查询进行规范化并适当索引的表;并使用后台进程从原始数据表中填充。。。在填充这些表时,请从原始表中删除/归档这些数据。由于统计数据是动态的,我认为您不能使用“摘要表”之类的内容。我认为问题不在于INSERT语句,而在于统计查询。随着时间的推移,在大型表上进行查询变得如此缓慢……我又添加了一些。嗨,瑞克!所有这些记录都将以它们到达的相同顺序插入,因此它们已经是连续的。我的意思是这些行已经按日期排序了。也许我可以为每个分组字段维护一个汇总表。例如,我想显示每个登录页的点击次数。我可以使用一个表格,并将每个登录页上已经分组的所有点击按天进行保存。所以,如果我想显示两天的数据,我只需要为每个登录页分组两行,而不是千行。你的想法是对的。随它去吧。请记住以增量方式更新汇总表,don