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

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

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

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

table2
id user_id описание updated_at создал_at
1 3 Другой текст xxxxxxxxxx xxxxxxxxx
2 4 И еще больше xxxxxxxxxx xxxxxxxxx

Таблица3
id user_id описание updated_at создал_at
1 5 Более красиво ххххххххх хххххххх
2 6 все в порядке xxxxxxxxxx xxxxxxxxx

Теперь я действительно хочу хранить данные в этих отдельных таблицах. Однако есть один странный случай, когда мне нужно было бы показать все эти записи из этих трех таблиц в одном и том же представлении, предпочтительно в поле orderBy create_at.

Я использовал следующий код для объединения этих таблиц:

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

Проблема, которая возникает, заключается в том, что красноречивые отношения не работают, и это утверждение в Blade нарушается. {{$comment->user->name}}.

Я просто хочу иметь возможность объединять / объединять все эти три таблицы и предпочтительно иметь возможность иметь отношения или найти какой-то другой способ, чтобы я мог получить имя пользователя, которому принадлежит конкретная запись в объединении / объединенном результат. А также иметь объединенный / объединенный результат упорядоченный столбец create_at.

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

Спасибо

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Конкатенация

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

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

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

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

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

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

  • id
  • user_id
  • описание
  • updated_at
  • создал_at

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

  • id
  • user_id
  • описание
  • тип
  • updated_at
  • create_at

Обязательно поставьте index на type, так что не влияет на производительность , чтобы вставить их всех в одно и то жеТаблица.Затем, чтобы отсортировать их все по create_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');

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

1 голос
/ 24 апреля 2019

Предположим, что вы хотите объединить результаты 3 сущностей: 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
...