回答

收藏

如何以最少的查询获取帖子列表和相关标签

技术问答 技术问答 329 人阅读 | 0 人回复 | 2023-09-12

我的手表结构如下:2 I8 c( r0 z) P5 ]
TAGS(更多类别):    ID,标签名称、描述、子弹4 r! n, {$ l; h
帖子:    id,标题,网址…
; Q( V( A2 ^! C  ~帖子:    id,idPost,idTag# t( X9 M* ]  Q# S! d  h" T0 e
用户:    id,用户名,userSlug …
5 z2 ?# W2 V0 f* @# E5 J5 k! _*投票 *:    id,idPost,idUser
* Y* z. m* M* [7 h) z每个帖子最多可以包含五个标签,每个用户只能投票一次。目前,由于标记尚未实现,我使用以下查询来搜索分页的结果集:& g- [( p3 h6 D5 ]& \# l0 r
SELECT p.*,u.username,u.userSlug,u.id as userId,exists (select 1 from votes v where v.idUser=$id AND p.userId=v.idUser AND p.url = v.url) as voted FROM posts p JOIN users u ON u.id=p.userIdORDER BY p.created DESCLIMIT 10 OFFSET ffset该查询通过PDO运行,并以JSON格式返回给angularjs ng-repeat。该$id用户登录ID。我在exists在子查询中使用它使我的角度视图中的投票按钮变灰(服务器端也有检查)。如果有人单击视图中的用户名,它将被带到一个详细的信息页面,并显示所有用户的帖子(userSlug救援)。
- \3 {- _' [& X4 T' A7 K; o  d下一步是在结果列表中包含标签,这里我结巴巴。列表中的每个帖子都必须包含所有相关标签(tagName,description,slug),而且每个标签都必须带您进入详细的信息页面,所有与特定标签相关的帖子都个页面上。
$ f$ q5 }. ~+ a" B4 N- `" i' V我想到的第一个解决方案是在运行前提到的查询后通过暴力破解我的方法:  @  q/ J; k  W; t3 {; x* I
foreach ($postsResult as &$post)    $sql ="SELECT t.* FROM tags t JOIN poststags pt ON t.id=pt.idTag WHERE pt.idPost=$post->id";    $stmt=$db->prepare($sql);    $stmt->execute();     $tagsResult=$stmt->fetchAll(PDO::FETCH_OBJ);    $post->tags = $tagsResult;}$response->write(json_encode($postsResult));完成,轻松自如!很多查询会给服务器带来很大的压力。我们不想这么做。. [9 E- R- v# t! I4 l: a! w
第二个解决方案是触发另一个查询,它将被获得和获得postsResult(s)所有相关标签,然后在每个帖子中插入相应的标签,使PHP能完成肮脏的工作。
# E% N6 F( {2 c. q+ Y: }$sql = "    SELECT t.*,           pt.idPost       FROM tags t JOIN poststags pt ON t.id=pt.idTag      WHERE pt.idPost IN (array of post ids)";$stmt=$db->prepare($sql);$stmt->execute();$tagsResult = $stmt->fetchAll(PDO::FETCH_OBJ);foreach ($postsResult as &$post)    $arr = array();     foreach ($tagsResult as $tag)        if ($post->id==$tag->idPost)            $arr[]=$tag;         $post->tags = $arr;}$response->write(json_encode($postsResult));有没有更好或更快的方法来做到这一点?8 V% M  g9 f* p5 Y1 _
                                                               
0 S! D, \5 V9 X& R/ C' u1 t    解决方案:                                                                ! e, @8 w& J2 r
                                                                有没有更好或更快的方法来做到这一点?
5 L2 [9 \1 I4 P8 j% C1 r如果指数$tagsResult的postId,您可以通过做FETCH_GROUP,然后你可以取下嵌套循环,在一定的时间内抓住所有帖子ID标签:
# Y; K9 L$ e" D4 Y2 C6 f$sql = "    SELECT pt.idPost,钬? select idPost first so it钬檚 grouped by this col           t.*      FROM tags t JOIN poststags pt ON t.id=pt.idTag      WHERE pt.idPost IN (array of post ids)";$stmt=$db->prepare($sql);$stmt->execute();$tagsResult = $smt->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_OBJ);//$tagsResult is now grouped by postId//see https://stackoverflow.com/questions/5361716/is-there-a-way-to-fetch-associative-array-grouped-by-the-values-of-a-specified-cforeach($postsResult as &$post)    if(isset($tagsResult[$post->id]))        $post->tags = $tagsResult[$post->id];   }    else        $post->tags = array();
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则