3-х уровневая схема и большие объемы данных - PullRequest
5 голосов
/ 25 мая 2009

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

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

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

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

Спасибо

Ответы [ 9 ]

2 голосов
/ 25 мая 2009

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

1 голос
/ 21 августа 2012

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

1 голос
/ 25 мая 2009

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

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

1 голос
/ 25 мая 2009

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

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

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

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

-
BMB

1 голос
/ 25 мая 2009

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

1 голос
/ 25 мая 2009

Да, ваш инстинкт верен.

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

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

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

0 голосов
/ 26 мая 2009

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

0 голосов
/ 25 мая 2009

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

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

0 голосов
/ 25 мая 2009

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

...