php - 显示喜欢项目列表中项目的用户

标签 php mysql database performance

我认为这是一个不切实际的问题,但我想得到一些反馈来确认。

我有一个产品和用户数据库,用户可以在其中喜欢产品,喜欢的数据存储在一个只有 pid 和 uid 的引用表中。

客户的要求是显示 3 个喜欢产品列表中每个产品的用户。

问题是,不可能在产品列表的一次查询中获取此数据,

我曾经实现和随后取消实现的方式是在产品列表循环期间为喜欢产品的用户执行请求。

即。

foreach($prods as $row):
$likers = $this->model->get_likers($row->id);
endforeach;

这行得通,但显然不仅会导致产品列表超慢,还会对数据库/CPU 造成很大压力。

最终实现的解决方案是只显示最近喜欢它的用户(这可以从产品列表查询中的连接获得)并有一个链接显示有多少人喜欢,点击它, 打开一个 ajax 点赞者列表。

所以我的问题是,是否真的有一种技术可以在产品列表中显示喜欢者,或者根本不可能实际执行?我实际上注意到,对于大多数社交媒体网站,它们不会在列表中显示所有喜欢者,而是采用“点击查看喜欢者”方法。但是,他们确实会显示列表中每个项目的评论,这实际上涉及相同的问题,不是吗?

编辑:附加在期望结果上的模型。每页将有 30 个产品。

enter image description here

最佳答案

通过阅读您对 Alex.Ritna 的评论回复,是的,您可以获得 x 号。每组的结果,使用 GROUP_CONCAT()SUBSTRING_INDEX()它将显示用逗号或您在查询中指定的任何分隔符分隔的喜欢者(我使用了 ||)。 ORDER BY子句可用于 group_concat 函数。由于没有可用的架构信息,因此我假设您有一个产品表、一个用户表和一个维护用户和产品关系的联结表。在子字符串函数中,我使用了 x=3

SELECT p.*,
COUNT(*) total_likes,
SUBSTRING_INDEX(
GROUP_CONCAT( CONCAT(u.firstname,'  ',u.lastname)  ORDER BY some_column DESC SEPARATOR '||'),
'||',3) x_no_of_likers
FROM product p
LEFT JOIN junction_table jt ON(p.id=jt.product_id)
INNER JOIN users u  ON(u.id=jt.user_id)
GROUP BY p.id

Fiddle

现在在您的应用程序级别,您只需循环遍历产品并拆分 x_no_of_likers按分隔符,您是每个产品的喜欢者

foreach($prods as $row):
$likers=explode('||',$row['x_no_of_likers']);
$total_likes= $row['total_likes'];
    foreach($likers as $user):
    ....
    endforeach;
endforeach;

注意 GROUP_CONCAT() 上设置了默认的 1024 个字符限制但您也可以按照 GROUP_CONCAT() 来增加它手册

从评论中编辑 这是另一种获取每组 n 个结果的方法,从中你可以从用户表中获取所有字段我使用了一些变量来获取产品组的排名,用于 junction_table 的子查询为了获得排名,在外部选择中,我使用 HAVING jt.user_rank <=3 过滤了具有此排名的记录所以它会给每个产品三个用户记录,我也使用了产品的子查询(SELECT * FROM product LIMIT 30 )所以前 30 个组每个会有 3 个结果,因为最后不能使用低于查询限制所以我在子查询中使用了

SELECT p.id,p.title,u.firstname,u.lastname,u.thumbnail,jt.user_rank
FROM 
(SELECT * FROM `product` LIMIT 30 ) p
LEFT JOIN 
 (  SELECT j.*,
   @current_rank:= CASE WHEN @current_rank = product_id THEN  @user_rank:=@user_rank +1 ELSE @user_rank:=1 END  user_rank,
   @current_rank:=product_id
    FROM `junction_table` j ,
    (SELECT @user_rank:=0,@current_rank:=0) r   
    ORDER BY product_id 
  ) jt ON(jt.product_id = p.id)
  LEFT JOIN `users` u ON (jt.`user_id` = u.`id`) 
  HAVING jt.user_rank <=3 
  ORDER BY p.id

Fiddle n results per group

关于php - 显示喜欢项目列表中项目的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22677781/

相关文章:

php - 随机 CSS 背景图片

php - 如何配置 vscode 实时服务器以正确处理 php 文件(我使用的是 Win10 和 Chrome)?

mysql - 如何创建临时表而不丢失 Django 中的 ORM?

php - MySQL统计一张表中最大的引用路径

php - 将一个表中的字段保存到 PHP 变量并在另一个查询中使用

php - 将 div 位置和大小属性插入 MySQL 数据库。如何使用 PHP 收集信息?

php - 使用 SoapClient 从 PHP 中的 WSDL 获取元素

mysql - 在 mysql 和 oracle 中按查询分组

ruby-on-rails - 谷歌地图 API 简单标记

javascript - 从 JavaScript 对象数组中生成 json