Abstrakcja bazy danych - czy jest przesadzana?

18

Po zetknięciu się z licznymi warstwami abstrakcji bazy danych zaczynam się zastanawiać, o co chodzi w tym, że każda biblioteka wymyśla swój własny paradygmat dostępu do danych. Odbieranie nowego DAL przypomina uczenie się nowego języka od nowa, kiedy zwykle wszystko, co chcę zrobić, to po prostu przekonać warstwę do wygenerowania zapytania SQL, które już napisałem w mojej głowie.

I to nawet bez wpływu na czytelność po fakcie:

# Exhibit A:  A typical DAL
rows = db(db.ips_x_users.ip_addr == '127.0.0.1')
    .inner_join(db.ips_x_users.user_id == db.users.id)
    .select(order=(db.ips_x_users.last_seen, 'desc'), limit=10)

# Exhibit B:  Another typical DAL
rows = db.ips_x_users
    .join(db.users, on=db.ips_x_users.user_id == db.users.id)
    .filter(db.ips_x_users.ip_addr == '127.0.0.1')
    .select(sort=~db.ips_x_users, limit=10)

# Exhibit C:  A hypothetical DAL based on standard SQL syntax
rows = db('''SELECT * FROM ips_x_users
             INNER JOIN users ON
                 (ips_x_users.user_id = users.id)
             WHERE ips_x_users.ip_addr = ip
             ORDER BY last_seen DESC LIMIT 10''', ip='127.0.0.1')

Co jest złego w standardowej składni SQL? Został stworzony do określonego celu i doskonale pasuje do tego celu. Może to tylko ja, ale rozumiem fragment C znacznie łatwiej niż pierwsze dwa. Zmienione nazwy słów kluczowych i sztuczki składniowe są urocze, ale IMO, jeśli chodzi o to, nie ułatwiają koderowi pobierania wierszy.

To prawdopodobnie wydawało się długim rantem, ale tutaj jest prawdziwe pytanie. Ponieważ każdy DAL wydaje się wymyślać nową DSL dla zapytań, a nie tylko analizować wypróbowany i prawdziwy SQL, muszą istnieć korzyści z użycia innej składni lub braki w standardowej składni SQL, o których nie wiem, że istnieją. Czy ktoś mógłby wskazać, co tutaj przeoczam?

Uwaga do siebie - myślę o nazwie
źródło
2
Największym problemem ze standardowym SQL jest to, że istnieje wiele zapytań specyficznych dla bazy danych. Zewnętrzna składnia złączeń jest bardzo zróżnicowana, podobnie jak proces uzyskiwania zapytania „okienkowego”. Na początek potrzeba DAL. Teraz, gdyby istniał standardowy wariant SQL używany przez DAL, który wie, jak radzić sobie z idiotsynchronizacją różnych dostawców SQL, byłbym zadowolony.
Berin Loritsch,

Odpowiedzi:

10

Najbardziej podstawowym problemem typowego użycia SQL jest to, że zapytania SQL są łańcuchami, które są w jakiś sposób złożone z innego języka. Stąd pochodzą zastrzyki SQL oraz inne podatności i WTF (twój przykład jest dość źle wybrany, ponieważ twoje zapytanie nie ma żadnych parametrów).

Następnym problemem jest w rzeczywistości następstwo: jeśli w kodzie jest zapisany kod SQL, kompilator nic na to nie poradzi. Błędy, takie jak literówki w nazwach kolumn, pojawią się tylko w czasie wykonywania. Zasadniczo jest to spowodowane tym, że nie chcesz reprezentować ciągu zapytania w kodzie źródłowym, ale coś, co kompilator może przeanalizować statycznie, aby zapobiec 95% wszystkich błędów facepalm.

Ostatni problem występuje, gdy próbujesz odwzorować relacyjną bazę danych na semantykę języka i model programowania: RDBMS nie idą dobrze razem z OOP (lub nawigacyjnym odzyskiwaniem danych). W rzeczywistości jest to dość okropny pomysł, łącząc te dwa, ale o to chodzi w tym wszystkim zorientowanym obiektowo DAL dla baz danych SQL (tj. ORM). Ale wszystkie te warstwy abstrakcji są skazane na wyciek. Myślę, że właśnie dlatego jest ich tak wiele: ponieważ pracujesz z nimi, widzisz, że są wadliwe, postanowiłeś napisać DAL, który robi to dobrze i ostatecznie kończy się niepowodzeniem.

Tak więc, chociaż problemy pierwszy i drugi sugerują posiadanie DAL, które pozbywają się SQL, problem trzeci implikuje, że nie ma prostego rozwiązania posiadania jednego (przynajmniej dla OOP), a zatem zawsze będzie morze DAL o różnych mocach i ograniczeniach. Ostatecznie wszystko, co możesz zrobić, to starannie wybrać kilka i trzymać się ich.

