Трехуровневый шаблон и большие объемы данных

Вот моя ситуация: я стараюсь изо всех сил следовать трехуровневому шаблону (т. Е. Уровень представления, бизнеса и данных). Когда мне нужны данные из БД, бизнес-уровень вызывает уровень данных, который возвращает информацию. Уровень данных никогда не возвращает объект SqlDataReader или DataTable, но часто представляет собой перечисление настраиваемого объекта, известного на уровне доступа к данным. Это работает очень хорошо, когда уровень данных должен возвращать список с несколькими объектами.

Теперь я столкнулся с этой проблемой, мое приложение (бизнес-уровень) должно обрабатывать 500000 записей. Я мог бы просто добавить еще один метод к моему слою данных и вернуть IEnumerable, но это звучит очень плохо для меня. Я не хочу загружать полмиллиона записей в память.

У меня вопрос: учитывая трехуровневую модель, как мне поступить в этом случае? Если бы у меня не было трехуровневого шаблона, я бы просто использовал SqlDataReader в своих бизнес-классах. Какие-либо предложения?

ОБНОВЛЕНИЕ: данные не будут отображаться, так что это не проблема подкачки (уровень представления здесь вообще не задействован). Я просто должен анализировать каждую запись, а затем сохранять некоторые из них.

Спасибо


person Martin    schedule 25.05.2009    source источник


Ответы (9)


Я предполагаю, что вы не отображаете 500 000 записей сразу? Вы, наверное, разбиваете страницы, верно? Таким образом, за один раз возвращайте только одну страницу данных из базы данных.

person Matt Grande    schedule 25.05.2009

Да, ваше чутье верно.

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

У вас есть выбор, где и когда ваше приложение будет обрабатывать эти полмиллиона записей. Вы можете разделить их на более мелкие единицы работы; вы можете обрабатывать их асинхронно; вы можете написать хранимую процедуру и обрабатывать их в базе данных, не перенося их на промежуточный уровень.

Шаблон MVC прекрасен, но это не святое писание. Сделайте выбор, который работает для вашего приложения.

person duffymo    schedule 25.05.2009

Бумага никогда не сможет превзойти реальность. Если ваша конкретная проблема требует сломать трехуровневую парадигму, сделайте это.

person Aaron Digulla    schedule 25.05.2009

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

  1. Когда вы «анализируете каждую запись, а затем сохраняете некоторые из них», действительно ли это является частью бизнес-логики? Или это функция доступа к данным? Возможно, это относится к уровню доступа к данным.

  2. Если это является частью бизнес-логики, нужны ли вам все 500 000 записей, чтобы принять решение о том, следует ли «сохранять» какую-либо отдельную запись? Возможно, бизнес-уровень должен обрабатывать одну запись за раз. Делать 500 000 последовательных вызовов базы данных некрасиво, но если это то, что приложение должно делать с концептуальной точки зрения, есть способы смягчить это.

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

--
бмб

person bmb    schedule 25.05.2009

Вы можете создать абстракцию поверх класса SqlReader. Таким образом, вам не нужно передавать SqlReader напрямую, но вы все равно можете обрабатывать объекты по одному.

Подумайте об итераторах.

person Peter Stuifzand    schedule 25.05.2009

Выполните фильтрацию в базе данных. нет необходимости приводить более 500000 записей, которые вы все равно собираетесь отфильтровывать. Зачем выносить их всех на средний уровень только для того, чтобы убрать. Позаботьтесь об операции (данных) как можно раньше, используя SQL Engine в серверной части (sproc). Наиболее эффективен, аналогичен проверке основных входных данных на уровне представления перед отправкой в ​​IIS.

person Tim    schedule 21.08.2012

Это нередкая проблема, и она часто возникает в ситуациях, когда необходимо консолидировать большие объемы данных и предоставить пользователю сводки (типичным примером являются отчеты). Ваше решение должно быть разработано с учетом этих соображений. Нет смысла игнорировать эффективность, обеспечиваемую средствами чтения sql (или аналогичными инструментами), когда строгое соответствие какой-либо конкретной архитектурной модели делает ваше приложение неэффективным. Часто можно преодолеть некоторые из этих проблем, адаптировав архитектурную модель к вашим потребностям. Общие архитектурные модели редко применимы в готовом виде. Это рекомендации, которые следует применять к вашим конкретным потребностям.

person Richard Dorman    schedule 25.05.2009

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

Вопрос в том, ожидает ли пользователь нажать кнопку, обработать все 500 тыс. записей и увидеть результат? Если да, готовы ли они сидеть и смотреть крутящуюся гифку, или будет достаточно получить какое-то уведомление, когда процесс завершится? Если обработка 500 КБ имеет первостепенное значение, требуется ли изменение вашей модели данных для поддержки этого процесса? Существуют такие методы обработки, как Hadoop и очереди сообщений, предназначенные для такого большого объема, но нужно ли вам идти в этом направлении? Возможно, вы сможете установить ожидания своих пользователей, прежде чем рвать на себе волосы из-за производительности.

person David Robbins    schedule 25.05.2009

Если я правильно понимаю, вы хотите «Проанализировать» записи, а затем сохранить некоторые из них и избавиться от остальных. Что ж, в таком случае я думаю, что лучше всего будет справиться с этим в самой базе данных (PL/SQL или T/SQL). Такие требования должны быть главным приоритетом, а не архитектура. Поскольку вы не показываете, а просто анализируете, лучше всего сделать это в самой процедуре.

person cbrcoder    schedule 26.05.2009