【发布时间】:2010-12-31 18:43:32
【问题描述】:
首先,这个 DB 问题可能有点与 DB 无关,但我使用的是 Sql Server 2008,如果它有专门的解决方案来解决这个问题,但如果你不是 MS Sql Server 人员,请继续阅读..请:)
好的,我读入了一个包含游戏数据的日志文件。例如。当玩家连接、断开连接、做事等时。没什么太难的。效果很好。
现在,两种日志文件条目类型是
- 新连接
- 丢失连接
我试图跟踪的是当前连接到游戏的玩家。 所以我最初的想法是创建第二个表,其中包含每个玩家最近的新连接。当玩家断开/失去连接时,我会从第二个表中删除此条目。
例如。
Table 1: LogEntries
LogEntryId INT PK NOT NULL
EntryTypeId TINYINT NOT NULL
PlayerId INT NOT NULL
....
Table 2: ConnectedPlayers
LogEntryId INT FK (back to LogEntries table) NOT NULL
然后,我想我可以使用触发器将其插入到 ConnectedPlayers 表的 cache 数据中。别忘了,如果是触发器,它需要handle multiple records,更新和删除。
但我不确定这是否是最好的方法。比如,我可以有一个索引视图吗?
我很想知道人们对此的看法。
哦,还有一件事:为了简单起见,让我们假设当玩家断开连接/延迟/调制解调器死机/等时,应用程序足够聪明,可以知道这一点并将其记录为 LostConnection 条目。不会有幻影用户报告为已连接,当他们真的意外断开连接时等等。
更新:
我在想也许我可以改用view? (如果我愿意,我也可以索引这个视图:))通过Partitioning 我的结果,我可以获得每个玩家的最新事件类型......其中事件是NewConnection 或LostConnection。然后只抓取那些最近的 NewConnection .. 这意味着它们已连接。没有第二个表/触发器/额外插入 .NET 代码/任何需要...
例如..
SELECT LogEntryId, EntryTypeId, PlayerId
FROM
(SELECT LogEntryId, EntryTypeId, PlayerId
RANK() OVER (PARTITION BY PlayerId ORDER BY LogEntryId DESC) AS MostRecentRank
FROM LogEntries
WHERE (EntryTypeId = 2 -- NewConnection
OR EntryTypeId = 4 -- LostConnection)
) SubQuery
WHERE MostRecentRank = 1
听起来/看起来怎么样?
【问题讨论】:
-
或者,您也可以在 LogEntries 表中设置一个 is_current 标志,当您断开连接时更新该标志。
-
嗯。我不明白这有什么帮助,罗兰。 LogEntries 表是文件中记录的数据的简单一对一映射。
-
这似乎不是您想要保留的那种信息,而是只保留在内存中,因为如果服务器重新启动,您无论如何都会失去所有连接。你坚持的理由是什么?如果您只想记录谁连接的日志,那没关系,但您为什么要从日志中读取以找出现在谁连接了?
-
因为我没有进入游戏的权限。只有实时的流式日志:((但是是的,我同意你的观点:P)
-
@Mark Byers:当服务器重新启动(或应用程序池重新启动)时,连接丢失并不总是正确的。将会话持久化到数据库以防止这种情况是很常见的。