Trello如何能够快速显示历史记录?

26

Trello可以显示自创建面板以来每个用户所做的所有历史记录。同样,如果您单击特定卡片,则会显示与该卡片相关的任何人所做的所有历史记录。

要永久跟踪保存的每个更改/添加/删除,必须收集大量数据,并且还可能在写入历史轨迹日志时出现瓶颈(假设它立即写入某种数据存储)。我的意思是,它不像是将所有内容存储在1000台服务器上分散的日志文件中,只有在需要查找东西时才会收集和解析它们--他们一直显示所有这些信息。

我知道这不是唯一提供此类服务的服务,但您会如何构建这样的系统?


你会惊讶于你的关系型数据库的表现。日志并非存储在文件中,而是存储在带有一些不错索引的数据库中。 - JonH
3个回答

35

我是 Trello 团队的成员。我们在 MongoDB 实例中使用 Actions 集合,并在其中为其引用的模型的 IDs(Card 和 Member 都是模型)和执行操作日期上创建了一个复合索引。除了 DB 在内存中保留索引和最近使用的文档之外,没有任何花哨的缓存或其他东西。Actions 是我们最大的集合。

值得一提的是,用于显示操作所需的大部分数据都以 denormalized 的方式存储在操作文档中,因此可以极大地加快速度。


因此,您可以在时间戳和索引上存储操作,以便进行快速查找,非常简单!“操作文档”是什么? - Ape-inago
我们使用MongoDB,因此“操作文档”相当于传统关系型数据库中“操作表中的一行”,但它保存的是任意JSON文档,而不是高度结构化的数据。 - Brett
@Brett,因为你的数据全部非规范化,所以写入操作会受到影响(变慢)吗? - Pacerier

3
最简单的方法是创建一个类似于下面这样的表格:
create table HistoryItems (
ID INT PK,
UserID INT PK,
DateTime datetime,
Data varbinary(max)/varchar(max)/...)

将此索引化为UserID,可以快速检索。覆盖索引可以使得检索整个用户的历史记录只需一次磁盘寻址,无论其长度如何。

这个表可以按(UserID升序,DateTime降序,ID)聚集,因此您甚至不需要任何索引也可以实现最佳性能。

对于关系数据库来说,这是一个简单的问题。


也许读取操作并不那么糟糕,但是将所有数据写入一个表中会导致非常严重的锁定问题,不是吗? - Oxed Frederik
通常不会。每个事务的写入量很少(本例中是这种情况),只会锁定行。通过这种方式,可以并发地进行插入操作。 - usr

1

我在我的PHP+MySQL应用程序中有与Trello上面的@Brett非常相似的内容,我使用它来跟踪我们在线网店的订单和生产管理应用程序中用户活动。

我有一个包含以下内容的活动表:

  • user_id:执行操作的用户
  • action_id:执行的操作(例如创建、更新、删除等)
  • resource:已执行操作的资源(模型)的枚举列表(例如订单、发票、产品等)
  • resource_id:执行操作的资源的PK
  • description:操作的文本描述(可以为空)

这确实是一个大表,但是通过正确的索引处理得非常好。 它很简单快速,目前它保存了20万条记录,并且每天增加约1000个新条目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接