MySQL表保存统计数据的最佳结构

MySQL表保存统计数据的最佳结构,mysql,performance,web-applications,statistics,scalability,Mysql,Performance,Web Applications,Statistics,Scalability,我需要一个解决方案,使我能够跟踪web应用程序(PHP5/MySQL5.7)中的每一次单击(以及单击的链接和日期)。最简单的解决方案显然是一个简单的表格: CREATE TABLE stats_data ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, log_date DATETIME NOT NULL DEFAULT NOW(), link VARCHAR(512) NOT NULL ) 我不知道这是如何提升性能的,因为每天

我需要一个解决方案,使我能够跟踪web应用程序(PHP5/MySQL5.7)中的每一次单击(以及单击的链接和日期)。最简单的解决方案显然是一个简单的表格:

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中
  • 为每个月创建自己的表,以避免在一个大表中进行搜索。并每月备份该表

  • 主要取决于您的用例。您希望在此数据集上运行哪些查询

    我肯定会推荐一些面向文档的数据库(如Redis或MongoDb),但正如我所说的,这取决于您将如何使用数据

    如果你想坚持使用MySQL,我有一些关于如何使该解决方案更可靠的建议

  • 不要在每次单击时都将每次单击保存到数据库中,而是将其存储到缓存(例如memcached)中,并每小时保存一次到MySQL中
  • 为每个月创建自己的表,以避免在一个大表中进行搜索。并每月备份该表

  • 我想您可以将链接放在一个单独的表中,并将表引用为外键。例如,应该能够更快地检查特定链接上的点击次数

    根据您希望数据的准确性,您还可以通过某种夜间运行的操作(计划的sp应该可以工作)将数据聚合到MAB中的另一个表中。
    这样,您就可以有一个表,例如,您可以在其中查看在特定时间间隔、一天或一小时或任何适合您需要的时间内单击链接的次数。我在工作中使用过这种方法,我们将web服务调用的统计数据存储在一个负载非常重的应用程序中,并且一直运行良好,没有任何性能问题。

    我想您可以将链接放在一个单独的表中,并将表引用为外键。例如,应该能够更快地检查特定链接上的点击次数

    根据您希望数据的准确性,您还可以通过某种夜间运行的操作(计划的sp应该可以工作)将数据聚合到MAB中的另一个表中。
    这样,您就可以有一个表,例如,您可以在其中查看在特定时间间隔、一天或一小时或任何适合您需要的时间内单击链接的次数。我在工作中使用过这种方法,我们将web服务调用的统计数据存储在一个负载非常重的应用程序中,它一直运行良好,没有任何性能问题。

    您可以采取一些措施来确保性能:

    • 索引
      记录日期
      列,这样在按日期范围()搜索结果时,查询可以运行得更快
    • 日志日期创建分区列()
    通过按日期列划分数据,您可以按小时/天/周/月/年“分离”数据。。。不管你想要什么

    例如:

    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”之间的日志上进行搜索


    我希望这能对您有所帮助。

    您可以做以下几点来确保性能:

    • 索引
      记录日期
      列,这样在按日期范围()搜索结果时,查询可以运行得更快
    • 日志日期创建分区列()
    通过按日期列划分数据,您可以按小时/天/周/月/年“分离”数据。。。不管你想要什么

    例如:

    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”之间的日志上进行搜索


    我希望这能对您有所帮助。

    link VARCHAR(512)
    更改为
    link\u id INT
    是一个明显的优化。这取决于您将使用的查询。请描述它们,或向我们展示暂定的
    SELECT
    语句。(5个月后150万条记录并不多。)问题解决了,如下所示。谢谢。将
    link VARCHAR(512)
    更改为
    link\u id INT
    是一个明显的优化。这取决于您将使用的查询。请描述它们,或向我们展示暂定的
    SELECT
    语句。(5个月后150万条记录并不多。)问题解决了,如下所示。谢谢。用例就是从中提取统计数据。在我的web应用程序中,我希望让用户看到(例如)特定月份、日期或自定义期间的点击次数。大多数情况下,查询(插入除外)会获取特定日期范围内的行。1.调查一下,谢谢。2.我喜欢这个想法,再次感谢。将数据保存到一些原始表中,并使用一些日常例程(cron)将有价值的数据聚合到一些轻量级的表中(例如一个表表示每天的点击次数,另一个表表示每天的点击次数)