Использование ORM или простого SQL?

Для некоторых приложений, которые я разработал (затем начал забывать), я писал простой SQL, в основном для MySQL. Хотя я использовал ORM в python, например SQLAlchemy, я долго не придерживался их. Обычно это была либо документация, либо сложность (с моей точки зрения), удерживающая меня.

Я вижу это так: используйте ORM для переносимости, простой SQL, если он просто будет использовать один тип базы данных. Я действительно ищу совет о том, когда использовать ORM или SQL при разработке приложения, которое нуждается в поддержке базы данных.

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

Ответ 1

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

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

Для приложений с тяжелой отчетностью или для большого количества строк базы данных на запрос ORM налог намного тяжелее, а кэширование, которое они делают, превращается в большую бесполезную нагрузку на память. В этом случае простое сопоставление SQL (LinQ или iBatis) или ручные SQL-запросы в тонком DAL - это путь.

Я обнаружил, что для любого крупномасштабного приложения вы используете оба подхода. (ORM для простого CRUD и SQL/тонкого DAL для отчетов).

Ответ 2

Говоря как человек, который потратил немало времени на работу с JPA (Java Persistence API, в основном стандартизованный API ORM для Java/J2EE/EJB), который включает в себя Hibernate, EclipseLink, Toplink, OpenJPA и другие, я поделюсь некоторые из моих наблюдений.

  • ORM не работают быстро. Они могут быть адекватными, и в большинстве случаев адекватное - это нормально, но в среде с малой задержкой в ​​больших объемах они не являются no-no;
  • В общедоступных языках программирования, таких как Java и С#, вам нужно очень много волшебства, чтобы заставить их работать (например, нагрузка во времени на Java, инструментарий и т.д.);
  • Если вы используете ORM, а не получаете от SQL (что кажется намеренным), вы будете поражены тем, сколько времени вы тратите на изменение XML и/или аннотаций/атрибутов, чтобы заставить ORM генерировать SQL файл с производительностью;
  • Для сложных запросов действительно нет замены. Как и в JPA, есть несколько запросов, которые просто невозможны, которые находятся в необработанном SQL, и когда вам нужно использовать raw SQL в JPA, это не очень (С#/.NET имеет хотя бы динамические типы - var - что много лучше, чем массив объектов);
  • При использовании ORM существует множество "gotchas". Это включает непреднамеренное или непредвиденное поведение, тот факт, что вы должны создать возможность выполнять SQL-обновления в своей базе данных (используя refresh() в JPA или аналогичных методах, потому что JPA по умолчанию кэширует все, чтобы он не поймал прямую базу данных update - запуск прямых SQL-обновлений - это обычная производственная поддержка);
  • Объектно-реляционное несоответствие всегда вызывает проблемы. При любой такой проблеме существует компромисс между сложностью и полнотой абстракции. Время от времени я чувствовал, что JPA зашла слишком далеко и попала в реальный закон уменьшения прибыли, где сложность ударила не была оправдана абстракцией.

Есть еще одна проблема, которая требует немного большего объяснения.

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

Одна из критических замечаний в отношении более простых методов SQL заключается в том, что вы получаете все эти VO (объекты значений) или DTO (объекты передачи данных), которые используются одним запросом. Это рекламируется как преимущество ORM, потому что вы избавляетесь от этого.

Дело в том, что эти проблемы не исчезают с ORM, они просто переходят к уровню представления. Вместо создания VO/DTO для запросов вы создаете пользовательские объекты представления, как правило, для каждого представления. Как это лучше? ИМХО это не так.

Я написал об этом в ORM или SQL: мы еще там?.

Моя технология персистентности выбора (на Java) в наши дни - ibatis. Это довольно тонкая оболочка вокруг SQL, которая делает 90% + того, что может сделать JPA (она может даже выполнять ленивую загрузку отношений, хотя и не очень хорошо документирована), но с гораздо меньшими накладными расходами (с точки зрения сложности и фактического кода).

Это появилось в прошлом году в приложении GWT, которое я писал. Множество переводов с EclipseLink на объекты презентации в реализации сервиса. Если бы мы использовали ibatis, было бы намного проще создать соответствующие объекты с помощью ibatis, а затем передать их вверх и вниз по стеку. Некоторые пуристы могут утверждать, что это плохо и торговля. Возможно, так (теоретически), но я вам скажу: это привело бы к более простому коду, более простому стеку и большей производительности.

Ответ 3

Я говорю простой SQL для чтения, ORM для CUD.

Производительность - это то, о чем я всегда беспокоюсь, особенно в веб-приложениях, а также поддерживаемость кода и его читаемость. Чтобы решить эти проблемы, я написал SqlBuilder.

Ответ 4

ORM - это не просто переносимость (чего нелегко достичь даже с ORM, если на то пошло). То, что оно дает вам, в основном представляет собой слой абстракции в постоянном хранилище, когда инструмент ORM освобождает вас от написания SQL-запросов (выбирает PK или предикатов, вставок, обновлений и удалений) и позволяет сосредоточиться на проблемном домене.

Ответ 5

Для любого респектабельного проекта потребуется абстракция для базы данных, чтобы справиться с несоответствием импеданса. Но самый простой первый шаг (и достаточный для большинства случаев), я бы ожидал, будет DAL, а не супертяжелом ORM. Ваши единственные варианты - это не те, что на концах спектра.


EDIT в ответ на комментарий с просьбой описать, как я различаю DAL от ORM:

DAL - это то, что вы пишете сами, возможно, начиная с класса, который просто инкапсулирует таблицу и отображает ее поля в свойства. ORM - это код, который вы не пишете, или механизмы абстракции, выведенные из других свойств вашей схемы dbms, в основном PK и FK. (Здесь вы обнаружите, что автоматические абстракции начинают просачиваться или нет). Я предпочитаю информировать их намеренно, но это может быть только мое личное предпочтение).

