请教一类复杂的数据库关联关系如何使用 ORM 表述?

问题

最近在做一款翻译相关的产品,遇到一个问题
已知有以下四个维度(language 可以看作两张表)

  • 产品 - product 表
  • 领域 - domain 表
  • 源语言 - language 表(from)
  • 目标语言 - language 表(to)

各个维度之间多对多关联

  • 每个产品下面有支持的领域
  • 每个产品领域下面有支持的源语言
  • 每个产品领域源语言下面有支持的目标语言 :joy:

如何创建中间表来关联他们的关系?

现有方法

目前的方法是创建了一个中间表,direction(product_domain_from_to),每两张表都通过这个中间表里的两个字段关联

class Product extends Model
{
    ...
    public function domains()
    {
        return $this->belongsToMany(Domain::class, 'direction', 'product_id', 'domain_id');
    }
    ...
}

class Domain extends Model
{
    ...
    public function froms()
    {
        return $this->belongsToMany(Language::class, 'direction', 'domain_id', 'from_id');
    }
    ...
}

class Language extends Model
{
    ...
    public function tos()
    {
        return $this->belongsToMany(Language::class, 'direction', 'from_id', 'to_id');
    }
    ...
}

其中 Product 表正常,但是如果期望获取到某个产品的领域的源语言下面有支持的目标语言的话就比较麻烦了,必须手动传入 product_id, domain_id

return Language::findOrFail($fromId)
    ->tos()
    ->wherePivot('product_id', $productId)
    ->wherePivot('domain_id', $domainId)
    ->get()

这样就无法使用with的方法获取数据了

return Language::with('tos')->findOrFail($fromId)->tos;

想看看大家有没有什么更好的数据库设计方案或者编码逻辑

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2

感觉你的关联梳理是不是有点问题:

  1. 源语言为什么要放在领域下面,不是应该跟产品关联么,不可能某个领域的所有产品的源语言都一样吧
  2. 同样的目标语言应该也是直接跟产品关联更合理一点吧

如果说必须要这么关联的话,远程关联应该可以解决你的问题

3年前 评论
licxisky (楼主) 3年前
licxisky (楼主) 3年前
zxdstyle (作者) 3年前

如果是复杂的sql、为啥不用DB facade来进行查询呢?

3年前 评论
licxisky (楼主) 3年前
cheer (作者) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!