2009-05-25 4 views
5

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

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

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

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

Благодаря

ответ

2

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

1

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

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

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

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

0

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

1

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

0

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

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

1

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

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

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

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

-
BMB

1

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

Think Iterators.

0

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

1

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