我可以定期检查当前在线的用户列表。我想把它变成有用的东西,比如每个用户的登录/登出时间条目列表。除了检查当前在线的人之外,没有其他方法可以确定此信息 经过一番思考后我想出了类似的东西:
CREATE TABLE onlineActivity (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR (32) NOT NULL,
login_time DATETIME NOT NULL,
logout_time DATETIME NOT NULL,
time SMALLINT (3) NOT NULL DEFAULT 0,
online BOOL DEFAULT NULL,
UNIQUE (name, online),
PRIMARY KEY (id)
) ENGINE = MyISAM;
我每隔几分钟运行一次此查询,以在活动列表中添加/更新名称:
INSERT INTO onlineActivity (name, login_time, logout_time, online)
SELECT name, now(), now(), true FROM onlineList ON DUPLICATE KEY UPDATE logout_time = now()
此查询针对已注销的每个用户运行:
(这些名称是通过比较两个相邻的在线列表,即当前的在线列表和前一个在线列表确定的)
UPDATE onlineActivity SET online = NULL WHERE name = ? AND online = 1
online
)是一个坏主意,并且会损害性能。我认为MySQL可能必须对每个名称执行所有online
(而不是使用索引)的完整扫描,以找到非NULL的。有人可以澄清这是否是这种情况?我找不到有关MySQL如何处理这种情况的任何信息。我想存储用户活动的完整历史记录,而不是单个条目。
答案 0 :(得分:1)
我不确定为什么你有一个独特的名字和在线,因为你要做的是创建一个在线活动列表。根据您的指定放置一个唯一键意味着您只能在其中有三个名称,每个州一个名称(null,true,false)。
你实际做的是尝试创建一个历史表,在这种情况下,使用当前填充表的方法,你应该在(name,logout_time)上放一个唯一的键,并使用null logout_time指示当前登录的用户(因为你只想要一个空的注销时间。
这样的事情:
CREATE TABLE onlineActivity (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR (32) NOT NULL,
login_time DATETIME NOT NULL,
logout_time DATETIME NULL,
time SMALLINT (3) NOT NULL DEFAULT 0,
online BOOL not null DEFAULT false,
UNIQUE (name, logout_time),
PRIMARY KEY (id)
) ENGINE = MyISAM;
然后按计划运行此更新表
INSERT IGNORE INTO onlineActivity (name, login_time, logout_time, online)
SELECT name, now(), null, true FROM onlineList
这是用户注销
UPDATE onlineActivity SET online = false, logout_time = now() WHERE name = ? AND logout_time = null