11

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

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

所以,在实践中:

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

John 是主语,created 是动词,Beautiful Post 是直接补语。

John commented "OMG" on Beautiful Post  (12/01 00:00)

John是主语,commented是动词,“OMG”是直接补语,Beautiful Post是间接补语。

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

有没有用 Doctrine 和 MySQL 做这件事的正确方法?一种更优雅、更通用的方法,它不会让我发疯并迫使我进行大量荒谬的查询和搜索?

4

1 回答 1

38

关于数据库架构

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

我建议你使用这个数据库设计:

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 示例

这是一个非常简单的示例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();

}

相关问题

以下是一些关于该主题的大量信息的帖子:

于 2013-05-01T04:28:38.677 回答