目前,我们会记录用户最近20个媒体观看次数,以便他们可以拥有他们最近查看过的简短历史记录页。
为此,我们将媒体ID插入表格中。
为了保持表的小尺寸,目前每个用户只有20个项目,所以在插入行之前我们检查它们当前有多少历史ID,如果它小于20,那么我们只需插入新行,如果然后我们必须选择最后一行并在插入新行之前将其删除。
$historyResult = mysql_query("SELECT id FROM mediatable WHERE userId = $userId ORDER BY id ASC");
if(mysql_num_rows($historyResult) >= 20)
{
$historyResult = mysql_query("SELECT id FROM mediatable WHERE userId = $userId ORDER BY id ASC LIMIT 1");
$historyRow = mysql_fetch_row($historyResult);
mysql_query("DELETE FROM mediatable WHERE id = '$historyRow[0]'");
}
mysql_query("INSERT INTO mediatable (userId, mediaId) VALUES ($userId, $mediaId))");
我现在正在将网站转换为更现代的代码并将使用pdo查询,我的问题是:
以上是解决这个问题的好方法吗?还是我应该在插入时使用其他方法,例如MySQL触发器?
答案 0 :(得分:7)
如果您真的对最高速度感兴趣,那么还有一个非常高效的选项,即不首先检查有多少行,并且在后台进行清理操作。无论何时想要插入新行,只需直接插入即可。每当您获取要显示的最新行时,请使用LIMIT 20
。
垃圾收集器进程可以根据需要独立运行,查找具有20个以上历史记录的用户并适当删除最旧的历史记录。通过这种方式,您可以保证最近历史记录项的下限(假设它们已经在某个时间点创建),并且等待修剪的旧历史记录的实际数量不受限制但很低。您可以根据需要决定收集频率。
另一方面,如果它不是绝对的性能,那么PHP的检查应该没问题 - 只要你在查看已经存在多少个id时将其更改为SELECT COUNT(*) FROM mediatable WHERE userId = $userId
。这样,到目前为止,修改您的保留策略也更容易。
更新:要考虑的垃圾收集策略
答案 1 :(得分:1)
如果用户已插入超过20行,则以下内容将插入新行或重用现有ID。该查询使用此用户最早的现有ID。
mysql_query("
INSERT INTO mediatable (id, userId, mediaId)
SELECT m.idd, d.u, d.m
FROM
(SELECT " . $userId . " u, " . $mediaId . " m FROM dual) d LEFT JOIN (
SELECT userid u, MIN(id) idd FROM mediatable
WHERE
userid = " . $userId . "
GROUP BY
userid
HAVING COUNT(*) > 20
) m ON d.u = m.u
");
答案 2 :(得分:0)
您可以做的最好的事情是,制作一个存储过程,只需将新数据传递给它,最大长度为最大长度,因为现在它的20更大,可能需要更改,所以动态更好
在速度和定制方面进行比较时,触发器也很好,但预编译过程会更好。