Використовуючи ORM або звичайний SQL? [зачинено]


245

Для деяких програм, які я розробив (потім забув), я писав звичайний SQL, в першу чергу для MySQL. Хоча я використовував ORM в python як SQLAlchemy , я довго не тримався з ними. Зазвичай це стримувало мене або документація, або складність (з моєї точки зору).

Я бачу це так: використовуйте ORM для портативності, звичайний SQL, якщо він буде просто використовувати один тип бази даних. Я дуже шукаю поради щодо використання ORM або SQL при розробці програми, яка потребує підтримки бази даних.

Думаючи про це, було б набагато краще просто використовувати легку обгортку для обробки невідповідностей бази даних порівняно з використанням ORM.


Стандартизація, безпека, ремонтопридатність, мовна абстракція, DRY тощо
Ben

Продуктивність з ORM може бути близькою до SQL, залежить від того, чи правильно ви її використовуєте та з правильними налаштуваннями ... Дивіться, як зробити EF6.x 5 разів швидше: linkedin.com/pulse/…
baHI

Що стосується архітектури ORM та способів використання (чого уникати), ось моє ще одне посилання: linkedin.com/pulse/…
baHI

Об'єктно-реляційне відображення (ORM) вже дуже популярне в багатьох мовах програмування та одна з найкращих альтернатив для SQL. Мене надихнуло стиль приєднання методів для створення CQL для мого проекту TRIADB. healis.eu/triadb/#latest-release
Афанасія

2
Дурне, що це питання було закрито.
Мітч Пшеничний

Відповіді:


169

ORM мають деякі приємні риси. Вони можуть обробляти велику частину собачих робіт з копіювання стовпців бази даних в поля об’єктів. Зазвичай вони обробляють перетворення типів дати та часу мови у відповідний тип бази даних. Вони, як правило, дуже елегантно обробляють відносини між багатьма, створюючи інстанції вкладених об'єктів. Я виявив, що якщо ви розробляєте свою базу даних з урахуванням сильних та слабких сторін ОРМ, це економить багато роботи з надходженням даних у базу даних та з них. (Ви хочете дізнатись, як він справляється з поліморфізмом і відносинами між багатьма, якщо вам потрібно їх скласти. Саме ці два домени забезпечують більшість «невідповідностей імпедансу», які змушують деякі називати ORM «В'єтнамом інформатики» .)

Для транзакційних додатків, тобто ви робите запит, отримуєте деякі об'єкти, обмінюєте їх, щоб отримати деякі дані та відображати їх на веб-сторінці, податок на ефективність невеликий, а в багатьох випадках ORM може бути швидшим, оскільки він буде кешувати об'єкти. раніше бачив, що інакше б кілька разів запитував базу даних.

Для додатків, які мають великі звіти або мають велику кількість рядків баз даних за запитом, податок на ORM набагато важчий, а кешування, яке вони роблять, перетворюється на велику, марну тягаря пам’яті. У цьому випадку просте просте відображення SQL (LinQ або iBatis) або ручне кодування SQL запитів у тонкому DAL.

Я знайшов для будь-якого масштабного застосування ви знайдете обидва підходи. (ORM для прямої CRUD та SQL / тонкий DAL для звітування).


Чи можете ви визначити "велика кількість рядків баз даних на запит"? Будь ласка :)
Моссельман

Тож чи можу я, наприклад, інтегрувати JPA з IBatis ?? І змусити їх працювати в одній операції?
Хайме Хаблуцель

2
Ще одна думка, про яку, схоже, ніхто не обговорює, - це основне управління державою. Весь цей пакет фреймворків (JSF, JPA тощо) заснований на методах отримання / встановлення бобів Java. Це ТОН котлована для кожної таблиці, для кожного стовпця і ... ось справжня антидіаграма: Просто викрийте кожне поле так, ніби воно публічне. Фактично, використання методу get / set на полях в об'єкті / таблиці / рядку дуже близьке до порушення кожного орендаря приховування та інкапсуляції інформації. Нарешті, повернення до управління державою ... де варіант незмінності? Можна чи слід допускати напівзадані об’єкти? Немає варіанту з більшістю.
Darrell Teague

2
Я хотів би приєднатися і особливо погодитися на ключове твердження у цій відповіді. "Для додатків, які мають велику кількість рядків баз даних на запит, податок з ОРМ набагато важчий". ORM хороша лише для розробників та обслуговування, тому що більшість розробників не дуже хороші в SQL, але якщо ви насправді говорите про продуктивність, SQL цілком перемагає її.
Маначі

"Більшість розробників не дуже хороші в SQL" ??? Я б сказав, що більшість розробників не знає, як правильно використовувати LINQ, силу дерев вираження та ORM в цілому, генерацію коду та багато іншого. Але ні, у мене немає підстав для того, щоб робити таку сильну заяву.
Аданай Мартін

