Как объединить / объединить три таблицы базы данных с точной схемой, но разными данными, заботясь о красноречивых отношениях?

В моем приложении Laravel у меня есть три таблицы базы данных с точно такой же структурой / схемой, а затем есть таблица «пользователи», содержащая всех пользователей.

Все три таблицы имеют следующую структуру ...

table1
id user_id описание updated_at created_at
1 1 Это хорошо xxxxxxxxxx xxxxxxxxx
2 2 да, верно, это xxxxxxxxxx xxxxxxxxx

table2
id user_id описание updated_at created_at
1 3 Другой текст xxxxxxxxxx xxxxxxxxx
2 4 И еще xxxxxxxxxx xxxxxxxxx

table3
id user_id описание updated_at created_at
1 5 Еще красиво xxxxxxxxxx xxxxxxxxx
2 6 Хорошо, готово xxxxxxxxxx xxxxxxxxx

Теперь я действительно хочу хранить данные в этих отдельных таблицах. Однако есть один странный случай, когда мне нужно будет показать все эти записи из этих трех таблиц в одном и том же представлении, предпочтительно в поле orderBy 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.

Любая помощь будет принята с благодарностью.

Спасибо


person Kashif    schedule 24.04.2019    source источник


Ответы (2)


Объединить

(вот как это сделать по-своему)

Ему в коллекциях. Я очень хочу загрузить пользователя, но вам не нужно этого делать. Однако это значительно улучшит производительность. Обратите внимание, что это 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');

База данных и ООП дизайн

(вот как это сделать)

Почему вы хотите, чтобы они были в отдельных таблицах? Обычно считается, что плохой дизайн не нормализуется. Если два объекта имеют одинаковые поля / элементы, они являются одним и тем же ВИДОМ объекта.

Если объекты имеют одинаковые поля, они должны быть одного и того же ВИДА объекта, и вы должны добавить флаг для типа этого объекта, который нужно получить. Поэтому вместо трех таблиц с

  • id
  • ID пользователя
  • описание
  • updated_at
  • создано в

У вас будет одна таблица с полями:

  • id
  • ID пользователя
  • описание
  • тип
  • updated_at
  • создано в

Убедитесь, что вы поставили index на 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');

Если один (или несколько) из «типов» объектов имеет новые поля, вы начинаете переходить по пути наследование.

person J. A. Streich    schedule 24.04.2019

Предположим, вы хотите объединить результаты трех сущностей: director, teacher, student, все эти три сущности имеют отношение role:

Вы можете сначала загрузить отношения, а затем объединить коллекции с помощью один из их многие методы:

$directors = Director::with('role')->get();
$teachers = Teacher::with('role')->get();
$students = Student::with('role')->get();

$users = $directors
            ->merge($teachers)
            ->merge($students);

Тогда вы можете получить доступ к отношению:

dd($users->first()->role->name);

Наблюдение

О чем следует помнить, если вы возвращаете эти значения в представление, используя метод compact вместо with():

return view('my_view', compact('users'));

Затем вы передадите ассоциативный массив вашему представлению, поэтому для доступа к значениям в отношениях вам необходимо сделать:

@foreach ($users as $user)
    <h1> {{ $user['role']['name'] }} </h1>
@endforeach
person Kenny Horna    schedule 24.04.2019
comment
@Kashif было ли это полезно для вас? - person Kenny Horna; 01.05.2019