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

时间:2014-03-27 03:37:31

标签: php mysql database performance social

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

我有一个产品和用户数据库,用户可以在这里使用产品,类似的数据存储在只有pid和uid的参考表中。

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

问题是,无法在产品列表的一个查询中获取此数据,

我曾经实施并随后未实施的方法是在循环期间通过产品列表对喜欢产品的用户执行请求。

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

这样做有效,但显然不仅导致产品列表超级缓慢,而且还会对数据库/ cpu造成很大压力。

实施的最终解决方案是仅显示喜欢它的最新用户(这可以通过产品列表查询中的联接获得)并显示一个链接,显示有多少人喜欢,并点击它,打开一个类似的ajax列表。

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

非常感谢任何帮助/指导!

由于

编辑:模拟了所需的结果。每页将有30个产品。

enter image description here

4 个答案:

答案 0 :(得分:3)

通过阅读您对Alex.Ritna的评论回复,是的,您可以获得x不。对于每组的结果,使用GROUP_CONCAT()SUBSTRING_INDEX()它将显示由逗号分隔的likers或您在查询中指定的任何分隔符(我使用过||)。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过滤了具有此排名的记录,因此它将为每个产品提供三个用户记录,我还使用了子查询产品{{1}所以前30个组每个都有3个结果,因为下面的查询限制不能在最后使用,所以我在子查询中使用了

(SELECT * FROM product LIMIT 30 )

Fiddle n results per group

答案 1 :(得分:1)

您应该能够获得所有使用此sql的所有产品的用户列表。

select uid, 
       count(pid) as liked_products
  from product_user
 group by uid
having liked_products = (select count(1) from products);

但随着数据的增长,这个查询变得缓慢。然后更好地维护一个具有相同计数的表,通过触发器或单独维护。在每个喜欢/不喜欢的情况下,计数器都会更新。这样可以很容易地显示每种产品的喜欢数量。然后,如果想要该产品的实际用户需要单独调用(在用户交互上),该调用将获取一个产品的特定喜欢。在实际请求之前,不要对页面上的所有产品执行此操作。

答案 2 :(得分:0)

我假设这两个表的大小都非常大。您应该创建一个新表(例如LastThreeLikes),其中列为piduid_1uid_2uid_3,由{{1}编制索引}。另外,在名为pid的产品表中添加一列。

对于每个&#34;喜欢&#34;您输入引用表,创建一个触发器,如果​​numLikes小于3,也会填充此LastThreeLikes表。如果要显示新值,可以选择随机更新其中一个值用户偶尔。

在展示产品时,只需从此表中提取numLikes并显示回来。

请注意,您还需要保持&#34;与&#34;不同的触发器。动作(如果有的话)用新的用户ID重新填充uid表。

答案 3 :(得分:0)

<强>问题

问题在于数据量。从您需要两个整数值作为答案的角度来看,您应该忘记从n&lt; - &gt; n关系表中构建一个繁重的查询。

<强>解决方案

每次用户喜欢产品时,使用带有追加选项的file_put_contents()生成可存储的表示。我没有足够的空间在这里写课。

public function export($file);

3D数组格式

array[product][line][user]

示例:

$likes[1293][1][456]=1;
$likes[82][2][656]=1;
$likes[65][3][456]=1;
.
.
.

喜欢此特定产品的用户数量:

$number_users_like_this_product = count($likes[$idProduct]);

所有喜欢这个特定产品的idUser:

$users_like_this_product = count($likes[$idProduct][$n]);

所有人喜欢

$all_likes = count($likes);

正在删除

此循环将取消设置$ idProduct和$ IdUser所需的唯一行。由于所有变量都是无符号整数,因此非常快。

for($n=1, $n <= count($likes[$idProduct]), $n++)
{
 unset($likes[$idProduct][$n][$idUser]);
}

<强>结论

让所有喜欢都很容易:

include('likes.php');

如果您想尝试一下,我会很高兴优化我的东西并分享它。我在2012年创建了这门课程。