Избегайте загрузки ненужных данных из БД в объекты (веб-страницы)

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

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

Некоторые методы, о которых я могу думать:

  1. Не беспокойтесь об этом, просто загружайте все из базы данных каждый раз.
  2. Имейте несколько разных, возможно, унаследованных классов для каждой таблицы и создайте соответствующий ситуации (например, SummaryArticle, FullArticle).
  3. Используйте один класс, но установите для неиспользуемых свойств значение null при создании, если это поле не нужно, и будьте осторожны.
  4. Предоставьте объектам доступ к базе данных, чтобы они могли загружать некоторые поля по требованию.
  5. Что-то другое?

Все вышеперечисленное, как представляется, имеет довольно серьезные недостатки.

Я довольно новичок в программировании, очень новичок в ООП и совершенно новичок в базах данных, поэтому я могу полностью пропустить здесь очевидный ответ. :)


person GmGr    schedule 31.03.2010    source источник


Ответы (3)


(1) К сожалению, ORM по умолчанию загружает весь объект. Вот почему настроенный вручную SQL работает лучше. Но большинству объектов эта оптимизация не нужна, и вы всегда можете отложить оптимизацию на потом. Не оптимизируйте преждевременно (но напишите хороший SQL/HQL и используйте хороший дизайн БД с индексами). Но в целом проекты ORM, которые я видел, приводят к множеству ленивых подходов, извлекающих или обновляющих гораздо больше данных, чем необходимо.

2) Различные модели (сущности), в зависимости от операции. Я предпочитаю этот. Может добавить больше классов в объектный домен, но для меня это самый чистый и приводит к лучшей производительности и безопасности (особенно если вы сериализуете в AJAX). Иногда я использую одну модель для сериализации объекта клиенту, а другую — для внутренних операций. Если вы используете наследование, вы можете сделать это хорошо. Например, CustomerBase -> Customer. CustomerBase может иметь идентификатор, имя и адрес. Клиент может расширить его, чтобы добавить другую информацию, даже такие вещи, как пароли. Для операций со списками (список всех клиентов) вы можете вернуть CustomerBase с помощью пользовательского запроса, но для отдельных операций CRUD (создание/получение/обновление/удаление) используйте полный объект Customer. Даже в этом случае будьте осторожны с тем, что вы сериализуете. У большинства фреймворков есть белые списки атрибутов, которые они будут и не будут сериализовать. Используй их.

3) Опасные, особые случаи вызовут ошибки в вашей системе.

4) Плохо для производительности. Попадите в базу данных один раз, а не для каждого поля (за исключением BLOB).

person codenheim    schedule 31.03.2010

У вас есть несколько способов решить вашу проблему.

  1. Используйте хранимые процедуры в своей базе данных, чтобы удалить ненужные строки или столбцы. Это может отлично работать, но занимает немного места.
  2. Используйте какой-нибудь ORM. Для .NET вы можете использовать Entity Framework, NHibernate или Subsonic. Есть много других инструментов ORM для .NET. В Ruby он встроен в Rails. Java использует Hibernate.
  3. Напишите встроенные запросы на своем веб-сайте. Не забудьте параметризовать их, иначе вы откроете себя для хакеров. Этот вариант обычно осуждается из-за смешения SQL и кода. Кроме того, его легче всего сломать.
person Ben Hoffman    schedule 31.03.2010

Из вашего списка варианты 1, 2 и 4, вероятно, наиболее часто используемые.

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

2. Имейте несколько разных, возможно унаследованных, классов для каждой таблицы и создайте соответствующий ситуации (например, SummaryArticle, FullArticle): Такие классы часто называют «моделями представления» или чем-то подобным, и в зависимости от вашего доступа к данным стратегия, вы могли бы получить такие объекты без фактического объявления какого-либо нового класса. Например, используя Linq-2-Sql, выражение data.Articles.Select(a => new { a .Title, a.Author }) даст вам набор анонимно типизированных объектов со свойствами Title и Author. Сгенерированный SQL будет похож на select Title, Author from Article.

4. Предоставьте объектам доступ к базе данных, чтобы они могли загружать некоторые поля по требованию: Объекты, которые вы здесь описываете, обычно называются "прокси-объектами" и/или их свойства упоминаются как "отложенные загрузки". Опять же, в зависимости от вашей стратегии доступа к данным, создание прокси может быть сложным или легким. Например. с NHibernate вы можете иметь ленивые свойства, просто добавив lazy=true в сопоставление, и прокси-серверы будут созданы автоматически.

В вашем вопросе не упоминается, как вы на самом деле сейчас сопоставляете данные из своей базы данных с объектами, но если вы в данный момент не используете какую-либо структуру ORM, взгляните на NHibernate и Entity Framework - они оба довольно надежные решения.

person Jørn Schou-Rode    schedule 31.03.2010