我喜欢为服务设计SQL数据层的一些输入,该服务应该为特定用户存储和提供最新的N个条目。我们的想法是跟踪每个用户(id),事件的时间,然后是事件ID。
服务应仅响应每个用户的最后X个事件数,并且仅包含在过去Y天内发生的事件。 该服务还需要扩展到大量的更新和读取。
我只考虑一个包含字段的简单表格:
ID | USERID | EVENT | TIMESTAMP
============================================
1 | 1 | created file Z | 2014-03-20
2 | 2 | deleted dir Y | 2014-03-20
3 | 1 | created dir Y | 2014-03-20
但您如何考虑解决时间要求?我在这里看到两种选择:
1)在为用户插入和/或读取时,还要删除过期的和除用户最后的X事件之外的所有事件。当您需要在每个请求上执行选择,删除和插入时,会影响延迟。但它将磁盘大小保持在最低限度。
2)让服务过滤查询并作为单独的批处理作业进行修剪,并使用一些sql:
我已经找到了关于这些要求的设计原则,这似乎是相当常见的。但我还没有找到完美的搭配。
目前不要求查询已执行特定类型事件的所有用户。
提前致谢!
编辑:
该服务的目的是扩展到数百万个请求/小时,所以我一直在玩这种出于性能原因而非规范化的想法。鉴于要求是一成不变的:
我实际上正在考虑像这样的数据透视表:
USERID | EV_1 | TS_1 | EV_2 | TS_2 | EV_3 | TS_3 | etc up to 10...
======================================================================
1 | Create | 2014.. | Del x | 2013.. | etc.. | 2013.. |
通过这种方式,我可以使用带有SELECT的MERGE来移动事件,并且我可以驱逐" free"。然后我只需要清除TS_1超过10天的所有记录。我还可以在我的应用程序逻辑中过滤,仅显示在执行琐碎选择后超过10天的事件。
需要注意的是,如果事件发生在"故障"。如果我能始终保证事件是从"从左到右排序的,那么上面的想法是有效的。可能要考虑那个......
除了它基本上是关系数据模型中的一个重要事实之外,如果首先要优先考虑性能,你认为我在这里是正确的吗?
答案 0 :(得分:0)
你的桌子设计很好。还要考虑要使用的索引。实际上,您需要在(userid,timestamp)上使用多列索引来快速响应查询具有特定用户标识的最后N个事件的查询。然后,您需要在(时间戳)上使用单列索引来有效删除旧事件。
您计划存储的事件数量以及您计划每次查询检索的事件数量是多少?即表的大小是否超过可用的RAM?您使用传统的旋转硬盘还是固态硬盘?如果表的大小超过可用的RAM并且您使用的是传统HDD,请注意,由于查找时间较慢,为查询返回的每一行大约需要5-15毫秒。
如果您的系统支持批处理作业,我会使用批处理作业删除旧事件,而不是在每次查询时删除旧事件。原因是批处理作业不会减慢交互式代码路径的速度,并且只要您很少执行批处理作业,就可以立即执行更多工作。
如果您的系统不支持批处理作业,您可以使用概率算法删除旧事件,即在查询事件时仅以1%的概率删除。或者,您可以有一个帮助程序表,在其中存储上次删除旧事件的时间戳,然后检查该时间戳,如果它已经足够旧,则执行新的删除作业并更新时间戳。辅助表应该很小,以至于它总是保留在缓存中。
答案 1 :(得分:0)
我倾向于不删除数据。我只是将数据存储在您的结构中,并具有运行查询的接口(可能是视图或表函数),例如;
select s.*
from simple s
where s.timestamp >= CURRENT_DATE - interval 'n days' and
s.UserId = $userid
order by s.timestamp desc
fetch first 10 row only;
(注意:这使用标准语法,因为您尚未指定数据库,但在任何数据库中都有类似的功能。)
对于性能,您需要simple(UserId, timestamp)
上的索引。这将完成大部分工作。
如果您真的想要,可以定期删除旧行。但是,保留所有行有利于响应不断变化的要求(“哦,我们现在需要60天而不是30天”)或其他目的,例如调查用户行为和事件随时间的变化。
有些情况不同寻常,您可能需要采用不同的方法。例如,您可以对保存数据的时间量进行法律限制。在这种情况下,请使用删除旧数据的作业并每天运行它。或者,如果您的数据库技术是内存数据库,您可能希望限制表的大小,以便旧数据不占用太多内存。或者,如果您的交易量非常高并且用户数量已经丢失(例如数百万用户拥有数千个事件),您可能会更关注影响性能的数据量。