Используете ORM или простой SQL? [закрыто]

247

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

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

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

hydrapheetz
источник
Стандартизация, безопасность, ремонтопригодность, абстракция языка, DRY и т. Д.
Бен
Производительность с ORM может быть близкой к SQL, зависит от того, правильно ли вы ее используете и с правильными настройками ... Смотрите, как сделать EF6.x в 5 раз быстрее: linkedin.com/pulse/…
baHI
Для архитектуры ORM и с практическими
рекомендациями
Объектно-реляционное отображение (ORM) уже очень популярно во многих языках программирования и является одной из лучших альтернатив для SQL. Я был вдохновлен стилем цепочки методов для создания CQL для моего проекта TRIADB. healis.eu/triadb/#latest-release
Athanassios
3
Глупо, что этот вопрос был закрыт.
Митч Пшеничный

Ответы:

169

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

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

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

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

Кэмерон Поуп
источник
Не могли бы вы определить «большое количество строк базы данных на запрос»? Пожалуйста :)
Моссельман
Так можно ли интегрировать JPA с IBatis например ?? И заставить их работать в одной транзакции?
Хайме Хаблутцель
2
Еще одно соображение, которое никто не обсуждает, - это основы государственного управления. Весь этот стек каркасов (JSF, JPA и т. Д.) Основан на методах get / set Java-бинов. Это тонна шаблонной таблицы для каждой таблицы, для каждого столбца и ... вот настоящий антишаблон: просто выставить каждое поле, как если бы оно было публичным. По сути, наличие метода get / set для полей в объекте / таблице / строке очень близко к нарушению каждого владельца сокрытия и инкапсуляции информации. Наконец, вернемся к управлению государством ... где опция неизменности? Можно или нужно разрешить наполовину заданные объекты? Нет варианта с большинством.
Даррелл Тиг
2
Я хотел бы отточить и особенно согласиться с ключевым утверждением в этом ответе. «Для приложений, которые обрабатывают большое количество строк базы данных на запрос, налог на ORM намного тяжелее». ORM хорош только для разработчиков и техобслуживания, потому что большинство разработчиков не очень хорошо разбираются в SQL, но если вы на самом деле говорите о производительности, SQL полностью ее превосходит.
Маначи
"большинство разработчиков не очень хороши в SQL" ??? Я бы сказал, что большинство разработчиков не знают, как правильно использовать LINQ, мощь деревьев выражений и ORM в целом, генерацию кода и многое другое. Но нет, у меня нет никаких оснований, чтобы сделать такое сильное заявление.
Аданай Мартин
253

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

  1. ОРМ не быстр. Они могут быть адекватными, и в большинстве случаев адекватными - это нормально, но в среде с большими объемами и малой задержкой их нет - нет;
  2. В языках программирования общего назначения, таких как Java и C #, вам нужно очень много магии, чтобы заставить их работать (например, ткачество во время загрузки в Java, инструментарий и т. Д.);
  3. При использовании ORM вместо того, чтобы идти дальше от SQL (что, похоже, и задумано), вы будете удивлены, сколько времени вы тратите на настройку XML и / или аннотаций / атрибутов, чтобы ваш ORM генерировал производительный SQL;
  4. Для сложных запросов действительно нет замены. Как и в JPA, есть некоторые запросы, которые просто невозможны, которые находятся в сыром SQL, и когда вам нужно использовать сырой SQL в JPA, это не очень красиво (C # /. Net, по крайней мере, имеет динамические типы - var - что много лучше, чем массив объектов);
  5. При использовании ORM очень много "ловушек". Это включает непреднамеренное или непредвиденное поведение, тот факт, что вам необходимо встроить возможность обновления SQL в вашей базе данных (с использованием refresh () в JPA или аналогичными методами, поскольку JPA по умолчанию кэширует все, поэтому он не перехватывает прямую базу данных). update - выполнение прямых обновлений SQL является распространенным видом деятельности поддержки производства);
  6. Несоответствие между объектами и отношениями всегда вызывает проблемы. В любой такой проблеме есть компромисс между сложностью и полнотой абстракции. Временами я чувствовал, что JPA зашел слишком далеко и достиг реального закона убывающей доходности, когда сложность не оправдывалась абстракцией.

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

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

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

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

Я написал об этом в ORM или SQL: мы уже там? ,

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

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

Клетус
источник
2
Я был вдохновлен, чтобы опубликовать еще один (хотя вики-сообщество) вопрос только для сбора ресурсов на подобные вещи. Что касается последнего абзаца: мне нравится простота. Наверное, слишком много.
Hydrapheetz
3
iBATIS великолепен, но, возможно, вы захотите попробовать jOOQ: jooq.sourceforge.net . Его основная цель - оставаться ближе к SQL по 6 упомянутым вами причинам.
Лукас Эдер
5
+1 к пункту 3. Многие считают, что использование ORM освобождает вас от глубокого понимания SQL. Дело в том, что как только вы научитесь делать гимнастику с использованием SQL, вы, вероятно, отойдете от ORM ... очень быстро.
Райан Фернандес
4
Итак, сейчас конец 2013 года, и, как мы все знаем, ничто не может быть более обманчивым, чем «старые факты» - так что я могу спросить вас, не изменились ли ваши точки зрения? Если нет, было бы здорово, если бы вы могли написать пост в блоге / соответственно обновить свой ответ.
Доминик
3
var не создает динамический тип в .NET, переменные с ключевым словом dynamic являются динамическими типами в .NET. var все еще статическая типизация. См stackoverflow.com/questions/961581/...
Fazi
45

