设计模式以使用关系数据库构建受 GitHub 启发的时间线


Design pattern to build a GitHub-inspired timeline with relational database?

是否有构建受 GitHub 启发的时间线的设计模式?我正在尝试为我的应用程序编写一个有点复杂且通用的时间线系统。它基于这个概念:

[Subject] [Verb] [DirectComplement] [IndirectComplement] (metadata: [date])

因此,在实践中:

John created a new post called Beautiful Post (12/01 00:01)

约翰是主语,创造是动词,美丽的帖子是直接补充。

John commented "OMG" on Beautiful Post  (12/01 00:00)
约翰是主语,

评论是动词,"OMG"是直接补语,美丽邮报是间接补语。

我正在使用Symfony2和Doctrine,运行MySQL。我创建了一个名为 Timeline 的实体,该实体以字符串形式存储主题、DirectComplement 和 IndirectComplement 的模型,以及它们的 ID。然后,我手动进行适当的查询,以便获取每个对象的对象。

有没有一种正确的方法来使用Doctrine和MySQL来做到这一点?一种更优雅、更通用的方法,不会让我发疯并迫使我进行荒谬的查询和询问?

关于数据库架构

ActivityStrea.ms 是您想要的社交活动流的标准建议。SO上有很多类似的帖子,主要是关于这些活动流的数据库设计(最后的链接)。请不要低估 ActivityStrea.ms JSON 模式的读数。我相信你会从中学到很多东西。

我建议您使用此数据库设计:

user_id        |  INTEGER  |  user being notified
actor_id       |  INTEGER  |  user performing the action
activity_type  |  STRING   |  classname/type of the object being notified
activity_id    |  INTEGER  |  id of the object being notified
context_type   |  STRING   |  classname/type of the object's parent
context_id     |  INTEGER  |  id of the object's parent
read/view_at   |  DATETIME |  timestamp of when user saw it

因此,例如,如果有人评论帖子,您将得到以下内容:

$notification = array(
    'user_id'       => $id_of_the_user_being_notified
    'actor_id'      => $comment->user_id
    'activity_type' => 'comment'
    'activity_id'   => $comment->id
    'context_type'  => 'post'
    'context_id'    => $comment->post_id
    'read_at'       => NULL
);

拥有所有这些领域似乎没有必要,但他们肯定会付出代价。

通过该设计,您可以:

  1. 按用户、类型或上下文对相关通知进行分组
  2. 按操作类型、上下文类型和特定参与者(通过联接)过滤通知
  3. 轻松清除已删除对象的通知(假设用户删除了已评论的帖子。其评论通知应消失)

注意:时间戳 (created_at/updated_at) 并不是必需的。由于您将加载activity对象(在这种情况下为注释记录),因此您已经拥有其时间戳。复制它们的唯一原因是按时间戳查询"通知"(您将无法在此处使用 JOIN)。无论如何,请随意添加您认为合适的内容。

关于Doctrine和Symfony

我不能为Symfony说太多,但我确信Doctrine支持多态查询。考虑到这一点,它应该与该设计很好地配合使用。

在Laravel上,我们使用模型的方法实现NotifiableInterface 。这样,不同的模型可以有自己的逻辑,谁会收到它的通知,以及它的上下文是什么。

应用程序本身侦听模型的create方法,并在适合时生成通知,因此模型和控制器不必自己处理通知,可以很好地解耦,并且更改存储应该尽可能简单。

可通知接口示例

这是一个非常简单的NotifiableInterface示例。您应该将其用作灵感并根据需要进行调整。

interface NotifiableInterface {
    // Returns a string representation of the type
    // It may be a get_class($this), the model table
    // or anything you like really.          
    public function get_type();
    // Returns an identifier for the object (ie its ID)
    // get_key is for compatibility with Laravel models
    // but you may use get_id.
    public function get_key();
    // Returns the context object for this entity.
    // It's advisable that this object also implements
    // NotifiableInterface, so it also has get_type and get_key
    public function get_context();
    // Returns the user_ids to be notified.
    // A comment, for instance, should notify the post owner
    // as well as anyone else that commented that post.
    public function should_notify();
}

相关问题

以下是一些帖子,其中包含有关该主题的大量信息:

  • 实施社交活动流的最佳方式是什么?
  • 如何在社交网络中实现活动流
  • Facebook类通知跟踪(DB设计)
  • 构建通知系统
  • 用于存储发送给用户的通知的数据库设计