首页 文章

Laravel - 为什么雄辩不使用join?

提问于
浏览
0

如果我有这个型号

class Post extends Model{
    public function author()
    {
        return $this->belongsTo(Author ::class);
    }

    public function category()
    {
        return $this->belongsTo(Category ::class);
    }

}

class Author extends Model{

}

class Category extends Model{

}

并运行此

$posts = Post::with('author', 'category')->get()

laravel运行3个MySQL查询 . 对我来说,速度和性能在这里并不是真正的问题(虽然,它可能适用于某人),但问题是,如果我想按作者姓名或类别名称对帖子进行排序,我无论如何需要手动加入帖子和类别,这是非常尴尬 .

1.第一个问题是我需要担心选择

->select('posts.*')

例如可以选择类别中的id并将其水合成Post模型 .

2.第二个问题是我需要担心groupBy - > groupBy('posts.id');例如如果关系是hasOne并且帖子有多个类别,则查询将返回更多类别的行 .

第三个问题是我需要改变所有其他的东西

->where('date', $date)

->where('posts.date', $date)

因为帖子和类别可以有日期属性而没有“模糊列”错误可以抛出 .

我认为以雄辩的方式运行连接可能非常笨拙且容易出错 . 有没有人有其他框架ORM(它不一定是PHP)的经验,它使用连接进行急切加载和连接以排序相关表?

PS . 对于过滤相关表我不需要使用连接,但whereHas使子查询通常比连接慢 .

1 回答

  • 1

    我很长一段时间都在使用Laravel / Eloquent这个问题,并且分组,顺序和性能都是同一个设计问题的一部分:Eloquent用于模型而不用于查询 .

    但是,另一方面,它是一种富有表现力的语言,可以完成任务,使用DB :: table('....') - > join ...或任何类型的东西都是浪费 .

    我最满意的解决方案是使用非规范化视图模式 .

    Normalized Data 是有效存储的数据,在创建专用视图(例如具有列子集的简明列表,特定顺序或分组)时难以查询 .

    另一方面, denormalized data 是仅在应用程序的单个部分中有意义的数据,但它是正确格式化和排序的 .

    这种分离对于理解是很重要的,因为我们忽略了在数据库中保存两者是多么容易 . 我们只需要决定 consistent 我们的非规范化视图和规范化数据是如何 .

    简而言之,让我们举一个例子:艺术家,专辑,歌曲 - 所有读者都应该清楚地了解这些关系 .

    我有一个页面,其中显示每个艺术家第一首歌曲的列表,按艺术家姓氏按字母顺序排列,以及该歌曲出现在哪张专辑中 . 如何以雄辩的方式解决这个问题 . 啊 . 此外,我问过我的产品团队,我们都得出结论,用户看到此列表的事件比向艺术家添加新专辑或将新歌添加到专辑中的情况高出100倍,尤其是FIRST SONG每个新艺术家都曾经发生过一次 .

    如果我有一张 table ,我可以运行一些简单的东西 - FirstSong :: orderBy('artist_last_name');

    我没有在查询中捣乱,而是雄辩地更新了我的first_songs视图(或临时表或实际表,无关紧要) . 我插入Song更新的事件,检查这首歌是不是第一个,如果是,我去更新我的first_songs表 . 我甚至在一个单独的过程中使用Laravel的队列或其他任何方式执行此操作,即使这样我的插入也不受影响 . 我甚至可以每天运行一次重新计算整个表的脚本 - 因此first_songs可能不会更新今天的更新 . 谁在乎?

    tl;dr 考虑将您的体系结构更改为具有单独的预加入,视图特定的表,以便使用自己的模型进行此类查询,而不是强制在规范化模型上进行连接 .

相关问题