mysql表必须包含80到100行

deikduxw  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(525)

对于学校作业,我需要一个包含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事件)表是否太多的原因,因为在某个点上可能有太多的行。理想的情况是每次添加新行时删除最旧的行。
我还有什么办法可以这样做吗?

nwlqm0z1

nwlqm0z11#

似乎我要找的不是真的可能,所以我每小时使用一个mysql事件来删除多余的行。
代码如下:
事件检查冗余行

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 ;

过程删除冗余行()

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 ;
jucafojl

jucafojl2#

你不能用触发器来做这个。我会用一个从应用程序代码调用的事务来完成它。

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行,它将为 @id ,并且delete不会删除任何行。
如果表中有超过100行,它将分配给 @id 行的id,从末尾算起100行。然后delete将删除该行和任何较早的行,只剩下100行。使用这个多步骤方法比仅仅删除id<max-100的地方要好,因为您不应该假设没有丢失的id值。
如果您有多个客户机同时执行此操作,则存在竞争条件。也就是说,两个并发会话可能同时选择和删除。这可能导致总行数暂时超过100行,至少在下次插入行并删除额外行之前是这样。

相关问题