【问题标题】:MySQL table must contain between 80 and 100 rowsMySQL 表必须包含 80 到 100 行
【发布时间】:2019-02-01 07:17:08
【问题描述】:

对于学校作业,我需要一个包含 80 到 100 行(含)的 MySQL 表。一个 cron 作业每 2 小时在表中输入一行。我想用触发器来做到这一点,但显然这是不可能的,因为表由于 INSERT 语句而被锁定。这是我使用的触发器:

CREATE TRIGGER too_many_rows
BEFORE INSERT ON log
FOR EACH ROW
BEGIN
    IF (SELECT COUNT(id) FROM log) >= 100 THEN
        DELETE FROM log LIMIT 1;
    END IF;
END

棘手的部分是表上还有手动插入,这就是我不能定期检查(CRON 作业或 MySQL 事件)是否有太多表的原因,因为在某些时候可能太多了行。理想的情况是每次添加新行时删除最旧的行。

我还有什么办法可以做到这一点吗?

【问题讨论】:

  • 您可以控制插入吗?如果是这样,您可以告诉您的 cron 作业更新(覆盖除 id 之外的所有内容)最旧的条目(使用时间戳字段)。
  • 为什么没有100行的表,然后只执行UPDATES?
  • 我无法控制定期更新。它是来自特定 IP 地址的特定用户,只有 INSERT 和 SELECT 权限。它每 2 小时发出一次 INSERT。
  • 是否可以使用触发器阻止 INSERT,并改为更新最旧的条目?
  • 您确定您正确理解了任务(或者没有遗漏重要的细节)?它可能是例如一个“应该”,你只需要运行一个 cronjob 来清理。 “必须”通常意味着如果不满足约束,数据将变为无效(如外键或唯一键)。行数在数据模型中是否有任何逻辑意义?查询是否中断?对只有插入/选择权限的日志表强制执行随机行限制(并且不能跳过插入?)听起来,即使可行,就像您只会学习如何不设计数据库(尤其是在练习中)。

标签: mysql triggers mariadb


【解决方案1】:

您不能使用触发器来执行此操作。我会使用从应用程序代码调用的事务来完成。

BEGIN;
INSERT INTO log ...;
SELECT id INTO @id FROM log ORDER BY id DESC LIMIT 1 OFFSET 100;
DELETE FROM log WHERE id <= @id;
COMMIT;

如果表中的行数少于 100 行,它会将 NULL 分配给@id,并且 DELETE 将不删除任何行。

如果表中的行数超过 100 行,它将分配给@id 从末尾起 100 行的行的 id。然后 DELETE 将删除该行和任何更早的行,只留下 100 行。使用这种多步骤方法比只删除 id

如果您有多个客户同时执行此操作,则有一个 race condition。也就是说,两个并发会话可能都在选择和删除。这可能会导致总行数暂时超过 100,至少在下一次插入行并删除额外行之前。

【讨论】:

  • 谢谢比尔!但是,我无法控制插入。它们会发生,所以我需要一种方法来触发在 INSERT 发生时删除最旧行的代码......
【解决方案2】:

看来我正在寻找的东西不太可能,所以我使用 MySQL 事件每小时删除冗余行。

代码如下:

EVENT check_for_redundant_rows

SET GLOBAL event_scheduler = ON;

DELIMITER $$

CREATE EVENT check_for_redundant_rows
ON SCHEDULE EVERY 1 HOUR
STARTS '2018-01-01 00:00:00'
DO
CALL delete_redundant_rows();
$$

DELIMITER ;

PROCEDURE delete_redundant_rows()

DELIMITER $$

CREATE PROCEDURE delete_redundant_rows()
BEGIN
    DECLARE cnt INT DEFAULT 0;

    SELECT COUNT(id)
    INTO cnt
    FROM log;

    SET cnt = cnt - 80;

    DELETE FROM log
    ORDER BY id ASC
    LIMIT cnt;
END
$$

DELIMITER ;

【讨论】:

    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 2018-11-14
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多