[英]Would a MySQL trigger be faster than php to check for 20+ rows?
At the moment we record a users last 20 media views so that they can have a brief history page of what they've looked at recently. 目前,我们为用户记录最近20次媒体观看,以便他们可以简要回顾他们最近浏览过的内容。
To do this we insert the media ids into a table. 为此,我们将媒体ID插入表中。
To keep the table a small size it's currently only 20 items per user so before inserting the row we check to see how many history ids they currently have in there, if it's less than 20 then we just insert the new row, if it's more than 20 then we have to select the last row and delete it before the new row can be inserted. 为了缩小表格的大小,目前每个用户只有20个项目,因此在插入该行之前,我们先检查一下他们当前在其中有多少个历史ID,如果小于20,则仅插入新行,如果大于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))");
I'm now converting the site to more modern code and will be using pdo queries, my quesiton is: 我现在正在将该网站转换为更现代的代码,并将使用pdo查询,我的问题是:
Is the above a good way to approach this or should I use another method such as a MySQL trigger on insert? 以上是解决此问题的好方法,还是应该在插入时使用其他方法(例如MySQL触发器)?
If you are really interested in maximum speed, there's also the extremely performant option of not checking how many rows are there in the first place and having a cleanup operation prune them in the background. 如果您真的对最大速度感兴趣,那么还有一个非常高性能的选择,即不首先检查多少行,而在后台进行清理操作来修剪它们。 Whenever you want to insert a new row, simply do so directly.
每当您要插入新行时,只需直接这样做即可。 Whenever you fetch the most recent rows to display, use
LIMIT 20
. 每当您获取要显示的最新行时,请使用
LIMIT 20
。
A garbage collector process can run independently of this as often as you want it to, looking for users with more than 20 history records and deleting the oldest appropriately. 垃圾收集器进程可以独立于此运行,您可以根据需要运行它,查找具有20多个历史记录的用户,并适当地删除最旧的记录。 This way you have a guaranteed lower bound for recent history items (provided they have been created at some point) and an unlimited but quite low in practice amount of old history records awaiting pruning.
这样,您就可以保证最近历史记录项的下限(前提是它们是在某个时候创建的),并且在实践中可以无限量但实际上数量很低的旧历史记录等待修剪。 You can decide on the collection frequency as you prefer.
您可以根据需要决定收集频率。
On the other hand, if it's not absolute performance that you are after then a check from PHP should be fine -- provided that you change it to do SELECT COUNT(*) FROM mediatable WHERE userId = $userId
when looking how many ids already exist. 另一方面,如果不是绝对的性能,那么从PHP进行检查应该没问题-前提是您更改它以在查看已有ID时
SELECT COUNT(*) FROM mediatable WHERE userId = $userId
进行SELECT COUNT(*) FROM mediatable WHERE userId = $userId
。 This way it's also easier by far to modify your retention strategy down the road. 这样,到目前为止,修改保留策略也更加容易。
Update: Garbage collection strategies to consider 更新:要考虑的垃圾收集策略
The following will insert a new row or reuse an existing id if a user has more than 20 rows inserted already. 如果用户已插入20行以上,则以下内容将插入新行或重用现有ID。 The query uses the oldest existing id for this user.
该查询为此用户使用最早的现有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
");
The best you can do is , make one stored procedure, just pass it your new data, and max length 最好的办法是,创建一个存储过程,将新数据传递给它,并且最大长度
max length because, now its 20, going larger, may need to be changed, so dynamic is better 最大长度,因为现在它的20会变大,可能需要更改,所以动态效果更好
Triggers are also good, but Precompiled Procedures, would better when comparing in term of speed and customization. 触发器也不错,但是在速度和自定义方面进行比较时,预编译过程会更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.