首页 > 解决方案 > 如何在处理雄辩关系的同时合并/合并三个具有精确模式但数据不同的数据库表?

问题描述

在我的 Laravel 应用程序中,我有三个具有完全相同结构/模式的数据库表,然后有一个包含所有用户的“用户”表。

所有三个表都具有以下结构...

table1
id user_id description updated_at created_at
1 1 这很好 xxxxxxxxxx xxxxxxxxx
2 2 是的,它是 xxxxxxxxxx xxxxxxxxx

table2
id user_id description updated_at created_at
1 3 另一个文本 xxxxxxxxxx xxxxxxxxx
2 4 还有更多 xxxxxxxxxx xxxxxxxxx

table3
id user_id description updated_at created_at
1 5 更漂亮 xxxxxxxxxx xxxxxxxxx
2 6 好的 xxxxxxxxxx xxxxxxxxx

现在我真的很想将数据保存在这些单独的表中。但是,有时我需要在同一个视图中显示这三个表中的所有这些条目,最好是orderedBy created_at 字段。

我使用以下代码来合并这些表:

   $table2 = DB::table('table2');
   $table3 = DB::table('table3');
   $query = DB::table('table1')
        ->union($table1)
        ->union($table3)
        ->get();

出现的问题是,雄辩的关系不起作用,Blade 中的这个陈述就被打破了。{{$comment->user->name}}.

我只想能够合并/合并所有这三个表,并且最好能够建立关系或找到其他方式,以便我可以获得在合并/合并结果中拥有特定条目的用户的名称。并且还有联合/合并结果orderBy created_at 列。

任何帮助将不胜感激。

谢谢

标签: phpmysqllaravellaravel-5.7eloquent-relationship

解决方案


连接

(这里是如何做你的方式)

在收藏中给它。在这里,我渴望加载用户,但您不必这样做。不过,它将大大提高性能。请注意,由于您的设计选择,这是 3 个不同的查询,每个查询都会执行一个连接)。

$table1 = Table1::with('user')->all();
$table2 = Table2::with('user')->all();
$table3 = Table3::with('user')->all();
$tables = $table1->merge($table2)->merge($table3);
$tables = $tables->sortBy('create_at');

数据库和 OOP 设计

(这是你应该怎么做的)

为什么要将它们放在单独的表中?大多数人通常认为糟糕的设计不能正常化。如果两个对象具有相同的字段/成员,则它们是相同种类的对象。

如果对象具有相同的字段,则它们应该是相同类型的对象,并且您应该为要获取的对象的类型添加一个标志。所以而不是有三个表

  • ID
  • 用户身份
  • 描述
  • 更新时间
  • created_at

您将拥有一张包含以下字段的表格:

  • ID
  • 用户身份
  • 描述
  • 类型
  • 更新时间
  • created_at

确保放置一个indexon type,因此将它们全部放在同一张桌子上不会影响性能。然后让它们全部按 created_at 排序(注意一个查询,一个连接):

$tables = Table::->orderBy('created_at')->with('user')->get();

要打破一个:

$table1 = Table::where('type','=',1)->with('user')->get();
$table2 = Table::where('type','=',2)->with('user')->get();
$table3 = Table::where('type','=',3)->with('user')->get();

为了得到他们所有,打破:

$tables = Table::->orderBy('created_at')->with('user')->get()->groupBy('type');

如果对象的一种(或多种)“类型”具有新字段,那么您就开始了继承之路。


推荐阅读