【问题标题】:Keep only 10 records per user每个用户只保留 10 条记录
【发布时间】:2010-07-20 14:56:57
【问题描述】:

我在我的网站上运行积分系统,因此我需要将用户不同操作的日志保存到数据库中。问题是我有太多用户,永久保留所有记录可能会导致服务器过载......我有办法让每个用户只保留 10 条记录并自动删除旧条目吗? mysql有这个功能吗?

提前致谢

【问题讨论】:

  • 你怎么知道它超载了?有什么症状?在决定解决方案之前,您应该收集一些相关的统计数据。
  • 我很好奇,你大概有多少用户?

标签: php mysql


【解决方案1】:

您可以添加一个用于删除旧条目的触发器。 例如,

DELIMITER //
CREATE definer='root'@'localhost' TRIGGER afterMytableInsert AFTER INSERT ON MyTable
FOR EACH ROW
BEGIN
    DELETE FROM MyTable WHERE user_id = NEW.user_id AND id NOT IN 
    (SELECT id FROM MyTable WHERE user_id = NEW.user_id ORDER BY action_time DESC LIMIT 10);
END//

【讨论】:

  • 我有 MySQL 5.7.14 并且无法创建这样的触发器 - 我收到以下错误:Error Code: 1235. This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
  • 好的,为了避免触发器内部的这种限制,我可以像DELETE FROM MyTable WHERE user_id = NEW.user_id AND id NOT IN (SELECT id FROM (SELECT id FROM MyTable WHERE user_id = NEW.user_id ORDER BY action_time DESC LIMIT 10) foo); 这样声明,但是我无法将记录插入到我的MyTable,我得到了这个回复Error Code: 1442. Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
  • @sbrbot :那么可能最简单的方法是使用某种调度程序,无论是内置的 (dev.mysql.com/doc/refman/8.0/en/create-event.html) 还是像 cron 这样的外部调度程序。我还建议创建一个新问题,因为 Mysql 从 8 年前到现在已经发展了相当长的一段时间。
【解决方案2】:

只需运行一个每小时删除第 11 - n 条记录的 cron 作业。

【讨论】:

  • 我的公司在超过 4 万条记录文件上取得了巨大成功。
【解决方案3】:

在插入记录之前,您可以先检查用户有多少。如果他们有 >=10 删除最旧的。然后插入新的。

【讨论】:

    【解决方案4】:

    如果您的目标是让数据库确保给定表的每个给定子键(用户)的行数不超过 N 行,那么解决此问题的正确方法是:

    如果您已经在使用存储过程进行数据访问,那么修改插入过程最有意义,否则触发器将是最简单的解决方案。

    或者,如果您的目标是定期删除旧数据,那么使用 cron 作业启动存储过程来修剪旧数据是最有意义的。

    【讨论】:

      【解决方案5】:

      当您为用户插入新记录时。之前只要做一个这样的查询(不要忘记where-condition):

      DELETE FROM tablename WHERE userID = 'currentUserId' LIMIT 9, 999999
      

      之后,您可以插入新数据。这使每个用户的数据始终保持在 10 条记录中。

      INSERT INTO tablename VALUES(....)
      

      【讨论】:

        【解决方案6】:
        DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table WHERE USER_ID = 1) AND USER_ID = 1
        

        更清晰的版本

        DELETE FROM Table
            WHERE ID NOT IN
            (
                SELECT TOP 10 ID  FROM Table WHERE USER_ID = 1
            )
            AND USER_ID = 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-10
          • 1970-01-01
          • 2010-09-15
          相关资源
          最近更新 更多