Używając ORM czy zwykłego SQL? [zamknięte]

Dla niektórych aplikacji, które stworzyłem (potem o nich zapomniałem), pisałem zwykły SQL, głównie dla MySQL. Chociaż używałem ORM w Pythonie jak sqlalchemy , nie trzymałem się ich długo. Zazwyczaj była to albo dokumentacja, albo złożoność (z mojego punktu widzenia) powstrzymująca mnie.

Widzę to tak: użyj ORM dla przenośności, zwykły SQL, jeśli tylko będzie używać jednego typu bazy danych. Szukam porady kiedy używać ORM lub SQL podczas tworzenia aplikacji wymagającej obsługi baz danych.

Myśląc o tym, byłoby o wiele lepiej użyć lekkiego wrappera do obsługi niespójności w bazie danych zamiast używania ORM.

Author: cletus, 2009-01-30

13 answers

Ormy mają kilka fajnych funkcji. Mogą obsługiwać wiele zadań kopiowania kolumn bazy danych do pól obiektów. Zwykle obsługują konwersję typów daty i czasu języka na odpowiedni typ bazy danych. Zazwyczaj obsługują one bardzo elegancko relacje od jednego do wielu, tworząc instancje zagnieżdżonych obiektów. Odkryłem, że jeśli zaprojektujesz swoją bazę danych z myślą o mocnych i słabych stronach ORM, oszczędza to wiele pracy w uzyskiwaniu danych do i z bazy danych. (Będziesz chciał aby wiedzieć, jak radzi sobie z polimorfizmem i wieloma relacjami, jeśli trzeba je odwzorować. To właśnie te dwie domeny zapewniają większość "niedopasowania impedancji", co sprawia, że niektórzy nazywają ORM "Wietnamem informatyki".)

Dla aplikacji, które są transakcyjne, tj. składasz żądanie, pobierasz niektóre obiekty, przemierzasz je, aby uzyskać niektóre dane i renderujesz je na stronie internetowej, podatek od wydajności jest niewielki, a w wielu przypadkach ORM może być szybszy, ponieważ będzie buforować obiekty, które wcześniej widziałem, że w przeciwnym razie zapytałbym bazę danych wiele razy.

Dla aplikacji, które są ciężkie do raportowania lub mają do czynienia z dużą liczbą wierszy bazy danych na żądanie, podatek ORM jest znacznie cięższy, a buforowanie, które robią, zamienia się w duże, bezużyteczne obciążenie pamięcią. W takim przypadku proste mapowanie SQL (LinQ lub iBatis) lub ręcznie kodowane zapytania SQL w cienkim DAL jest drogą do zrobienia.

Znalazłem dla każdej aplikacji na dużą skalę znajdziesz się za pomocą obu podejść. (ORM dla proste CRUD i SQL / thin DAL do raportowania).

 143
Author: Cameron Pope,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 19:24:47

