我想以高效的方式将最后的 X 条记录存储在 MySQL 数据库中。因此,当存储第 4 条记录时,应删除第 1 条记录。
我这样做的方法不是先运行查询获取项目。比检查我应该做什么然后插入/删除。
必须有更好的方法来做到这一点。有什么建议吗?
Edit
我想我应该补充一点,存储的记录没有唯一编号。他们有一个混合的标准。例如 article_id 和 user_id。
然后我想用 user_x 的最后 X 个项目制作一个表。
仅从按用户分组并按时间排序的表格中选择文章对我来说不是一个选项。我进行排序和分组的表有数百万条记录,并且无缘无故地受到了很多打击。因此,在最后 X 条记录之间制作一个表格会更有效。
附言。我不会将其用于文章和用户。
最佳答案
在存储过程中实现(表名为ibt,代表in-between-table):
delimiter ;
DROP TABLE IF EXISTS `ibt`;
CREATE TABLE `ibt` (
`seqid` int(10) unsigned NOT NULL auto_increment,
`article_id` varchar(10) NOT NULL default '',
`user_id` varchar(10) NOT NULL default '',
anotherVar VARCHAR(10),
PRIMARY KEY (`article_id`,`user_id`),
KEY `seqid` (`seqid`)
) ENGINE=MEMORY AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
drop procedure if exists addEntry;
delimiter $$
create procedure addEntry(_article_id INT, _user_id INT, _anotherVar VARCHAR(10))
begin
DECLARE done INT DEFAULT 0;
declare seq INT;
declare seqNew INT DEFAULT 1;
declare Cnt INT DEFAULT 0;
declare cur CURSOR for
SELECT seqid
from ibt
where user_id=_user_id
order by seqid desc;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
START TRANSACTION;
open cur;
REPEAT
FETCH cur INTO seq;
IF NOT done THEN
SET Cnt = Cnt+1;
IF Cnt = 3 THEN
DELETE FROM `ibt` where seqid = seq;
END IF;
IF Cnt = 1 THEN
SET seqNew = seq + 1;
END IF;
END IF;
UNTIL done END REPEAT;
INSERT into `ibt`
SET article_id=_article_id,
user_id=_user_id,
seqid=seqNew,
anotherVar=_anotherVar;
close cur;
COMMIT;
end $$
delimiter ;
call addEntry(1, 1, 'a');
call addEntry(2, 1, 'b');
call addEntry(3, 1, 'c');
call addEntry(4, 1, 'd');
可以将上面的SQL作为一个单元来运行进行测试。我用过 HeidiSQL。
一旦您的数据库中有了存储过程,您就可以从您的 PHP 代码中“调用 addEntry”。
关于mysql - 有效地存储每个项目的最后 X 条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2583621/