2012-06-04 4 views
1

Это очень простой вопрос, который применяется к программированию веб-интерфейсов с помощью java. Скажем, я не использую ORM (даже если я его использую), и, допустим, у меня есть этот автомобиль (id, name, color, type, blah, blah) в моем приложении, и у меня есть таблица CAR представляют эту сущность в базе данных. Так, скажем, у меня есть эта необходимость обновить только подмножество полей на кучу машин, я понимаю, что типичный поток будет:Должен ли я всегда получать полный объект из базы данных?

  1. DAO класса (CarDAO) - getCarsForUpdate()
  2. перебрать все объекты автомобилей, обновите только цвет, чтобы сказать «зеленый» или что-то еще.
  3. Еще один вызов DAO для обновления автомобилей (автомобили легковые).

Теперь, разве это не так много бьется вокруг куста, что будет простым вопросом выбора и обновления? На первом шаге выше я получаю все данные объекта из базы данных: «выберите id, name, color, type, blah, blah .. где .. от CAR« вместо «выберите id, цвет от CAR, где ... ". Так почему я должен получать эти дополнительные поля, когда вы отправляете вызов DAO, я бы никогда не использовал ничего, кроме «цвета»? То же самое относится к последнему шагу 3. ИЛИ, скажем, я запрашиваю только для идентификатора и цвета (выберите id, color) и создайте объект автомобиля только с заполненным идентификатором и цветом - это нормально, не так ли? В любом случае объект «Автомобиль» анемичен?

Не все ли это (объектно-ориентированная) кажется немного поддельным?

ответ

4

Во-первых, я бы предпочел, чтобы RDBMS могла обрабатывать ваши запросы, пусть это. Причина в том, что вы не хотите, чтобы ваша JVM выполняла всю работу, особенно при запуске корпоративного приложения (и у вас много параллельных подключений, требующих одного и того же ресурса).

Если вы особенно хотите обновить объект (например, установить цвет автомобиля на зеленый) в базе данных, я хотел бы предложить SQL как

UPDATE CAR SET COLOR = 'GREEN'; 

(Заметьте, что я не использовал статью в ГДЕ). Это обновляет таблицу ВСЕCAR и мне не нужно было тянуть весь объект Car, позвоните setColor("Green") и сделайте обновление.

Оглядываясь назад, я пытаюсь сказать, что применяю инженерные знания. Ваш DAO должен просто быстро выбирать, обновлять и т. Д., А все SQL «работать» обрабатываются СУРБД.

+0

Обновление всей таблицы не имеет смысла, когда я хочу обновить только кучу автомобилей на основе некоторых критериев (где условие), не так ли? – Jay

+0

Вопрос в том, почему мы любим вести себя так, как будто мы читаем из РСУБД в объект, когда эти две вещи являются совершенно разными пространствами? Таблицы - это не объекты, объекты не являются таблицами. – Jay

+0

@Jay, все же, можете ли вы написать SQL-запрос, который обрабатывает ваше состояние? Если да, то пусть RDBMS выполнит запрос, а не вытащит его на Java и обновит сам. –

2

Из моего опыта, что я могу сказать: Пока вы не выполняете операции объединения, то есть просто запрашиваете столбцы из одной таблицы, количество выбранных столбцов почти ничего не изменит для производительности. Что действительно влияет на производительность, так это количество строк, которые вы получаете, и предложение where. Извлечение 2 или 20 столбцов настолько мало меняется, что вы не увидите никакой разницы. То же самое для обновления

+0

«почти ничего» - это действительно зависит от таблицы и данных, которые вы получаете, не так ли? Как насчет производительности сети? Как насчет получения огромных текстов? Это влияет на производительность приложения, которое извлекает данные из удаленной базы данных? – Jay

+0

То, что вы пытаетесь сделать, - это оптимизация. Вы бы очень усложнили свою жизнь и приложение, только извлекая и обновляя определенные поля. И это ничего не принесет вам. Конечно, если у вас есть очень конкретные случаи, например столбец с огромным текстом в нем, вы должны разработать конкретное решение. Но это другой вопрос :) – jonasr

+0

Я буду второй jonasr о том, что сокращение количества выбранных столбцов обычно оказывает ограниченное влияние на производительность. СУБД будет в основном получать всю строку за один раз. Единственное различие, которое я вижу, - это скорость передачи в сети, если у вас очень большие столбцы. См. Http://stackoverflow.com/questions/2194424/effect-of-number-of-projections-on-query-performance. Если вы действительно видите улучшение загрузки объектов в своем контексте, вы можете реализовать ленивую загрузку больших столбцов (BLOB, CLOB и т. Д.), Но это заставит вас переписать то, что ORM уже делают из коробки. – guillaume31

1

Я думаю, что в некоторых ситуациях он is полезен для запроса подмножества полей объекта. Это может быть выигрыш в производительности, если у вас большое количество столбцов или есть некоторые большие столбцы BLOB, которые могут повлиять на производительность, если они были увлажнены. Хотя база данных обычно читается во всей строке информации всякий раз, когда есть совпадение, типично хранить BLOB и другие большие поля в разных местах с нетривиальными требованиями ввода-вывода.

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

Кроме того, если вы используете только поля, которые находятся в индексах, я считаю, что сама строка никогда не будет прочитана, и она будет использовать поля из самого индекса. Не уверен в вашем примере, если бы color был проиндексирован.

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

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