Mówiąc jako ktoś, kto spędził sporo czasu pracując z JPA (Java Persistence API, zasadniczo znormalizowane API ORM dla Java/J2EE / EJB), które obejmuje Hibernate, EclipseLink, Toplink, OpenJPA i inne, podzielę się niektórymi z moich obserwacji.

    Ormy nie są szybkie. Mogą być odpowiednie I przez większość czasu odpowiednie jest OK, ale w środowisku o dużej objętości i niskim opóźnieniu są Nie-Nie; {]}
  1. w językach programowania ogólnego przeznaczenia, takich jak Java i C#, potrzebujesz okropnego wiele magii, aby mogły działać (np. tkanie w czasie ładowania w Javie, oprzyrządowanie itp.); {]}
  2. podczas korzystania z ORM, zamiast iść dalej od SQL (co wydaje się być intencją), będziesz zaskoczony, jak dużo czasu spędzasz na ulepszaniu XML i/lub adnotacji/atrybutów, aby twój ORM generował wydajny SQL;
  3. dla złożonych zapytań, naprawdę nie ma substytutu. Podobnie jak w JPA są pewne zapytania, które po prostu nie są możliwe, że są w surowym SQL i kiedy trzeba użyć surowego SQL w JPA nie jest ładna (C#/. Net ma przynajmniej typy dynamiczne--var--które są o wiele ładniejsze niż tablica obiektów);
  4. [[3]}jest strasznie dużo "gotchas" podczas korzystania z ORM. Obejmuje to niezamierzone lub nieoczekiwane zachowanie, fakt, że musisz zbudować możliwość robienia aktualizacji SQL do bazy danych (za pomocą refresh () w JPA lub podobnych metod, ponieważ JPA domyślnie buforuje wszystko, więc nie złapie bezpośredniej aktualizacji bazy danych-Uruchamianie direct SQL updates jest powszechną obsługą produkcji aktywność);
  5. niedopasowanie obiektowo-relacyjne zawsze będzie powodować problemy. Z każdym takim problemem istnieje kompromis między złożonością a kompletnością abstrakcji. Czasami czułem, że JPA posunął się za daleko i uderzył w prawdziwe prawo malejących zwrotów, gdzie hit złożoności nie był uzasadniony abstrakcją.

Jest jeszcze jeden problem, który wymaga nieco więcej wyjaśnienia.

Tradycyjny model aplikacji internetowej ma mieć warstwę trwałości i warstwa prezentacji (prawdopodobnie z usługami lub innymi warstwami pomiędzy, ale są to dwie ważne dla tej dyskusji). ORMs wymusza sztywny widok od warstwy trwałości do warstwy prezentacji(tj.

Jedną z krytycznych cech bardziej surowych metod SQL jest to, że otrzymujesz wszystkie te obiekty vos (value objects) lub DTOs (data transfer objects), które są używane przez jedno zapytanie. Jest to reklamowane jako zaleta ORMs, ponieważ pozbędziesz się tego.

Rzecz jest te problemy nie znikają z ORMs, po prostu przechodzą do warstwy prezentacji. Zamiast tworzyć VOs/DTOs dla zapytań, tworzysz własne obiekty prezentacji, zazwyczaj po jednym dla każdego widoku. Jak to jest lepsze? IMHO nie jest.

Pisałem o tym w ORM lub SQL: czy już jesteśmy?.

Moją ulubioną technologią (w Javie) w dzisiejszych czasach jest ibatis. Jest to dość cienka owijka wokół SQL, która robi 90% + tego, co może zrobić JPA (może nawet zrobić leniwe Ładowanie zależności, choć nie jest dobrze udokumentowane), ale o znacznie mniejszym napowietrzeniu (pod względem złożoności i rzeczywistego kodu).

To pojawiło się w zeszłym roku w aplikacji GWT, którą pisałem. Wiele tłumaczeń z EclipseLink do obiektów prezentacyjnych w implementacji usługi. Gdybyśmy używali ibatisa, o wiele prostsze byłoby tworzenie odpowiednich obiektów za pomocą ibatisa, a następnie przekazywanie ich w górę i w dół stosu. Niektórzy puryści mogą twierdzić, że jest to złe. Może tak (teoretycznie) ale powiem ci coś: doprowadziłoby to do prostszego kodu, prostszego stosu i większej produktywności.

 227
Author: cletus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-25 15:56:55

Mówię zwykły SQL dla R eads, ORM dla CUD .

Wydajność jest czymś, o co zawsze się martwię, szczególnie w aplikacjach internetowych, ale także o łatwość obsługi i czytelność kodu. Aby rozwiązać te problemy napisałem sqlbuilder.

 35
Author: Max Toro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 16:13:21

ORM to nie tylko przenośność(co jest dość trudne do osiągnięcia nawet w przypadku ORMs). To, co daje Ci, to w zasadzie warstwa abstrakcji nad trwałym sklepem, gdy narzędzie ORM uwalnia cię od pisania zapytań SQL typu boilerplate (wybiera przez PK lub predykaty, wstawia, aktualizuje i usuwa) i pozwala skoncentrować się na domenie problemu.

 11
Author: Anton Gogolev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-30 07:48:06

Każdy szanowany projekt będzie potrzebował trochę abstrakcji dla bazy danych, aby poradzić sobie z niedopasowaniem impedancji. Ale najprostszym pierwszym krokiem (i adekwatnym w większości przypadków) spodziewałbym się DAL, a nie ORM wagi ciężkiej. Twoje jedyne opcje nie są te na końcu spektrum.


EDIT w odpowiedzi na komentarz z prośbą o opisanie jak odróżniam DAL od ORM:

DAL jest tym, co sam piszesz, może zaczynając od klasy, która po prostu zawiera tabelę i mapuje swoje pola do właściwości. ORM to kod, którego nie piszesz lub mechanizmy abstrakcyjne wnioskowane z innych właściwości twojego schematu dbms, głównie PKs i FKs. (Tutaj dowiesz się, czy automatyczne abstrakcje zaczynają się przeciekać, czy nie. Wolę informować ich celowo, ale to może być tylko moje osobiste preferencje).

 9
Author: dkretz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-31 05:18:04

Każde narzędzie ma swój cel i wizję. Stworzyłem http://www.jooq.org / dokładnie dopasowane do Twoich potrzeb, choć iBatis jest prawdopodobnie dobrym rozwiązaniem również dla Ciebie.

JOOQ ma podstawowe funkcje ORM, ale skupia się głównie na tym, czego większość programistów potrzebuje najbardziej, próbując znaleźć najlepszy ORM dla swoich potrzeb: {]}

  • generowanie kodu
  • Wiązanie zmienne (to ból w JDBC)
  • abstrakcja składni SQL (aby zapobiec składni błędy)

Ale często idą za daleko i dostarczają tyle abstrakcji, że nie można by pomyśleć, że działają przeciwko RDBMS. Z drugiej strony, wybrałeś RDBMS właśnie dlatego, że

  • jest to solidne źródło danych
  • SQL potrafi zrobić wiele dobrych, wydajnych rzeczy (zagnieżdżone selekcje, związki, złożone połączenia, itp.). Często ORM nie może zrobić tych rzeczy.
  • możesz obsługiwać transakcje i sesje samodzielnie
  • masz procedury UDT i przechowywane

JOOQ odnosi się dokładnie do tych punktów. Będzie działać tak samo jak JDBC, ale bez bólu.

 6
Author: Lukas Eder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-25 14:01:54

Kluczem, który sprawił, że mój ORM naprawdę latał, było generowanie kodu. Zgadzam się, że trasa ORM nie jest najszybsza, jeśli chodzi o wydajność kodu. Ale gdy masz średni lub duży zespół, DB zmienia się szybko zdolność do regeneracji klas i mapowania z DB jako część procesu budowania jest czymś genialnym, szczególnie gdy używasz CI. Więc Twój kod może nie być najszybszy, ale twoje kodowanie będzie-wiem, co wziąłbym w większości projektów.

Moja rekomendacja to rozwijaj za pomocą ORM gdy schemat jest nadal płynny, użyj profilowania, aby znaleźć wąskie gardła, a następnie dostroić te obszary, które go potrzebują, używając surowego Sql.

Inna myśl, buforowanie wbudowane w Hibernate może często znacznie poprawić wydajność, jeśli zostanie użyte we właściwy sposób. Koniec z powrotem do DB, aby odczytać dane referencyjne.

 5
Author: MrTelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-30 10:29:16

Dylemat, czy używać frameworka, czy nie, jest dość powszechny we współczesnych scenariuszach tworzenia oprogramowania.

Ważne jest, aby zrozumieć, że każdy framework lub podejście ma swoje plusy i minusy - na przykład z naszego doświadczenia odkryliśmy, że ORM jest przydatny w przypadku transakcji, tj. operacji wstawiania/aktualizowania/usuwania - ale jeśli chodzi o pobieranie danych ze złożonymi wynikami, ważna staje się Ocena wydajności i skuteczności narzędzia ORM.

Także ważne jest, aby zrozumieć, że nie jest obowiązkowe wybranie RAM lub podejścia i wdrożenie wszystkiego w tym zakresie. Co rozumiemy przez to, że możemy mieć mieszankę ORM i natywny język zapytań. Wiele frameworków ORM daje punkty rozszerzeń wtyczce w natywnym SQL. Powinniśmy starać się nie nadużywać RAM lub podejścia. Możemy połączyć pewne ramy lub podejścia i przyjść z odpowiednim rozwiązaniem.

Możesz użyć ORM, jeśli chodzi o wstawianie, aktualizowanie, usuwanie, wersjonowanie z wysokim poziomem współbieżności i można używać natywnego SQL do generowania raportów i długiej listy

 4
Author: Rutesh Makhijani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-30 08:21:44

Nie ma rozwiązania "one-tool-fits-all" I dotyczy to również pytania " Czy powinienem używać or / m czy nie ? '.

Powiedziałbym: jeśli musisz napisać aplikację / narzędzie, które jest bardzo "dane" koncentruje, bez wielu innych logiki, a następnie używać zwykłego SQL, ponieważ SQL jest specyficzny język domeny dla tego rodzaju aplikacji.

Z drugiej strony, gdybym miał napisać aplikację biznesową / korporacyjną, która zawiera dużo logiki "domeny", to napisałbym bogaty model klasy które mogłyby wyrazić tę domenę w kodzie. W takim przypadku maper OR / M może być bardzo pomocny, aby to z powodzeniem zrobić, ponieważ zabiera dużo kodu hydraulicznego z twoich rąk.

 3
Author: Frederik Gheysels,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 07:53:05

Wiem, że to pytanie jest bardzo stare, ale pomyślałem, że opublikuję odpowiedź na wypadek, gdyby ktoś natknął się na to jak ja. Ormy przebyły długą drogę. Niektóre z nich dają ci to, co najlepsze z obu światów: sprawiają, że rozwój jest bardziej produktywny i utrzymuje wydajność.

Spójrz na dane SQL ( http://sqldata.codeplex.com ). jest to bardzo lekki ORM dla c#, który obejmuje wszystkie podstawy.

FYI, jestem autorem danych SQL.

 1
Author: tjscience,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-12 20:38:07

Jedną z aplikacji, którą stworzyłem, był Bot IRC napisany w Pythonie. Moduły, których używa, działają w oddzielnych wątkach, ale nie wymyśliłem sposobu obsługi wątków podczas korzystania z sqlite. Ale to może być lepsze dla osobnego pytania.

Naprawdę powinienem był przerobić zarówno tytuł , jak i pytanie. Nigdy wcześniej nie używałem DAL w żadnym języku.

 0
Author: hydrapheetz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-30 07:48:45

Użyj ORM, który działa Jak SQL, ale zapewnia kontrolę czasu kompilacji i bezpieczeństwo typu. Jak mój ulubiony: Obiekty wiedzy danych (ujawnienie: napisałem to)

Na przykład:

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

W pełni streaming. Łatwa konfiguracja (brak mapowania do zdefiniowania-odczytuje istniejące schematy). Obsługuje połączenia, transakcje, zapytania wewnętrzne, agregację itp. Prawie wszystko, co można zrobić w SQL. I zostało udowodnione od gigantycznych zbiorów danych (finansowych szeregów czasowych) aż do trivial (Android).

 0
Author: keredson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-13 20:13:42

Chciałbym dodać swój głos do refrenu odpowiedzi, które mówią :"jest środek!".

Dla programisty aplikacji, SQL jest mieszanką rzeczy, które możesz chcieć kontrolować i rzeczy, które prawie na pewno nie chcesz się przejmować kontrolowaniem.

To, czego zawsze chciałem, to warstwa (nazwij ją DAL, ORM lub micro-ORM, nie mam nic przeciwko której), która zajmie się całkowicie przewidywalnymi decyzjami (jak pisać słowa kluczowe SQL, gdzie znajdują się nawiasy, kiedy wymyślić kolumnę aliases, jakie kolumny utworzyć dla klasy, która posiada dwa pływaki i int ...), pozostawiając mnie odpowiedzialnym za aspekty wyższego poziomu SQL, tj. jak układać Joiny, obliczenia po stronie serwera, rozróżnienia, grupy BYs, skalarne podzakresy itp.

Więc napisałem coś, co robi to: http://quince-lib.com/

To jest dla C++: Nie wiem, czy to jest język, którego używasz, ale mimo to może być interesujące zobaczyć to ujęcie na jakim " średnim gruncie" na to wygląda.

 0
Author: slyqualin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-14 05:37:55