Я говорю простой SQL для R EADS, ORM для КЕД .

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

Макс Торо
источник
1
Что такое CUD? Я не могу найти определение.
Кимчи Ман
27
@KimchiMan CRUD без R.
Макс Торо
3
CUD - Создать, обновить, удалить.
Объединить
14

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

Антон Гоголев
источник
3
Я думал о чем-то более близком к переносимости между разновидностями базы данных. Я не должен оставлять вопросы поздно ночью.
Hydrapheetz
1
Это именно то, что я говорил: даже самые простые сценарии потенциально могут быть подвержены ошибкам в разных СУБД - например, при разной обработке NULL.
Антон Гоголев
ORM дает вам уровень абстракции над отношениями между объектами, но нет большого преимущества в отношении стандартных запросов, которые вы упоминаете. В приложении JDBC вы можете написать эти типы запросов с небольшим количеством кода в абстрактном суперклассе или служебном классе. Нет необходимости повторять шаблон для каждой новой таблицы.
Кевин Стембридж
11

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


РЕДАКТИРОВАТЬ в ответ на комментарий с просьбой описать, как я отличаю DAL от ORM:

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

dkretz
источник
2
Где вы проводите грань между DAL и ORM?
хаос
4
Итак, если вы являетесь автором ORM, ваш ORM автоматически превращается в DAL? :)
Бомба
DAL = уровень персистентности, а ORM - это инструмент, который вы используете внутри DAL для выполнения операций CRUD в хранилище данных.
Вахид Гадири
7

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

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

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

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

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

JOOQ обращается именно к этим пунктам. Он будет работать так же хорошо, как JDBC, но без боли.

Лукас Эдер
источник
6

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

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

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

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

Рутеш Махиджани
источник
3
Почему ORM лучше для высокого параллелизма?
user359996
6

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

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

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

MrTelly
источник
2
Абсолютно дело личного вкуса. Для меня генерация кода является недостатком.
dkretz
5
Прочитайте второй абзац .... возможно, полнота также полезна
MrTelly
Генерация кода - это единственный способ быстрее выполнить определенные задачи. Как и все инструменты, он может быть мощным или привести к катастрофе. Технически все языки производят другие типы кода.
Banjocat
4

Не существует единого решения для всех инструментов, и это также верно для вопроса «использовать или / или нет? ».

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

С другой стороны, если бы я должен был написать приложение для бизнеса / предприятия, которое содержит много логики «предметной области», то я написал бы богатую модель классов, которая могла бы выразить этот домен в коде. В таком случае, маппер OR / M может быть очень полезен для успешного выполнения, так как он берет много сантехнического кода из ваших рук.

Фредерик Гейселс
источник
«Нет единого решения, подходящего для всех»… ну, должно быть.
Рушино
1

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

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

hydrapheetz
источник
4
Ну, я считаю, что вы должны. Необработанный SQL повсюду довольно отвратителен.
хаос
Ну, да. Там есть кусок программного обеспечения форума я взломать на время от времени , который имеет тонны из mysql_query () и mysql_result () повсюду. Это орехи.
Hydrapheetz
Что это за «приложение», о котором ты говоришь?
Зоран Павлович
Забавно, что этот вопрос был задан в приложении irc для ботов и стал тем, чем он был (очень полезное руководство)! Приложение irc bot находится на одном конце шкалы, а приложение, которое имеет 50-100+ таблиц со сложными объединениями и миллионы строк данных, над которыми работают более 20 разработчиков, находится на другом конце шкалы. Смею сказать, что когда дело доходит до конца шкалы «irc bot app», это едва ли имеет значение.
Манахи
1

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

Например:

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

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

keredson
источник
Ваша IDE также может предоставлять такие статические проверки напрямую (IDEA знает структуру БД, пока вы сообщаете ей, где находится БД / где находятся файлы DDL, поэтому она может выполнять проверки типов / проверки отношений / и т. Д. В ваших SQL-запросах / процедурах / что угодно )
Xenos
это полезно может ли это сделать как часть шага сборки / CI? как это классифицировать sql против других строк? он может обрабатывать строковые манипуляции, или только строковые константы?
Кередсон
Я блокируюсь abBlock, но IntelliJ анализирует SQL, как и любой другой язык jetbrains.com/datagrip/features, чтобы можно было интегрировать его в CI / CD / build (возможно, попросив команду IJ изолировать код синтаксического анализа SQL? Может быть, Sonar уже есть такой парсер). Синтаксический анализ приносит тип данных, так что вы можете добавить проверки на них (я сделал это с помощью пользовательского плагина) или проверки типа «имеет ли столбец JOIN индекс FK?» и т. д. Это было бы изящным улучшением инспекций SQL нативного IJ
Xenos
1

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

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

К вашему сведению, я автор данных SQL.

tjscience
источник
1

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

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

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

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

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

slyqualin
источник