Альтернатива SQL-ограничению результирующего набора - PullRequest
0 голосов
/ 21 февраля 2019

Мы запрашиваем реляционную базу данных, используя стандартизированный SQL.Результатом запроса является двумерная таблица;строки и столбцы.

Мне очень нравится структура well rdms (я, честно говоря, никогда не работал профессионально с другими системами БД).Но язык запросов или, точнее, набор результатов, который создает sql, является довольно ограничивающим фактором, влияющим на производительность в целом.

Давайте создадим простой пример: Customer - Order (1 - n) Я хочу опросить всех клиентов, начиная с буквы«А» имеет заказ в этом году и отображает каждый со всеми его / ее заказами.

У меня есть два варианта запроса этих данных.

Опция 1 Загрузить данные содин запрос с объединением обеих таблиц.Недостаток: результат, который передается клиенту, содержит дублированные данные клиента, которые представляют собой накладные расходы.

Опция 2 Запрос клиентов и запуск второго запроса для загрузки их заказов.Недостатки: 2 запроса, которые приводят к удвоенной задержке в сети, где второй член запроса может быть очень большим, что может привести к нарушению ограничения длины запроса, производительность не является оптимальной, поскольку оба запроса выполняют соединение / фильтрацию в / изордера

Конечно, возможен третий вариант, когда мы начинаем запрос с таблицы ордеров.

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

Таким образом, в идеале SQL мог бы указывать результат запроса в форме структуры объекта.Представьте, что результат запроса будет структурирован как xml или json вместо таблицы.Если вы когда-либо работали с ORM, например EntityFramework, вы, возможно, знаете команду «Включить».С поддержкой команды include в sql и возвращением результата не как join, а как структура, мир стал бы лучше.Другим сценарием будет запрос на включение, но без дубликатов.Так что в основном две таблицы в одном результате.Чтобы визуализировать это, результаты могут выглядеть следующим образом:

{
  { customer 1 { order 1 order 2} }
  { customer 2 { order 3 order 4} }
} or
{
  { customer1, customer2 }
  { order1, order2, order3, order4 }
}

В MS SQL Server есть функция «Множественные результирующие наборы», которая, я думаю, довольно близка.Но это не часть стандартного SQL.Также я не уверен, что ORM Mappers действительно используют такую ​​функцию.И я предполагаю, что все еще выполняется два запроса (но один запрос от клиента к серверу).Вместо того, чтобы что-то типа «выберите клиентов, включите заказы. От клиентов присоединяйтесь к заказам, где клиенты начинаются с буквы« А », а заказы ...»

Вы обычно сталкиваетесь с такой же проблемой?Как вы решите это, если так?Знаете ли вы язык запросов к базе данных, который может сделать это, возможно, даже с существующей поддержкой ORM Mapper (возможно, нет)?У меня нет реального опыта работы с другими системами баз данных, но я не думаю, что все новые системы баз данных решают эту проблему?(но, конечно, другие проблемы) Интересно то, что, как я понимаю, в графовых базах данных соединения в основном бесплатны.

Ответы [ 2 ]

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

Есть возможность вернуть json на некоторый SQL-сервер.Если у вас есть таблица A, относящаяся к таблице B, и каждая запись в таблице указывает максимум на одну запись в таблице A, то вы можете уменьшить перегрузку трафика, как вы описали.В качестве примера можно привести адрес и их контакты.

SELECT * FROM Address
JOIN Contact ON Address.AddressId = Contact.AddressId
FOR JSON AUTO

Результат возврата SQL будет меньше:

"AddressId": "3396B2F8",
"Contact": [{
        "ContactId": "05E41746",
        ... some other information
    }, {
        "ContactId": "025417A5",
        ... some other information
    }, {
        "ContactId": "15E417D5",
        ... some other information
    }
    }
]

Но на самом деле я не знаю ни одного ORM, который обрабатывает JSON длясокращение трафика.Если бы у вас было несколько контактов для разных адресов, это могло бы привести к обратным результатам.

Не забывайте, что JSON также имеет некоторую избыточность, и его необходимо сериализовать и десериализовать

Оптимальным для сокращения трафика будетесли SQL-сервер разделяет объединенный результат на множественные результирующие наборы и клиент соответственно Object-Relational-Mapper отображает их вместе.Мне было бы интересно, если бы вы нашли решение для вашей проблемы.

Еще один ход мысли - использовать графовую базу данных.

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

Я думаю, что вы можете изменить рабочий процесс своего приложения, чтобы решить эту проблему.Новый рабочий процесс приложения:

  1. Запросите таблицу Customer, которую клиент начинает с буквы «A».Отправьте результат клиенту для отображения.
  2. Пользователь выбирает клиента из клиента и отправляет обратно идентификатор клиента на сервер
  3. Запрос таблицы заказов по идентификатору клиента и отправляет результат клиенту для отображения.
...