back2dos
źródło
3
„RDBMS nie współpracuje dobrze z OOP” - Czy wszystko w oprogramowaniu musi być OO?
quant_dev
@quant_dev: Nie. Ale warstwy „abstrakcji” są z natury przynajmniej „zorientowane na abstrakcję”. Również dostarczone fragmenty kodu sugerują, że mówimy o kodzie OO.
back2dos
Zawsze myślałem, że osadzenie SQL w C lub cokolwiek innego było najgłupszą rzeczą, jaką można sobie wyobrazić. Kiedy musiałem zrobić coś takiego, stworzyłem sposób definiowania relacji między tabelami i przechowywania ich w bazie danych, a następnie używania tych relacji do tworzenia SQL w czasie wykonywania do rozmowy z bazą danych. Mój kod C brzmiał tylko: „Znajdź ten byt przy użyciu tego klucza”, „Zapisz w nim zmiany”.
9

Pomija się oczywisty fakt, że nie wszystkie platformy baz danych akceptują tę samą składnię SQL, więc osadzanie instrukcji SQL w całej aplikacji po prostu nie będzie działać na każdej platformie bazy danych. Jeśli kiedykolwiek będziesz musiał obsługiwać wiele platform baz danych, będziesz musiał przemyśleć większość (jeśli nie wszystkie) tych instrukcji SQL.

Bernard
źródło
3
@ Uwaga - Ale wtedy DAL musiałby mieć pełny parser SQL i musiałby mieć własny obsługiwany dialekt, który byłby inny niż jakakolwiek konkretna baza danych. A wtedy miałby całą złożoność, jaką obecnie ma, generowanie odpowiedniej instrukcji SQL specyficznej dla bazy danych. Na przykład słowo kluczowe LIMIT jest prawidłowe w MySQL, ale nie w Oracle ani SQL Server.
Justin Cave,
2
Teraz dochodzimy do sedna pytania. Co sprawia, że ​​niestandardowy zestaw nazw metod i przeciążenia operatora przewyższa niestandardowy dialekt języka SQL? Korzystanie z SQL dałoby przynajmniej koderowi podstawy do rozpoczęcia nauki frameworka.
Uwaga dla siebie - wymyśl imię
3
@Note to self: prawdopodobnie dlatego, że łatwiej jest napisać płynny interfejs API niż napisać parser SQL w pewnym dialekcie SQL, a następnie przetłumaczyć go na inny dialekt SQL.
Dean Harding,
1
Dla przypomnienia wolę także używać „natywnego” SQL. Większość moich projektów nigdy nie musiała obsługiwać więcej niż jednej bazy danych, więc nigdy nie było to dla mnie problemem.
Dean Harding
3
„Pomija się oczywisty fakt, że nie wszystkie platformy baz danych akceptują tę samą składnię SQL” - tak, ale jak często piszesz kod, który ma być uruchamiany na dowolnej bazie danych? Zwykle platforma DB jest znaczącą inwestycją i nie jest często zmieniana. Ponadto można zoptymalizować zapytania w stosunku do znanego typu bazy danych, aby uzyskać znaczną poprawę wydajności.
quant_dev
5

Wydaje mi się, że SQL ulega tej samej zasadniczej zmianie, co wskaźniki 10 lat temu. Trwa próba wyeliminowania pracy ręcznej za pomocą SQL i przeniesienia jej na wyższy poziom abstrakcji. To samo stało się ze wskaźnikami i ręcznym zarządzaniem pamięcią wiele lat temu.

Ponieważ prace są obecnie w toku, możesz cieszyć się widokiem wielu różnych podejść sugerowanych, wypróbowanych, porzuconych i zintegrowanych. Jestem pewien, że zobaczymy ich więcej przed jakimś wspólnym podejściem lub standardem branżowym, jeśli chcesz się manifestować.

Z pewnością daje ci to przewagę, gdy możesz manipulować kodem dostępu do danych na tym samym poziomie iz tym samym paradygmatem, jaki stosujesz podczas pracy z kodem aplikacji.

W kilku słowach - uproszczenie, zwinność, szybkość - oto cele.


źródło
4

Joel napisał fajny artykuł 10 lat temu: Nie pozwól, aby astronauci z architektury cię przestraszyli

Myślę, że dokładnie tak jest. Użyłem warstwy abstrakcji we własnych aplikacjach, ponieważ znalazłem wzory i było mi łatwo to zrobić. Ale to był mój DAL Znałem każdy wiersz w kodzie źródłowym => pełna kontrola. Ale nie sugerowałbym, aby używać tego frameworka osobom spoza mojego zespołu / projektów.

Kiedy używasz czegoś takiego, ważne jest, aby wiedzieć, jak to jest zaimplementowane, co oznacza, że ​​powinieneś poświęcić dużo czasu na naukę biblioteki / narzędzia. Jeśli nie masz czasu na naukę - nie używaj. Nawet jeśli od samego początku wygląda to bardzo łatwo.

m5ba
źródło
Tak, firma, dla której pracowałem w przeszłości, zaczęła entuzjastycznie korzystać z Hibernacji. Następnie odkryli, jak zaskakujące (w dziwny sposób) mogą być zapytania generowane przez framework.
quant_dev
@quant_dev Tak, to jest pułapka - łatwo jest zacząć robić proste rzeczy za pomocą Hibernacji lub JPA.
m5ba