Ответ 6

Ключом, который заставлял мое использование ORM действительно летать, было генерация кода. Я согласен с тем, что маршрут ORM не самый быстрый, с точки зрения производительности кода. Но когда у вас есть средняя и большая команда, БД быстро меняет способность регенерировать классы и сопоставления из БД, поскольку часть процесса сборки - это что-то блестящее, особенно если вы используете CI. Поэтому ваш код может быть не самым быстрым, но ваша кодировка будет - я знаю, что я возьму в большинстве проектов.

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

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

Ответ 7

Каждый инструмент имеет свою цель и видение. Я создал http://www.jooq.org/ точно в соответствии с вашими потребностями, хотя iBatis, вероятно, также является хорошим решением для вас.

jOOQ имеет основные функции ORM, но в основном он фокусируется на вещах, которые, как я полагаю, большинству разработчиков требуется больше всего, пытаясь найти лучший ORM для своих нужд:

  • генерация кода
  • привязка переменных (что боль в JDBC)
  • Абстракция синтаксиса SQL (для предотвращения синтаксических ошибок)

Но часто они заходят слишком далеко и обеспечивают такую ​​абстракцию, вы не думаете, что они работают против РСУБД. С другой стороны, вы выбрали РСУБД именно потому, что

  • это надежный источник данных
  • SQL может делать много хороших, совершенных вещей (вложенные selects, union, complex join и т.д.). Часто ORM не может этого делать.
  • вы можете самостоятельно обрабатывать транзакции и сеансы.
  • У вас есть UDT и хранимые процедуры.

jOOQ адресует именно эти точки. Он будет работать так же, как JDBC, но без боли.

Ответ 8

Дилемма, следует ли использовать фреймворк или нет, довольно распространена в современном сценарии разработки программного обеспечения.

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

Также важно понимать, что не обязательно выбирать рамки или подход и реализовывать в этом все. Под этим мы подразумеваем, что мы можем смешивать ORM и собственный язык запросов. Многие рамки ORM предоставляют точки расширения для плагина в собственном SQL. Мы должны стараться не использовать рамки или подход. Мы можем объединить определенные рамки или подходы и прийти с соответствующим решением.

Вы можете использовать ORM, когда дело доходит до вставки, обновления, удаления, управления версиями с высоким уровнем concurrency, и вы можете использовать Native SQL для генерации отчетов и длинного перечисления

Ответ 9

Нет решения "one-tool-fits-all", и это также верно для вопроса "должен ли я использовать or/m или нет?.

Я бы сказал: если вам нужно написать приложение/инструмент, который сфокусирован на "данные", без какой-либо другой логики, тогда я бы использовал простой SQL, поскольку SQL является языком, специфичным для домена для таких приложений.

С другой стороны, если бы я должен был написать бизнес/корпоративное приложение, содержащее много логики "домена", то я бы написал модель богатого класса, которая могла бы выразить этот домен в коде. В этом случае ORM-M-картограф может быть очень полезен, чтобы успешно это сделать, так как из ваших рук требуется много сантехнического кода.

Ответ 10

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

Взгляните на данные SQL (http://sqldata.codeplex.com). Это очень легкий ORM для С#, который охватывает все базы.

FYI, я являюсь автором SQL Data.

Ответ 11

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

Я действительно должен был просто изменить как заголовок , так и фактический вопрос. Я никогда раньше не использовал DAL на любом языке.

Ответ 12

Использовать ORM, который работает как SQL, но обеспечивает проверку времени и времени на компиляцию. Как и мой любимый: Объекты знаний данных (раскрытие: Я написал его)

Например:

for (Bug bug : Bug.ALL.limit(100)) {
  int id = bug.getId();
  String title = bug.getTitle();
  System.out.println(id +" "+ title);
}

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

Ответ 13

Я хотел бы добавить свой голос к хору ответов, в которых говорится: "Там середина!".

Для программиста приложений SQL - это смесь вещей, которые вы, возможно, захотите контролировать, и вещи, которые вы почти наверняка не хотите контролировать.

То, что я всегда хотел, это слой (назовите его DAL, ORM или micro-ORM, я не против), который возьмет на себя ответственность за полностью предсказуемые решения (как указать слова SQL, где скобки go, когда придумывать псевдонимы столбцов, какие столбцы создавать для класса, содержащего два поплавка и int...), оставляя меня ответственным за аспекты SQL более высокого уровня, то есть, как организовать JOINs, боковые вычисления, DISTINCT, GROUP BY, скалярные подзапросы и т.д.

Итак, я написал что-то, что делает это: http://quince-lib.com/

Это для С++: я не знаю, есть ли этот язык, который вы используете, но, тем не менее, может быть интересно посмотреть, как это выглядит так, как может выглядеть "средняя земля".