热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Laravel雄辩的加入vs内加入?-LaravelEloquentJoinvsInnerJoin?

SoIamhavingsometroublefiguringouthowtodoafeedstylemysqlcall,andIdontknowifits

So I am having some trouble figuring out how to do a feed style mysql call, and I don't know if its an eloquent issue or a mysql issue. I am sure it is possible in both and I am just in need of some help.

因此,我在解决如何使用提要样式的mysql调用时遇到了一些麻烦,我不知道这是一个有说服力的问题还是一个mysql问题。我相信两者都有可能,我只是需要一些帮助。

So I have a user and they go to their feed page, on this page it shows stuff from their friends (friends votes, friends comments, friends status updates). So say I have tom, tim and taylor as my friends and I need to get all of their votes, comments, status updates. How do I go about this? I have a list of all the friends by Id number, and I have tables for each of the events (votes, comments, status updates) that have the Id stored in it to link back to the user. So how can I get all of that information at once so that I can display it in a feed in the form of.

我有一个用户,他们去他们的feed页面,在这个页面上显示他们的朋友的东西(朋友投票,朋友评论,朋友状态更新)。假设我有tom, tim和taylor作为我的朋友,我需要得到他们所有的选票,评论,状态更新。我该怎么做呢?我有一个按Id号排列的所有朋友的列表,我有每个事件(投票、评论、状态更新)的表,其中存储了Id以链接回用户。我如何能一次得到所有这些信息,这样我就可以在提要中以。

Tim commented "Cool"

提姆说“酷”

Taylor Said "Woot first status update~!"

泰勒说“Woot first status update~!”

Taylor Voted on "Best competition ever"

泰勒投票评选“史上最好的比赛”

Edit @damiani So after doing the model changes I have code like this, and it does return the correct rows

编辑@damiani,在做了模型修改之后,我有这样的代码,它确实返回了正确的行

$friends_votes = $user->friends()->join('votes', 'votes.userId', '=', 'friend.friendId')->orderBy('created_at', 'DESC')->get(['votes.*']);
$friends_comments = $user->friends()->join('comments', 'comments.userId', '=', 'friend.friendId')->orderBy('created_at', 'DESC')->get(['comments.*']);
$friends_status = $user->friends()->join('status', 'status.userId', '=', 'friend.friendId')->orderBy('created_at', 'DESC')->get(['status.*']);

But I would like them all to happen at once, this is because mysql sorting thousands of records in order is 100x faster then php taking 3 lists, merging them and then doing it. Any ideas?

但是我希望它们同时发生,这是因为mysql对成千上万条记录进行排序的速度比php快100倍,php取3个列表,合并它们,然后进行排序。什么好主意吗?

2 个解决方案

#1


23  

I'm sure there are other ways to accomplish this, but one solution would be to use join through the Query Builder.

我确信还有其他方法可以实现这一点,但是一种解决方案是通过查询构建器使用join。

If you have tables set up something like this:

如果你有这样的表格:

users
    id
    ...

friends
    id
    user_id
    friend_id
    ...

votes, comments and status_updates (3 tables)
    id
    user_id
    ....

In your User model:

在你的用户模型:

class User extends Eloquent {
    public function friends()
    {
        return $this->hasMany('Friend');
    }
}

In your Friend model:

在你的朋友的模型:

class Friend extends Eloquent {
    public function user()
    {
        return $this->belongsTo('User');
    }
}

Then, to gather all the votes for the friends of the user with the id of 1, you could run this query:

然后,要为id为1的用户的朋友收集所有选票,可以运行以下查询:

$user = User::find(1);
$friends_votes = $user->friends()
    ->with('user') // bring along details of the friend
    ->join('votes', 'votes.user_id', '=', 'friends.friend_id')
    ->get(['votes.*']); // exclude extra details from friends table

Run the same join for the comments and status_updates tables. If you would like votes, comments, and status_updates to be in one chronological list, you can merge the resulting three collections into one and then sort the merged collection.

对注释和status_updates表运行相同的连接。如果您希望在一个时间列表中使用投票、注释和status_updates,您可以将产生的三个集合合并为一个,然后对合并的集合进行排序。


Edit

编辑

To get votes, comments, and status updates in one query, you could build up each query and then union the results. Unfortunately, this doesn't seem to work if we use the Eloquent hasMany relationship (see comments for this question for a discussion of that problem) so we have to modify to queries to use where instead:

要在一个查询中获得选票、注释和状态更新,可以构建每个查询,然后将结果合并。不幸的是,如果我们使用雄辩的hasMany关系(关于这个问题的讨论请参阅对这个问题的评论),这似乎行不通,因此我们必须修改查询以使用where:

$friends_votes = 
    DB::table('friends')->where('friends.user_id','1')
    ->join('votes', 'votes.user_id', '=', 'friends.friend_id');

