Подход для отображения один-ко-многим в SQL без ORM - PullRequest
0 голосов
/ 15 февраля 2019

Допустим, у меня есть сущность.

class Building {
  List<Floor> floors;
  List<Elevator> elevators; 
}

Для простоты у пола и лифта есть только id.И у здания есть id, elevator_id, floor_id

Таким образом, запрос для получения всех зданий со всеми этажами и всеми лифтами будет:

select 
      id, 
      floor.id as floor_id, 
      elevator.id as elevator_id 
from building 
left join floor on (floor.building_id = building.id)
left join elevator on (elevator.building_id = building.id)

Теперь предположим, что у меня 1 здание с 2полы и 2 лифта.Запрос выдаст набор результатов, например:

 id|floor_id|elevator_id
 1   f1        e1
 2   f2        e2
 1   f1        e2
 2   f2        e1 

Итак, 4 записи.Способ их анализа:

  1. Идти не по строкам, а по столбцам.
  2. Создать каждую сущность отдельно
  3. Удалить дубликаты
  4. Объедините все сущности в правильную структуру.

Итак, вопрос в том, есть ли лучший подход для решения проблемы?А также ORM делает то же самое под капотом или нет?

Не ищу конкретную библиотеку, так как я пытаюсь выяснить, как она работает.

1 Ответ

0 голосов
/ 15 февраля 2019

Выполнить несколько запросов

Интеллектуальный ORM должен выполнить 2-3 запроса:

  1. Запрос, выбирающий все здания и, возможно, их этажи
  2. Выбор запросаЭтажи (если еще не выбраны)
  3. Запрос, извлекающий все лифты

После выполнения этих запросов данные могут быть снова объединены на клиенте.Это не очень хорошая идея, ни в SQL, ни в ORM, делать все это за один раз, используя множество левых соединений, так как вы будете создавать декартово произведение между этажами и лифтами с помощью предложенного вами SQL.Представьте, что если оба левых объединения производят 1000 строк на здание, вы получите 1000000 строк повторяющихся данных, даже если в каждом здании только 2000 дочерних элементов.

Примечание для мультимножеств

Обратите внимание, чтоВ стандарте SQL есть оператор MULTISET(), который будет лучшим выбором, но очень немногие СУБД реализуют его:

select 
  building.*,
  multiset(select * from floor where floor.building_id = building.id),
  multiset(select * from elevator where elevator.building_id = building.id)
from building 

Многие базы данных поддерживают XML и JSON, поэтому решение этой проблемы может помочь в решении этой проблемы.проблема, если бы вы могли абстрагироваться достаточно хорошо.Я не знаю ни о каких ORM, которые сейчас делают это на Java. У jOOQ это есть на дорожной карте , но это не реализовано. Также нет версии Hibernate .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...