假设您要在用户个人资料页面上显示最新访问者。
你会如何构建这个?也许是一个名为uservisitors
的表:
你怎么用mysql选择这个?没有任何重复,我的意思是如果用户1访问用户2的个人资料,然后5分钟后再次访问,我不希望它只显示两个条目最新
喝彩!
答案 0 :(得分:4)
SELECT visitorid, MAX(time) AS lastvisit
FROM uservisitors
WHERE userid = ?
GROUP BY
userid, visitorid
ORDER BY
lastvisit DESC
LIMIT 5
在(userid, visitorid, time)
上创建一个复合索引,以便更快地工作。
此查询:
SELECT visitorid
FROM uservisitors ui
WHERE userid = ?
NOT EXISTS
(
SELECT NULL
FROM uservisitors uo
WHERE uo.userid = ui.userid
AND uo.visitorid = ui.visitorid
AND uo.time > ui.time
)
ORDER BY
time DESC
LIMIT 5
如果你有很多不同的访问者,可能会更有效率。
在这种情况下,您需要(userid, time, visitorid)
上的索引。
<强>更新强>
我的博客中的这篇文章比较了两种方法:
答案 1 :(得分:0)
这样的事情应该有效:
SELECT visitorid, MAX(time)
FROM uservisitors
WHERE userid = 1
GROUP BY visitorid
答案 2 :(得分:0)
在过去5分钟内找到不同的访问者。 您可以将INTERVAL更改为过去24小时内的任何时间段,例如INTERVAL 1 DAY。
SELECT distinct visitorid
FROM uservisitors
WHERE userid = 1 AND time > DATE_SUB(NOW(), INTERVAL 5 MIN);
答案 3 :(得分:0)
假设您只关心访问者的最后一次访问而不是所有访问,那么如何为userid / visitorid使用唯一密钥对,然后使用INSERT INTO ..在DUPLICATE KEY:
CREATE TABLE uservisitors (... UNIQUE (userid, visitorid) );
INSERT INTO uservisitors (userid, visitorid, time) VALUES (....) ON DUPLICATE KEY UPDATE time=NOW();
然后一个简单的选择来获得前5名访客:
SELECT visitorid FROM uservisitors WHERE user_id=1 ORDER BY time DESC LIMIT 5;
没有重复记录或必须使用分组。
答案 4 :(得分:0)
您打算如何从表中删除内容?您可能需要为此添加另一个索引才能有效工作。
如果你只想要最后5次访问,我会对表进行反规范化(节省空间,索引并且只使用一个主键查找),在这个过程中,我不再需要担心删除旧数据。每个用户只占用表中的一行,因此随着时间的推移不会增长太多。所以:
CREATE TABLE user_visitors (user_id int primary key,
visitor_1_id int,
visitor_1_time timestamp,
..
visitor_5_id int,
visitor_5_time timestamp);
要存储访问权限,您可以使用visitor_1作为访问者插入新行。在重复项上,您将向下移动先前存储的值:
INSERT INTO user_visitors SET ...
... ON DUPLICATE KEY UPDATE visitor_5_id = visitor_4_id, visitor_5_time = visitor_4_time ...
... visitor_1_id = ?, visitor_1_time = ?
如果您担心重复,可以通过在UPDATE部分中添加IF来解决这个问题,这样如果该行中已存在visitor_id,则该行将不会更新。在代码中,您可以检查更新的行数。如果为零,则从那里处理重复的访问者时间更新。它涉及一些工作,但它将快速且易于理解。
答案 5 :(得分:0)
我已经处理了几次,这是我对它的看法。
我的表格如下:
CREATE TABLE visitors (
userid int,
visitorid int,
last_visit datetime,
primary key(userid, visitorid),
index(visitorid)
index(userid, last_visit)
) engine = memory;
插入数据:
INSERT INTO visitors (userid, last_visit) VALUES ( 50, now() )
ON DUPLICATE KEY UPDATE last_visit = now();
选择
select * from visitors WHERE userid=10 order by last_visit limit 10; # or whatever you need
偶尔清除表格
DELETE from visitors WHERE last_visit < date_add(now(), INTERVAL -1 WEEK);
这是出于某些原因的方法。
你可以运行一个cron来每分钟备份一次这个表
SELECT * from visitors INTO OUTFILE "/tmp/visitors.txt"