$friends_comments = 
    DB::table('friends')->where('friends.user_id','1')
    ->join('comments', 'comments.user_id', '=', 'friends.friend_id');

$friends_status_updates = 
    DB::table('status_updates')->where('status_updates.user_id','1')
    ->join('friends', 'status_updates.user_id', '=', 'friends.friend_id');

$friends_events = 
    $friends_votes
    ->union($friends_comments)
    ->union($friends_status_updates)
    ->get();

At this point, though, our query is getting a bit hairy, so a polymorphic relationship with and an extra table (like DefiniteIntegral suggests below) might be a better idea.

不过,在这一点上,我们的查询变得有点麻烦了,因此一个多态关系和一个额外的表(就像下面给出的定义一样)可能是个更好的主意。

#2


2  

Probably not what you want to hear, but a "feeds" table would be a great middleman for this sort of transaction, giving you a denormalized way of pivoting to all these data with a polymorphic relationship.

可能不是您想要听到的,但是一个“提要”表将是这种事务的一个很好的中间体,使您能够以一种非规格化的方式以多态性关系对所有这些数据进行旋转。

You could build it like this:

你可以这样构建它:

increments('id');
    $table->timestamps();
    $table->unsignedInteger('user_id');
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    $table->morphs('target'); 
});

Build the feed model like so:

构建提要模型如下:

belongsTo('User');
    }

    public function target()
    {
        return $this->morphTo();
    }
}

Then keep it up to date with something like:

然后保持最新的信息,比如:

id;
    $user_id     = $vote->user_id;

    Feed::create(compact('target_type', 'target_id', 'user_id'));
});

You could make the above much more generic/robust—this is just for demonstration purposes.

您可以使上面的内容更加通用/健壮—这只是为了演示目的。

At this point, your feed items are really easy to retrieve all at once:

此时,您的提要条目非常容易同时检索到所有内容:

with('user', 'target')
    ->orderBy('created_at', 'desc')
    ->get();

推荐阅读
  • spotify engineering culture part 1
    原文,因为原视频说的太快太长,又没有字幕,于是借助youtube,把原文听&打出来了。中文版日后有时间再翻译。oneofthebigsucceessfactorshereatSpo ... [详细]
  • 1.File类:文件和目录路径名的抽象表现形式2.创建对象:File(Stringpathname)通过给定的路径创建文件对象File(Stringpa ... [详细]
  • UNP总结 Chapter 12~14 IPv4与IPv6的互操作性、守护进程和inet超级服务器、高级I/O函数
    一、IPv4与IPv6的互操作性1.IPv4客户与IPv6服务器拥有双重协议栈的主机的一个基本特性就是:其上运行的IPv6服务器既能应付IPv4客户,又能应付IPv6客户。这是通过使用IPv4映射 ... [详细]
  • java中如何对汉字进行排序?
    前言:上一篇文章我们讲解了java中实现Comparator进行排序和实现Comparable进行排序,我们分别举例根据学号和姓名降序排序, ... [详细]
  • 自定义RecyclerView添加EmptyView
    你知道RecyclerView里没有Em ... [详细]
  • PIMPL 是 C++ 中的一个编程技巧,意思为指向实现的指针。具体操作是把类的实现细节放到一个单独的类中,并用一个指针进行访问 ... [详细]
  • delphi控件大全
    本文章已收录于:delphi控件查询:http:www.torry.nethttp:www.jrsoftware.orgTb97最有名的工具条(ToolBar) ... [详细]
  • 找出字符串中重复字符
    2019独角兽企业重金招聘Python工程师标准packagejavaBasic;importjava.util.HashMap;importjava.util.Map; ... [详细]
  • 我正在使用数组列表通过构建一个交互式菜单供用户选择来存储来自用户输入的值。到目前为止,我的两个选择是为用户提供向列表输入数据和读取列表的全部内容。到目前为止,我创建的代码由两个类组成。 ... [详细]
  • 我理解ViewHolder的onBindViewHolder如何工作,但是我不清楚notifyItemRangeChanged(0,this.data.size())如何;适用于此示例以及它的确 ... [详细]
  • 在这一期的SendMessage函数应用中,我将向大家介绍如何利用消息函数来扩展树型列表(TreeView)控件的功能相信对于树型列表控件大家十分的熟悉, ... [详细]
  • Flex中使用filter过滤数据 ... [详细]
  • 发现很多时候展示一堆文字,需要让局部的某些字变粗啊,变大、变颜色、能点击等等要求,今天在这简单总结下方便日后直接复用(用ht ... [详细]
  • 九日集训 Day 4 指针
    一、概念定义1、指针即地址计算机中所有的数据都必须放置在内存中,不同类型的数据占用的字节数也不一样,例如32位整型int占据4个字节,64位整型longlong占据8个字节,字符型 ... [详细]
  • IDEA实用插件Lombok
    LombokLombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。通常,我们所定义的对象和b ... [详细]
author-avatar
手浪用户2602933263
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有