W każdej firmie, w której pracowałem, zauważyłem, że ludzie nadal piszą swoje zapytania SQL w standardzie ANSI-89:
select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id
zamiast standardu ANSI-92:
select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id
W przypadku niezwykle prostego zapytania, takiego jak to, nie ma dużej różnicy w czytelności, ale w przypadku dużych zapytań okazuje się, że pogrupowanie kryteriów łączenia z listą tabeli znacznie ułatwia sprawdzenie, gdzie mogą wystąpić problemy z połączeniem, i pozwól mi zachować całe moje filtrowanie w mojej klauzuli WHERE. Nie wspominając już o tym, że czuję, że łączenia zewnętrzne są dużo intuicyjne niż składnia (+) w Oracle.
Kiedy próbuję ewangelizować ANSI-92 wśród ludzi, czy są jakieś konkretne korzyści z używania ANSI-92 w porównaniu z ANSI-89? Chciałbym wypróbować to sam, ale konfiguracje Oracle, które tutaj mamy, nie pozwalają nam na użycie EXPLAIN PLAN - czy nie chciałbyś, aby ludzie próbowali zoptymalizować swój kod, prawda?
Odpowiedzi:
Według raportu „SQL Performance Tuning” Petera Gulutzana i Trudy Pelzer, z sześciu lub ośmiu testowanych przez nich marek RDBMS, nie było różnicy w optymalizacji lub wydajności łączenia SQL-89 i SQL-92. Można założyć, że większość silników RDBMS przekształca składnię w wewnętrzną reprezentację przed optymalizacją lub wykonaniem zapytania, więc składnia czytelna dla człowieka nie robi różnicy.
Próbuję też ewangelizować składnię SQL-92. Szesnaście lat po zatwierdzeniu, najwyższy czas, aby ludzie zaczęli go używać! Wszystkie bazy danych SQL obsługują ją teraz, więc nie ma powodu, aby nadal używać niestandardowej
(+)
składni Oracle lub składni*=
Microsoft / Sybase.Jeśli chodzi o to, dlaczego tak trudno jest zerwać społeczność programistów z nawykiem SQL-89, mogę tylko założyć, że istnieje duża „baza piramidy” programistów, którzy kodują metodą kopiowania i wklejania, używając starożytnych przykładów z książek, artykułów z czasopism, lub inna baza kodu, a ci ludzie nie uczą się nowej składni w sposób abstrakcyjny. Niektórzy ludzie dopasowują się do wzorców, a niektórzy uczą się na pamięć.
Jednak stopniowo widzę ludzi używających składni SQL-92 częściej niż kiedyś. Odpowiadam na pytania SQL online od 1994 roku.
źródło
Cóż, standard ANSI092 zawiera dość ohydną składnię. Połączenia naturalne to jedno, a klauzula USING to drugie. IMHO, dodanie kolumny do tabeli nie powinno zepsuć kodu, ale NATURALNE JOIN zepsuje się w najbardziej rażący sposób. „Najlepszym” sposobem na przerwanie jest błąd kompilacji. Na przykład, jeśli gdzieś wybierzesz *, dodanie kolumny możenie udało się skompilować. Następnym najlepszym sposobem na niepowodzenie byłby błąd czasu wykonywania. Jest gorzej, ponieważ Twoi użytkownicy mogą to zobaczyć, ale nadal daje ładne ostrzeżenie, że coś zepsułeś. Jeśli używasz ANSI92 i piszesz zapytania z łączeniami NATURAL, nie ulegnie on awarii w czasie kompilacji i nie ulegnie awarii w czasie wykonywania, zapytanie nagle zacznie dawać błędne wyniki. Tego typu błędy są podstępne. Raporty są błędne, potencjalne informacje finansowe są nieprawidłowe.
Dla tych, którzy nie są zaznajomieni z połączeniami NATURAL. Łączą dwie tabele w każdej nazwie kolumny, która istnieje w obu tabelach. Co jest naprawdę fajne, gdy masz 4-kolumnowy klucz i masz dość wpisywania go. Problem pojawia się, gdy Tabela1 ma wcześniej istniejącą kolumnę o nazwie DESCRIPTION i dodajesz nową kolumnę o nazwie Table2 o nazwie, och, nie wiem, coś nieszkodliwego, jak mmm, DESCRIPTION, a teraz dołączasz do dwóch tabel na VARCHAR2 (1000) pole o dowolnym kształcie.
Klauzula USING może prowadzić do całkowitej niejednoznaczności oprócz problemu opisanego powyżej. W innym poście SO ktoś pokazał ten ANSI-92 SQL i poprosił o pomoc w jego czytaniu.
To jest całkowicie niejednoznaczne. Umieściłem kolumnę UserID w tabelach firm i użytkowników i nie ma żadnych skarg. Co się stanie, jeśli kolumna ID użytkownika w firmach jest identyfikatorem ostatniej osoby, która zmodyfikowała ten wiersz?
Mówię poważnie, czy ktoś może wyjaśnić, dlaczego taka dwuznaczność była konieczna? Dlaczego jest wbudowany bezpośrednio w standard?
Myślę, że Bill ma rację, że istnieje duża baza programistów, którzy kopiują / wklejają tam przez kodowanie. Prawdę mówiąc, mogę przyznać, że jestem taki, jeśli chodzi o ANSI-92. Każdy przykład, jaki kiedykolwiek widziałem, pokazywał, że wiele złączeń jest zagnieżdżonych w nawiasach. Szczerość, która sprawia, że wybieranie stolików w sql jest w najlepszym razie trudne. Ale potem ewangilista SQL92 wyjaśnił, że faktycznie wymusiłoby to kolejność łączenia. JEZUS ... wszyscy ci kopiący pasterze, których widziałem, wymuszają teraz polecenie łączenia - zadanie, które w 95% przypadków lepiej pozostawić optymalizatorom, zwłaszcza kopiowaniu / pasterowi.
Tomalak dobrze zrozumiał, kiedy powiedział:
To musi mi coś dać i nie widzę korzyści. A jeśli jest plus, negatywy to albatros zbyt duży, aby je zignorować.
źródło
SELECT *
(wtedy dowiadujemy się, że klient polega na zamówieniu w terenie) - Po prostu wydaje się trochę niechlujnyPrzychodzi mi na myśl kilka powodów:
Ze swojej strony wykonuję wszystkie sprzężenia w składni SQL-92 i konwertuję kod tam, gdzie mogę. Jest to czystszy, bardziej czytelny i skuteczniejszy sposób. Ale trudno jest przekonać kogoś do używania nowego stylu, gdy uważa, że boli go to, ponieważ wymaga więcej pracy na klawiaturze bez zmiany wyniku zapytania.
źródło
W odpowiedzi na powyższy post NATURAL JOIN and USING.
DLACZEGO kiedykolwiek widziałbyś potrzebę ich użycia - nie były one dostępne w ANSI-89 i zostały dodane dla ANSI-92 jako coś, co widzę tylko jako skrót.
Nigdy nie zostawiłbym połączenia przypadkowi i zawsze określałbym tabelę / alias i identyfikator.
Dla mnie jedyną możliwą drogą jest ANSI-92. Jest bardziej rozwlekły, a składnia nie jest lubiana przez zwolenników ANSI-89, ale zgrabnie oddziela SPRZĘŻENIA od FILTROWANIA.
źródło
Najpierw powiem, że w SQL Server składnia sprzężenia zewnętrznego (* =) nie daje przez cały czas poprawnych wyników. Są chwile, kiedy interpretuje to jako połączenie krzyżowe, a nie połączenie zewnętrzne. Jest więc dobry powód, aby przestać go używać. A ta składnia sprzężenia zewnętrznego jest przestarzałą funkcją i nie będzie dostępna w następnej wersji SQL Server po SQL Server 2008. Nadal będziesz w stanie wykonywać sprzężenia wewnętrzne, ale dlaczego ktoś miałby to robić? Są niejasne i dużo trudniejsze w utrzymaniu. Nie łatwo wiesz, co jest częścią złączenia, a co tak naprawdę jest tylko klauzulą Where.
Jednym z powodów, dla których uważam, że nie powinieneś używać starej składni, jest to, że zrozumienie łączy i tego, co robią, a czego nie, jest krytycznym krokiem dla każdego, kto napisze kod SQL. Nie powinieneś pisać żadnego kodu SQL bez dokładnego zrozumienia złączeń. Jeśli dobrze je zrozumiesz, prawdopodobnie dojdziesz do wniosku, że składnia ANSI-92 jest jaśniejsza i łatwiejsza w utrzymaniu. Nigdy nie spotkałem eksperta od SQL, który nie używałby składni ANSI-92 zamiast starej składni.
Większość ludzi, z którymi się spotkałem lub z którymi miałem do czynienia, którzy używają starego kodu, naprawdę nie rozumie złączeń i przez to wpada w kłopoty podczas wysyłania zapytań do bazy danych. To jest moje osobiste doświadczenie, więc nie mówię, że zawsze jest prawdą. Ale jako specjalista od danych musiałem przez lata naprawiać zbyt wiele tych śmieci, żeby w to nie wierzyć.
źródło
W szkole uczyłem się ANSI-89 i przez kilka lat pracowałem w przemyśle. Potem na 8 lat opuściłem bajkowy świat DBMS. Ale potem wróciłem i nauczono tego nowego materiału ANSI 92. Nauczyłem się składni Join On, a teraz faktycznie uczę SQL i polecam nową składnię JOIN ON.
Ale wadą, którą widzę, są skorelowane podzapytania, które nie mają sensu w świetle złączeń ANSI 92. Kiedy informacje o złączeniach zostały uwzględnione w GDZIE, a skorelowane podzapytania są „połączone” w GDZIE, wszystko wydawało się prawidłowe i spójne. W ANSI 92 kryteria łączenia tabel nie znajdują się w GDZIE, a podzapytanie „łączenie” jest, składnia wydaje się niespójna. Z drugiej strony próba „naprawienia” tej niespójności prawdopodobnie tylko pogorszy sytuację.
źródło
Nie znam odpowiedzi na pewno ... to jest wojna religijna (prawie w mniejszym stopniu niż Mac-PC lub inne)
Można przypuszczać, że do niedawna Oracle (i być może także inni dostawcy) nie przyjęli standardu ANSI-92 (myślę, że był to Oracle v9, lub coś podobnego), a więc w przypadku DBA / Db Developers pracujących w firmach, które nadal używali tych wersji (lub chcieli, aby kod był przenośny między serwerami, które mogą używać tych wersji, musieli trzymać się starego standardu ...
Naprawdę szkoda, ponieważ nowa składnia złączeń jest znacznie bardziej czytelna, a stara składnia generuje błędne (niepoprawne) wyniki w kilku dobrze udokumentowanych scenariuszach.
źródło
INNER JOIN
w 1995 r., AleLEFT JOIN
dopiero w 1996 r. MySQL obsługuje go co najmniej od wersji 3.23, wydanej w 1999 r .; PostgreSQL przynajmniej od wersji 7.2, wydanej w 2002 roku. Niektóre zwykłe Googlowanie nie daje mi odpowiedzi na temat Teradata.Bezwładność i praktyczność.
ANSI-92 SQL przypomina pisanie bezwzrokowe. W pewnym sensie teoretycznie może to kiedyś poprawić wszystko, ale teraz mogę pisać znacznie szybciej, patrząc na klawisze czterema palcami. Musiałbym cofnąć się, aby iść naprzód, bez gwarancji, że kiedykolwiek nastąpi zwrot.
Pisanie SQL to około 10% mojej pracy. Jeśli potrzebuję ANSI-92 SQL do rozwiązania problemu, którego ANSI-89 SQL nie może rozwiązać, użyję go. (Właściwie używam go w Accessie). Gdyby używanie go cały czas pomogło mi znacznie szybciej rozwiązać istniejące problemy, poświęciłbym czas na przyswojenie go. Ale mogę wypisać ANSI-89 SQL bez zastanawiania się nad składnią. Płacą mi za rozwiązywanie problemów - myślenie o składni SQL to strata czasu i pieniędzy pracodawcy.
Pewnego dnia, młody Grasshopperze, będziesz bronić swojego używania składni ANSI-92 SQL przed narzekaniem młodych ludzi, że powinieneś używać SQL3 (lub czegoś podobnego). A wtedy zrozumiesz. :-)
źródło
Miałem zapytanie, które zostało pierwotnie napisane dla SQL Server 6.5, które nie obsługuje składni złączenia SQL 92, tj
został zamiast tego zapisany jako
Zapytanie istniało już od jakiegoś czasu, a odpowiednie dane zostały zgromadzone, aby wykonać zapytanie zbyt wolno, trwało około 90 sekund. Zanim pojawił się ten problem, przeprowadziliśmy aktualizację do SQL Server 7.
Po grzebaniu w indeksach i innych żartach na Wielkanoc, zmieniłem składnię łączenia na zgodną z SQL 92. Czas zapytania spadł do 3 sekund.
Jest dobry powód, aby się zmienić.
Opublikowano ponownie stąd .
źródło
Potrafię odpowiedzieć z punktu widzenia przeciętnego programisty, znając tylko tyle SQL, aby zrozumieć obie składnie, ale wciąż szukam w Google dokładnej składni wstawiania za każdym razem, gdy tego potrzebuję ... :-P (nie robię SQL przez cały dzień , po prostu od czasu do czasu naprawiając niektóre problemy).
Cóż, właściwie, uważam, że pierwsza forma jest bardziej intuicyjna, bez widocznej hierarchii między dwiema tabelami. Fakt, że nauczyłem się SQL prawdopodobnie ze starych książek, pokazując pierwszą formę, prawdopodobnie nie pomaga ... ;-)
I pierwsza wzmianka, którą znajduję w wyszukiwaniu sql select w Google (która zwraca dla mnie głównie francuskie odpowiedzi ... ) najpierw pokazuje starszą formę (następnie wyjaśnij drugą).
Podaję tylko kilka wskazówek na pytanie „dlaczego”… ^ _ ^ Powinienem przeczytać dobrą, nowoczesną książkę (agnostyk DB) na ten temat. Jeśli ktoś ma sugestie ...
źródło
Nie mogę mówić w imieniu wszystkich szkół, ale na moim uniwersytecie, kiedy robiliśmy moduł SQL naszego kursu, nie uczyli ANSI-92, uczyli ANSI-89 - i to na starym systemie VAX! Nie byłem narażony na ANSI-92, dopóki nie zacząłem kopać w programie Access, budując kilka zapytań za pomocą projektanta zapytań, a następnie zagłębiając się w kod SQL. Zdając sobie sprawę, że nie miałem pojęcia, jak kończy się łączenie, ani implikacje składni, zacząłem szukać głębiej, aby móc to zrozumieć.
Biorąc pod uwagę, że dostępna dokumentacja w wielu przypadkach nie jest dokładnie intuicyjna, a ludzie mają tendencję do trzymania się tego, co wiedzą, aw wielu przypadkach nie starają się uczyć więcej niż potrzebują, aby wykonać swoją pracę, łatwo zrozumieć, dlaczego adopcja trwa tak długo.
Oczywiście są tacy ewangeliści techniczni, którzy lubią majsterkować i rozumieć, i są to zazwyczaj te typy, które przyjmują „nowsze” zasady i próbują nawrócić resztę.
Co dziwne, wydaje mi się, że wielu programistów wychodzi ze szkoły i przestaje robić postępy; myśląc, że skoro tego ich uczono, tak się to robi. Dopiero gdy zdejmiesz migawki, zdasz sobie sprawę, że szkoła miała tylko nauczyć cię podstaw i dać ci wystarczająco dużo zrozumienia, aby samemu nauczyć się reszty, i że tak naprawdę ledwo zarysowałeś powierzchnię tego, co trzeba wiedzieć; teraz twoim zadaniem jest kontynuować tę ścieżkę.
Oczywiście to tylko moja opinia oparta na moim doświadczeniu.
źródło
1) Standardowy sposób zapisywania OUTER JOIN w porównaniu z * = lub (+) =
2) NATURALNE DOŁĄCZENIE
3) W zależności od silnika bazy danych, ANSI-92 jest bardziej optymalny.
4) Optymalizacja ręczna:
Powiedzmy, że mamy następną składnię (ANSI-89):
Można to zapisać jako:
Ale także jako:
Wszystkie (1), (2), (3) zwracają ten sam wynik, jednak są one inaczej optymalizowane, zależy to od silnika bazy danych, ale większość z nich:
5) Dłuższe zapytania są mniej kłopotliwe.
źródło
Powody, dla których ludzie używają ANSI-89 z mojego praktycznego doświadczenia ze starymi i młodymi programistami i stażystami oraz świeżymi absolwentami:
Osobiście wolę ANSI-92 i zmieniam każde zapytanie, które widzę w składni ANSI-89, czasami tylko po to, aby lepiej zrozumieć instrukcję SQL. Ale zdałem sobie sprawę, że większość ludzi, z którymi pracuję, nie ma wystarczających umiejętności, aby pisać złączenia na wielu tabelach. Kodują najlepiej, jak potrafią i używają tego, co zapamiętali, gdy po raz pierwszy napotkali instrukcję SQL.
źródło
Oto kilka punktów porównujących SQL-89 i SQL-92 oraz wyjaśniających pewne nieporozumienia w innych odpowiedziach.
NATURAL JOINS
to okropny pomysł. Są niejawne i wymagają metainformacji o tabeli. Nic w SQL-92 nie wymaga ich użycia, więc po prostu je zignoruj . Nie mają one znaczenia dla tej dyskusji.USING
to świetny pomysł, ma dwa efekty:id
w obu tabelach. Po dołączeniu do tabel staje się to niejednoznaczne i wymaga jawnego aliasingu. Co więcej,id
znaki na złączeniu prawie na pewno miały inne dane. Jeśli łączysz osobę z firmą, musisz teraz utworzyć alias jedenid
doperson_id
i jedenid
docompany_id
, bez których sprzężenie dałoby dwie niejednoznaczne kolumny. Użycie unikalnego globalnie identyfikatora dla klucza zastępczego tabeli jest konwencją, zgodnie z którą standardowo nagradzaUSING
.CROSS JOIN
. ACROSS JOIN
nie redukuje zbioru, ale pośrednio go powiększa.FROM T1,T2
jest tym samym, coFROM T1 CROSS JOIN T2
, tworzy sprzężenie kartezjańskie, które zwykle nie jest tym, czego chcesz. Posiadanie selektywności pozwalającej zredukować to do odległegoWHERE
warunku oznacza, że bardziej prawdopodobne jest popełnienie błędów podczas projektowania.,
JawneJOIN
kody SQL-89 i SQL-92 mają inny priorytet.JOIN
ma wyższy priorytet. Co gorsza, niektóre bazy danych, takie jak MySQL, źle to rozumiały przez bardzo długi czas. . Tak więc mieszanie tych dwóch stylów jest złym pomysłem, a obecnie o wiele bardziej popularnym stylem jest styl SQL-92.źródło
Oracle w ogóle nie implementuje standardu ANSI-92. Miałem kilka problemów, między innymi dlatego, że tabele danych w Oracle Apps są tak dobrze wyposażone w kolumny. Jeśli liczba kolumn w połączeniach przekracza około 1050 kolumn (co jest bardzo łatwe w aplikacjach), otrzymasz ten fałszywy błąd, który nie ma absolutnie żadnego logicznego sensu:
Ponowne napisanie zapytania w celu użycia składni łączenia w starym stylu sprawia, że problem znika, co wydaje się wskazywać palcem winy bezpośrednio na implementację złączeń ANSI-92.
Dopóki nie napotkałem tego problemu, byłem niezłomnym promotorem ASNI-92, ze względu na korzyści w zmniejszaniu szansy przypadkowego łączenia krzyżowego, co jest zbyt łatwe do wykonania przy użyciu składni starego stylu.
Teraz jednak jest mi o wiele trudniej nalegać na to. Wskazują na złą implementację Oracle i mówią „Zrobimy to po swojemu, dzięki”.
źródło
Nowy standard SQL dziedziczy wszystko z poprzedniego standardu, czyli „kajdany zgodności”. Tak więc styl łączenia „stary” / „rozdzielany przecinkami” / „niekwalifikowany” jest całkowicie poprawnym sytaxem SQL-92.
Teraz twierdzę, że SQL-92
NATURAL JOIN
jest jedynym złączeniem, którego potrzebujesz. Na przykład uważam, że jest lepszy odinner join
tego, że nie generuje zduplikowanych kolumn - nie ma już zmiennych zakresu wSELECT
klauzulach, aby ujednoznacznić kolumny! Ale nie mogę oczekiwać, że zmienię każde serce i umysł, więc muszę pracować z programistami, którzy będą nadal przyjmować to, co osobiście uważam za starsze style łączenia (a mogą nawet odnosić się do zmiennych zakresu jako „aliasy”!). Taka jest natura pracy zespołowej, a nie działania w próżni.Jedną z krytyki języka SQL jest to, że ten sam wynik można uzyskać za pomocą kilku semantycznie równoważnych składni (niektóre używają algebry relacyjnej, inne używają rachunku relacyjnego), gdzie wybór `` najlepszej '' sprowadza się po prostu do osobistego stylu . Więc czuję się równie dobrze z połączeniami „w starym stylu”, jak z
INNER
. To, czy poświęcę trochę czasu, aby je przepisać,NATURAL
zależy od kontekstu.źródło