253

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

  1. ORM не швидкі. Вони можуть бути адекватними і більшу частину часу адекватними, але в умовах великої гучності з низькою затримкою вони ні-ні;
  2. У загальноприйнятих мовах програмування, таких як Java та C #, вам потрібно надзвичайно багато магії, щоб змусити їх працювати (наприклад, плетіння часу на Java, інструментарій тощо);
  3. Використовуючи ORM, а не віддаляючись від SQL (що, здається, є наміром), ви будете вражені, скільки часу ви витрачаєте на налаштування XML та / або анотацій / атрибутів, щоб отримати ORM для створення ефективного SQL;
  4. Для складних запитів насправді заміни немає. Як і в JPA, є деякі запити, які просто неможливі, які є в необробленому SQL, і коли вам доведеться використовувати необроблений SQL в JPA, це не дуже добре (C # /. Net принаймні має динамічні типи - var - яких багато приємніше, ніж масив Object);
  5. Під час використання ORM існує дуже багато "готів". Сюди входить ненавмисна чи несподівана поведінка, той факт, що вам потрібно створити можливість робити оновлення SQL у вашій базі даних (використовуючи refresh () у JPA або подібні методи, оскільки JPA за замовчуванням кешує все, щоб не потрапити в пряму базу даних оновлення - запуск прямих оновлень SQL - це звичайна діяльність з підтримки виробництва);
  6. Об'єктно-реляційна невідповідність завжди викличе проблеми. З будь-якою такою проблемою відбувається компроміс між складністю та повнотою абстракції. Часом я відчував, що СВЗ зайшов занадто далеко, і потрапив у справжній закон зменшення віддачі, коли втручання складності не було виправдане абстракцією.

Є ще одна проблема, яка потребує трохи більше пояснень.

Традиційна модель для веб-додатків полягає в тому, щоб мати стійкий рівень та рівень презентації (можливо, між ними є сервіс чи інші шари, але це два важливі для цього обговорення). 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, змінні з динамічним ключовим словом є динамічними типами в .NET. var досі статичний набір. Дивіться stackoverflow.com/questions/961581/…
Fazi

45

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

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


1
Що таке CUD? Я не можу знайти визначення.
Кімчі Людина

27
@KimchiMan CRUD without the R.
Макс Торо

3
CUD - Створення, оновлення, видалення.
Поєднайте

14

ORM - це не просто портативність (чого важко досягти навіть з ORM). Що це дає вам - це в основному шар абстрагування над стійким магазином, коли інструмент ORM звільняє вас від запису SQL запитів на колонці (вибирається ПК або предикатами, вставляє, оновлює та видаляє) і дозволяє зосередитись на проблемній області.


3
Я думав про щось наближене до портативності в різних смаках. Я не повинен публікувати запитання пізно вночі.
hydrapheetz

1
Саме так я і говорив: навіть найосновніші сценарії потенційно можуть піддаватися помилкам в різних СУБД - наприклад, різній обробці NULL.
Антон Гоголєв

ORM надає вам шар абстракції щодо відносин між об'єктами, але немає великої переваги щодо згадуваних вами запитів котлованних панелей. У додатку JDBC ви можете записувати ті типи запитів з невеликою кількістю коду в абстрактному суперкласі або класі корисності. Не потрібно повторювати котельну плиту для кожної нової таблиці.
Кевін Стембрідж

11

Будь-який респектабельний дизайн потребує деякої абстракції для бази даних, просто для усунення невідповідності імпедансу. Але найпростішим першим кроком (і адекватним для більшості випадків), я б очікував, буде DAL, а не важкий ORM. Ваші єдині варіанти - це не ті, що знаходяться на кінці спектру.


EDIT у відповідь на коментар із проханням описати, як я відрізняю DAL від ORM:

DAL - це те, що ви пишете самі, можливо, починаючи з класу, який просто інкапсулює таблицю і відображає її поля у властивості. ORM - це код, який ви не записуєте або механізми абстрагування виводяться з інших властивостей вашої dbms-схеми, в основному ПК та FK. (Тут ви дізнаєтесь, чи починають автоматичні абстракції витікати чи ні. Я вважаю за краще навмисно повідомити їх, але це може бути моїм особистим уподобанням).


2
Де ви проводите межу між тим, що таке DAL та що ORM?
хаос

4
Отже, якщо ви автор ORM, ваш ORM автоматично перетворюється на DAL? :)
Бомбе

DAL = рівень стійкості та ORM - це інструмент, який ви використовуєте всередині свого DAL для виконання операцій CRUD у сховищі даних.
Вахід Гадірі

7

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

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

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

