如何组合 mysql 的多个表(以创建流动的新闻提要),但仍然区分记录?

How can I combine multiple tables of mysql (to create a flowing news feed), but still tell apart the records?

我正在 PHP (oop) 和 mysql 数据库中构建一个应用程序,它的主页是 'News Feed'。

我的 MySQL 数据库表中有公告、事件、通知等,我想按以下方式组合它们:

我想加入所有这些表(只有共同的 datetime 字段)以创建一个流动的中央新闻提要,它由 datetime 字段混合和排序,但仍然知道每条记录是哪种类型。

原因是 - 我想创建不同的布局,并为每种记录类型显示不同的详细信息(就像在 Facebook 中一样 - 您可以在其中拥有状态、照片、事件、文章以及新闻提要中没有的内容)。

我确信我不是唯一一个问这个问题的人 - 我不知道如何在互联网上搜索类似的东西(因为我花了所有这些行来解释这个问题。 .).

我想要的结果是这样的(仅供示例):

<!-- Announcement = red block !-->
-------------------------------------------------
[title]                 [post date=12.9.15 16:40]
[author]
-------------------------------------------------
[content]
-------------------------------------------------

<!-- Event = blue block !-->
-------------------------------------------------
[title]             [creation date=12.9.15 12:55]
[place]                 [start-time] - [end-time]
-------------------------------------------------
[description]
-------------------------------------------------
10 people are going..
-------------------------------------------------

<!-- Announcement = red block !-->
-------------------------------------------------
[title]                 [post date=12.9.15 11:23]
[author]
-------------------------------------------------
[content]
-------------------------------------------------

编辑: 顺便说一句,我正在使用 smarty 模板引擎,如果它确实有什么不同的话。

这不是我所说的好的解决方案,但可以使用子查询和联合来实现:

SELECT type, title, whoWhere, whenPosted, description
FROM (
    SELECT 'announcement' as type, 
           title, 
           author as whoWhere, 
           posted as whenPosted,
           content as description
    FROM announcements
    WHERE 1
        UNION
    SELECT 'event' as type,
           title,
           place as whoWhere,
           creationdate as whenPosted,
           description
    FROM events
    WHERE 1
) AS feed
ORDER BY whenPosted

一个更好的解决方案是制作一个具有规范化字段的新闻源 table(或视图)。

我是如何解决这个问题的? 这是我的 'thank you' 堆栈溢出:)

[在此处插入咖啡壶图片]

  1. 我构建了一个连接到数据库的 ORM 抽象 class 并具有一个接口,这样派生对象只需在数据库中输入它的 table 即可构建,主要-键列等..

  2. 在这个 ORM 摘要 class 中,我有一个函数可以获取特定 table 中的所有记录。这是一个名为 all() 的静态函数。它的工作方式是,对于 table 中的每条记录,它都会创建一个同类对象并将其推送到一个数组中。最后,我得到一个数组,其中填充了代表整个 table 数据的对象。

  3. 要创建提要 - 我采用了我想要的两个模块 - 公告和事件,分别创建每个 class - 公告和事件,每个模块都从自己的 table 在数据库中。

  4. 我用array_merge合并了Announcement::all()和Event::all()的结果。现在我有一个数组,其中包含数据库中的所有公告和事件。

  5. 现在,我需要按日期对这些 post 进行排序。我在 ORM 摘要 class 中创建了一个神奇的方法来执行此操作 -> __get,即 returns 我需要从记录详细信息中获取的特定字段。现在我可以使用 usort 按数据对数组进行排序。

  6. 最终修复 - 我想知道每个 post 的类型,这样我就可以为每个都有不同的布局。我用 smarty 支持的 instanceof 解决了它。

最终结果:

private function get_feed_content()
{
    $feed = array_merge(Announcement::all(), Event::all());

    usort($feed, function($a, $b)
    {
        return (strtotime($b->create_date) - strtotime($a->create_date));
    });

    return $feed;
}

简洁大方,正是我想要的样子。 :)

希望我启发了一些人。感谢所有阅读它并试图帮助我的人。

我们通过创建一个结合了 table 的 mysql 视图来做到这一点,然后我们处理该视图,就好像它是一个规范化的 table(创建了它自己的模型为了它和一切!)。稍后如果视图变得太重,我们总是可以通过最少的重构来规范化内容。我们可能还会考虑 getstream.io

等解决方案

公认的解决方案在 PHP 上看起来相当繁重,当您可以直接使用 MySQL 执行某些操作并利用其在 UNION 和 ORDERBY 上的速度时。

因此,如果这对任何人有进一步的帮助,我们将采用 samlev 答案(一个庞大的 UNION),但我们需要让某些提要仅对某些用户可用。所以我们要...

  • 将 UNION 放入 VIEW 中 table 使其始终存在
  • 在 VIEW table 中添加外键到指向允许访问该对话的用户的对话模型

HTH