2016-06-30 2 views
10

У меня есть программная система для выставления счетов. В нем есть ежедневные журналы вызовов пользователей. Журналы горизонтально разделены по дате (месяц). Каждый раздел хранится в отдельной базе данных и может распространяться на несколько экземпляров.Как сортировать горизонтальные секционированные данные

В пользовательском интерфейсе пользователь укажет диапазон дат. Возвращенные данные могут быть отсортированы в любом поле. Диапазон дат может охватывать несколько разделов. Приложение должно поддерживать пейджинг через данные диапазона дат.

Я не могу загрузить слишком много записей в память для сортировки. Помещение сортировки внутри запроса дает мне отсортированные данные внутри одного набора результатов.

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

EDIT: После более подробного анализа этой проблемы у нас есть еще несколько входов. Существует также требование разбивки на страницы. В связи с этим нам нужно выяснить еще один способ сделать сортировку в реальном времени на нескольких наборах результатов.

+1

Вы можете загружать только отсортированный столбец и идентификаторы записей, а затем сортировать и, наконец, загружать записи, которые вы хотите отображать, на основе отсортированных идентификаторов. Я не уверен, что вы могли бы сделать какое-либо значимое чередование на уровне db, поэтому сделать это в вашем коде кажется самым простым способом. Другим вариантом может быть запись (частичных) записей в файл с отображением памяти и сортировка там, но это, вероятно, будет стоить даже больше производительности - ведь у вас здесь есть классическая ситуация с частотой вращения vs-memory. – Thomas

+0

Мы обсудили первый подход, но недостатком этого подхода является то, что нам нужно снова запросить идентификаторы Id, а так как это из пользовательского интерфейса, необходимо также разбиение на страницы. –

+1

Ну, у нас была аналогичная ситуация, когда загрузка всех данных занимала слишком много памяти, и поэтому мы следовали за подходом к первой загрузке только отсортированных данных, а также идентификаторов, а затем сортировки и хранения только идентификаторов. Затем пейджинг будет работать с отсортированными идентификаторами, и только записи, соответствующие идентификаторам страницы, будут загружены полностью. Конечно, вам нужно будет запросить еще раз, но с пейджингом вам все равно придется это делать. Чтобы ускорить второй (поисковый запрос), вы также можете сохранить исходный раздел и только запрашивать эти разделы. – Thomas

ответ

2

Используя возможность ResultSet для загрузки ограниченных данных в память, мы можем предложить решение на Java с помощью Dynamic Comparator. Решение состоит в том, чтобы взять первую запись из каждого набора результатов и отсортировать ее в java и вернуть первый элемент из отсортированных данных.

Подробное решение:

Сначала мы создали программу, которая может дать нам dymanic компаратора на основе критериев Choosed на экране.

Second Мы написали одну обертку AggregateResultSet над DAO, которая обертывает ResultSets из разных разделов. Примечание: эти отдельные ResultSets уже отсортированы по тем же критериям. Затем AggregateResultSet получит динамический компаратор.

Этот AggregateResultSet будет иметь структуру данных для первоначального хранения первого элемента каждого набора результатов. Он вернет следующий элемент при вызове next(). Этот элемент будет элементом, который будет первым в соответствии с dynamicComparator. Во время следующего() вызова мы удаляем этот элемент из временной структуры данных и вставляем следующий элемент из того же набора результатов во временную структуру данных. Таким образом, AggregateResultSet вернет данные в ожидаемом порядке, объединив/сохранив/отсортировав очень ограниченные данные в Java.

Надеемся, что мы не получим проблем со сравнением, поскольку в сортировке мы имеем в основном числовые/строковые данные.

+1

Звучит как интересное решение, которое должно уменьшить накладные расходы памяти в приложении Java. Я не уверен в значениях для баз данных, хотя теоретически вам нужно было бы поддерживать соединение открытым, а также сохранять результат в кэше db, чтобы быстро получить следующий элемент. Кроме того, вы можете столкнуться с транзакционными проблемами, если обновлены данные, хранящиеся в кэше db. – Thomas

+0

@Thomas, поскольку это биллинговая система, данные (записи вызовов) загружаются только один раз (день + 2) после согласования данных на разных уровнях и никогда не обновляются (безопасность). –

+0

Если я правильно понимаю ваше решение, пейджинг будет очень неэффективным, так как вам нужно будет прочитать все страницы «n-1» перед страницей 'n'. –

Смежные вопросы