Але часто вони заходять занадто далеко і надають стільки абстракцій, ви б не думали, що вони бігають проти RDBMS. З іншого боку, ви вибрали RDBMS саме тому

  • це надійне джерело даних
  • SQL може зробити багато хороших, ефективних речей (вкладені вибори, об'єднання, складні приєднання тощо). Часто ORM не може зробити це.
  • ви можете самостійно обробляти транзакції та сеанси
  • у вас є UDT і зберігаються процедури

jOOQ вирішує саме ці точки. Він виступить так само добре, як і JDBC, але без болю.


6

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

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

Також важливо розуміти, що не обов'язково вибирати рамку чи підхід і впроваджувати все в цьому. Що ми маємо на увазі під цим, ми можемо поєднати ORM та рідну мову запитів. Багато фреймворків ORM дають точки розширення для плагіна у рідному SQL. Нам слід намагатися не надто використовувати рамки чи підхід. Ми можемо поєднати певні рамки чи підходи та підійти до відповідного рішення.

Ви можете використовувати ORM, коли мова йде про вставку, оновлення, видалення, версії з високим рівнем одночасності, а також ви можете використовувати Native SQL для створення звітів та довгого списку


3
Чому ОРМ краща для високої одночасності?
користувач359996

6

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

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

Ще одна думка: кешування, вбудований у режим Hibernate, часто може зробити значне поліпшення продуктивності при правильному використанні. Більше не повертаючись до БД, щоб прочитати довідкові дані.


2
Зовсім справа особистого смаку. Для мене генерація коду є вадою.
dkretz

5
Прочитайте другий абзац .... можливо повнота також корисна
MrTelly

Генерація коду - єдиний спосіб швидше виконати певні завдання. Як і всі інструменти, він може бути потужним або призвести до катастрофи. Технічно всі мови виробляють код інших типів.
Банджокат

4

Немає рішення "єдиний інструмент - все", і це також стосується питання "чи слід використовувати або / m чи ні? '.

Я б сказав: якщо вам доведеться писати додаток / інструмент, орієнтований на дуже «дані», без особливої ​​логіки, я б використовував звичайний SQL, оскільки SQL є мовою, характерною для домену для цього типу додатків.

З іншого боку, якби я писав додаток для бізнесу / підприємства, що містить багато логіки «домена», я б написав модель насиченого класу, яка могла б виразити цей домен у коді. У такому випадку, оператор OR / M може бути дуже корисним для успішного виконання цього завдання, оскільки це потребує великої кількості сантехнічного коду з ваших рук.


"Немає рішення" єдиний засіб "для всіх".
Рушино

1

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

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


4
Ну, я вважаю, що слід. Сирий SQL в усьому світі досить гидкий.
хаос

Ну так. Існує фрагмент програмного забезпечення для форуму, який я час від часу лаю, який містить у собі тони mysql_query () та mysql_result (). Це горіхи.
hydrapheetz

Про що це "додаток", про який ви говорите?
Зоран Павлович

Це смішно, що це питання було задано через додаток irc bot і стало тим, що воно було (дуже корисний посібник)! Додаток бота irc знаходиться на одному кінці шкали, а додаток, який містить 50-100 + таблиць зі складними з'єднаннями та мільйонами рядків даних із 20+ розробниками, що працюють над ним, знаходиться на іншому кінці шкали. Смію сказати, що мова йде про кінець шкали програми «irc bot», це навряд чи має значення.
Маначі

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).


Ваш IDE також може надавати такі статичні перевірки безпосередньо (IDEA знає структуру БД так довго, коли ви повідомляєте, де знаходиться БД / де знаходяться файли DDL, тому він може робити перевірки / перевірки відношення / тощо у ваших SQL запитах / процедурах / будь-що )
Xenos

це корисно. чи може це зробити як частина кроку збірки / CI? як вона класифікує sql проти інших рядків? чи може він обробляти стринг-маніпуляції чи лише струнні константи?
Кередсон

Мене заблокує abBlock, але IntelliJ аналізує SQL, як і будь-яку іншу мову jetbrains.com/datagrip/features, щоб можна було інтегрувати його в CI / CD / build (можливо, попросивши команду IJ виділити код розбору SQL? Можливо, Sonar вже має такий парсер). Парсинг приносить тип даних, щоб ви могли додавати чеки на них (я це робив із користувацьким плагіном) або перевіряти на кшталт "чи колонки JOIN мають індекс FK?" і т.д. Вони будуть акуратно improvments до перевірок SQL Native Ij в
Xenos

1

Я знаю, що це питання дуже давнє, але я думав, що надішлю відповідь у випадку, якщо хтось натрапить на нього, як я. ОРМ пройшли довгий шлях. Деякі з них насправді дають вам найкраще з обох світів: роблять розвиток більш продуктивним та підтримують продуктивність.

Погляньте на дані SQL ( http://sqldata.codeplex.com ). Це дуже легка ORM для c #, яка охоплює всі основи.

FYI, я автор SQL Data.


1

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

Для програміста додатків SQL - це суміш речей, якими ви хочете керувати, і речей, які ви майже напевно не хочете, щоб їх було заважало контролювати.

Я завжди хотів - це шар (назвіть це DAL, ORM або micro-ORM, я не заперечую), який візьме на себе відповідальність за цілком передбачувані рішення (як написання ключових слів SQL, куди заходять дужки, коли винайти псевдоніми стовпців, які стовпці створити для класу, який містить два плавці та int ...), залишаючи мене відповідальним за аспекти вищого рівня SQL, тобто як організувати JOIN, обчислення на сервері, ВИДАЛЕННЯ, GROUP BY, скалярні підзапити тощо.

Тому я написав щось, що робить це: http://quince-lib.com/

Це для C ++: я не знаю, чи це мова, якою ви користуєтесь, але все-таки це може бути цікаво побачити, як це може виглядати "середина".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.