Chr*_*ens 28 php mysql social-networking
我正在为我们的网站构建一个活动流,并且已经取得了相当不错的进展.
它由两个表提供支持:
流:
id - 唯一的流项目IDuser_id - 创建流项目的用户的IDobject_type - 对象类型(当前为'卖方'或'产品')object_id - 对象的内部ID(当前是卖家ID或产品ID)action_name - 针对对象采取的行动(目前是'买'或'心')stream_date - 创建操作的时间戳.hidden - 用户是否已选择隐藏项目的布尔值.如下:
id - 独特的关注IDuser_id - 启动"关注"操作的用户的ID.following_user - 正在关注的用户的ID.followed - 执行跟随操作的时间戳.目前我正在使用以下查询从数据库中提取内容:
查询:
SELECT stream.*,
COUNT(stream.id) AS rows_in_group,
GROUP_CONCAT(stream.id) AS in_collection
FROM stream
INNER JOIN follows ON stream.user_id = follows.following_user
WHERE follows.user_id = '1'
AND stream.hidden = '0'
GROUP BY stream.user_id,
stream.action_name,
stream.object_type,
date(stream.stream_date)
ORDER BY stream.stream_date DESC;
Run Code Online (Sandbox Code Playgroud)
这个查询实际上运行得很好,并且使用一点点PHP来解析MySQL返回的数据我们可以创建一个很好的活动流,如果行为之间的时间不是太大,同一个用户被分组在一起的行为相同(见下面的例子).

我的问题是,我如何让这更聪明?目前,它通过一个轴"用户"活动进行分组,当特定用户在特定时间范围内有多个项目时,MySQL知道将它们分组.
我怎样才能使这个更智能,并按另一个轴分组,例如"object_id",所以如果同一个对象按顺序有多个动作,则这些项被分组,但保持我们当前用于按用户分组动作/对象的分组逻辑.并实现这一点,没有数据重复?
按顺序出现的多个对象的示例:

我理解像这样的问题的解决方案可以变得非常复杂,非常快,但我想知道是否有一个优雅的,相当简单的解决方案(希望)在MySQL中.
O. *_*nes 18
关于您期望的结果的一些观察:
一些项目是汇总的(杰克斯普拉特心灵七个卖家)和其他项目(尼尔森勋爵特许黄金后市).您可能需要在查询中使用UNION,它将来自两个单独子查询的这两类项目合并在一起.
您可以使用一个相当原始的时间戳,贴近功能组的项目...... DATE().你可能想要使用更复杂和可调整的方案......也许这样
GROUP BY TIMESTAMPDIFF(HOUR,CURRENT_TIME(),stream_date) DIV hourchunk
Run Code Online (Sandbox Code Playgroud)
这将允许您按年龄块分组.例如,如果您使用48,则hourchunk可以将0-48小时前的内容组合在一起.在向系统添加流量和操作时,您可能希望降低该hourchunk值.
boi*_*ert 14
我的印象是你需要像用户一样按用户分组,而且在分组之后,还需要按行动进行分组.
它看起来像你需要这样的子查询:
SELECT *, -- or whatever columns
SUM(actions_in_group) AS total_rows_in_group,
GROUP_CONCAT(in_collection) AS complete_collection
FROM
( SELECT stream.*, -- or whatever columns
COUNT(stream.id) AS actions_in_user_group,
GROUP_CONCAT(stream.id) AS actions_in_user_collection
FROM stream
INNER JOIN follows
ON stream.user_id = follows.following_user
WHERE follows.user_id = '1'
AND stream.hidden = '0'
GROUP BY stream.user_id,
date(stream.stream_date)
)
GROUP BY object_id,
date(stream.stream_date)
ORDER BY stream.stream_date DESC;
Run Code Online (Sandbox Code Playgroud)
您的初始查询(现在是内部查询)按用户分组,但随后用相同的操作重新组合用户组 - 也就是说,购买的相同产品或来自一个卖方的销售将被放在一起.
在Fashiolista,我们开放了构建饲料系统的方法. https://github.com/tschellenbach/Feedly 它是目前最大的开源库,旨在解决这个问题.(但用Python编写)
构建Feedly的同一团队还提供托管API,可以为您处理复杂性.看看getstream.io有PHP,Node,Ruby和Python的客户端. https://github.com/tbarbugli/stream-php 它还支持您正在寻找的自定义聚合.
另外看看这个高可扩展性的帖子,我们解释了一些涉及的设计决策:http: //highscalability.com/blog/2013/10/28/design-decisions-for-scaling-your-high-traffic- feeds.html
本教程将帮助您使用Redis设置Pinterest的Feed这样的系统.开始使用非常简单.
要了解有关Feed设计的更多信息,我强烈建议您阅读我们基于Feedly的一些文章:
我们通过使用"物化视图"方法解决了类似问题 - 我们正在使用专用表来更新插入/更新/删除事件.所有用户活动都记录在此表中,并为预先准备好进行简单的选择和渲染.
好处是简单快速的选择,缺点是插入/更新/删除有点慢,因为日志表也必须更新.
如果这个系统设计得很好 - 这是一个很好的解决方案.
如果您使用带有插入/更新/删除事件的ORM(如Doctrine),这很容易实现