Wszyscy, którzy pracują z relacyjnymi bazami danych, nauczyli się (lub uczą się), że SQL jest inny. Uzyskanie pożądanych rezultatów i zrobienie tego wydajnie wymaga żmudnego procesu częściowo charakteryzującego się poznaniem nieznanych paradygmatów i odkryciem, że niektóre z naszych najbardziej znanych wzorców programowania nie działają tutaj. Jakie są typowe antypatterny, które widziałeś (lub sam popełniłeś)?
sql
anti-patterns
le dorfier
źródło
źródło
Odpowiedzi:
Konsekwentnie rozczarowuje mnie tendencja większości programistów do mieszania logiki interfejsu użytkownika w warstwie dostępu do danych:
Zwykle programiści robią to, ponieważ zamierzają powiązać swój zestaw danych bezpośrednio z siatką, a po prostu wygodnie jest mieć format SQL Server po stronie serwera niż format na kliencie.
Zapytania takie jak powyższe są wyjątkowo kruche, ponieważ ściśle łączą warstwę danych z warstwą interfejsu użytkownika. Ponadto ten styl programowania całkowicie uniemożliwia ponowne użycie procedur przechowywanych.
źródło
Oto moje 3 najlepsze.
Numer 1. Brak określenia listy pól. (Edycja: aby uniknąć nieporozumień: jest to reguła kodu produkcyjnego. Nie dotyczy to jednorazowych skryptów analitycznych - chyba że jestem autorem).
Powinien być
Numer 2. Używając kursora i pętli while, gdy wykona się pętla while ze zmienną pętli.
Numer 3. DateLogic poprzez typy ciągów.
Powinien być
Widziałem ostatnio skok „Jedno zapytanie jest lepsze niż dwa, prawda?”
To zapytanie wymaga dwóch lub trzech różnych planów wykonania w zależności od wartości parametrów. Generowany jest tylko jeden plan wykonania i umieszczany w pamięci podręcznej dla tego tekstu sql. Ten plan będzie stosowany niezależnie od wartości parametrów. Powoduje to sporadyczne słabe działanie. O wiele lepiej jest napisać dwa zapytania (jedno zapytanie na planowany plan wykonania).
źródło
Pola hasła czytelne dla człowieka , np. Wyjaśniające.
Korzystanie LIKE przed indeksowanych kolumnach, a ja prawie pokusie tylko powiedzieć, jak w ogóle.
Recykling wygenerowanych przez SQL wartości PK.
Niespodzianka, nikt jeszcze nie wspomniał o boskim stole . Nic nie mówi „organiczne” jak 100 kolumn flag bitowych, dużych ciągów i liczb całkowitych.
Następnie jest wzorzec „Tęsknię za plikami .ini” : przechowywanie plików CSV, ciągów rozdzielanych potokami lub innych wymaganych danych w dużych polach tekstowych.
A w przypadku serwera MS SQL w ogóle korzystanie z kursorów . Jest lepszy sposób na wykonanie dowolnego zadania kursora.
Edytowane, ponieważ jest ich tak wiele!
źródło
LIKE '%LIKE'
.Nie musisz za to głęboko sięgać: nie używaj przygotowanych instrukcji.
źródło
Używanie bez znaczenia aliasów tabeli:
Sprawia, że czytanie dużej instrukcji SQL jest o wiele trudniejsze niż to konieczne
źródło
źródło
Moje błędy to 450 kolumn z tabelami dostępu, które zostały zebrane przez 8-letniego syna najlepszego przyjaciela dyrektora zarządzającego, pielęgnatora psów i podejrzana tabela przeglądowa, która istnieje tylko dlatego, że ktoś nie wie, jak poprawnie znormalizować strukturę danych.
Zazwyczaj ta tabela odnośników wygląda następująco:
Straciłem rachubę liczby klientów, którzy widziałem, którzy mają systemy oparte na takich ohydach.
źródło
Te, których najbardziej nie lubię, to
Używanie spacji podczas tworzenia tabel, sproków itp. Nie mam nic przeciwko CamelCase lub under_scores i liczby pojedynczej lub mnogiej i DUŻYM lub małym literom, ale muszę odwoływać się do tabeli lub kolumny [ze spacjami], zwłaszcza jeśli [jest dziwnie rozmieszczony] (tak, Wpadłem na to) naprawdę mnie denerwuje.
Dane zdormalizowane. Tabela nie musi być doskonale znormalizowana, ale kiedy napotkam tabelę pracowników, która ma informacje o ich bieżącym wyniku oceny lub ich podstawowej naturze, mówi mi, że prawdopodobnie będę musiał kiedyś stworzyć osobną tabelę i następnie spróbuj je zsynchronizować. Najpierw znormalizuję dane, a następnie, jeśli zobaczę miejsce, w którym pomaga denormalizacja, rozważę to.
Nadużywanie widoków lub kursorów. Widoki mają swój cel, ale kiedy każdy stół jest zawinięty w widok, jest to zbyt wiele. Musiałem użyć kursorów kilka razy, ale ogólnie możesz do tego użyć innych mechanizmów.
Dostęp. Czy program może być anty-wzorcem? W mojej pracy mamy SQL Server, ale wiele osób korzysta z dostępu ze względu na jego dostępność, „łatwość użycia” i „przyjazność” dla użytkowników nietechnicznych. Jest tu zbyt wiele, aby się w nie zaangażować, ale jeśli byłeś w podobnym środowisku, wiesz.
źródło
użyj SP jako prefiksu nazwy procedury składowania, ponieważ najpierw przeszuka ona lokalizację procedur systemowych, a nie niestandardowe.
źródło
Nadużywanie tymczasowych tabel i kursorów.
źródło
Do przechowywania wartości czasu należy używać tylko strefy czasowej UTC. Nie należy używać czasu lokalnego.
źródło
używając @@ IDENTITY zamiast SCOPE_IDENTITY ()
Cytat z tej odpowiedzi :
źródło
Ponowne użycie „martwego” pola do czegoś, do czego nie było przeznaczone (np. Przechowywanie danych użytkownika w polu „Faks”) - bardzo kuszące jako szybkie rozwiązanie!
źródło
i zakładając, że wynik zostanie posortowany według some_column. Widziałem to trochę w Sybase, gdzie założenie to obowiązuje (na razie).
źródło
Lub wkuwanie wszystkiego w jedną linię.
źródło
FROM TableA, TableB WHERE
Składnia ŁĄCZY zamiastFROM TableA INNER JOIN TableB ON
Przyjmując założenie, że zapytanie zostanie zwrócone, posortowano w określony sposób bez wstawiania klauzuli ORDER BY, tylko dlatego, że tak to pokazało się podczas testowania w narzędziu zapytań.
źródło
Nauka języka SQL w ciągu pierwszych sześciu miesięcy ich kariery i nigdy nie uczenie się niczego przez następne 10 lat. W szczególności brak uczenia się lub efektywnego korzystania z funkcji okienkowania / analizy SQL. W szczególności użycie over () i podział według.
Aby uzyskać ładny przegląd funkcji okienkowania, zobacz O'Reilly SQL Cookbook Dodatek A.
źródło
Muszę tu umieścić mojego obecnego faworyta, aby uzupełnić listę. Mój ulubiony antypattern nie testuje twoich zapytań .
Ma to zastosowanie, gdy:
Wszelkie testy przeprowadzane na nietypowych lub niewystarczających danych się nie liczą. Jeśli jest to procedura składowana, umieść instrukcję testu w komentarzu i zapisz ją wraz z wynikami. W przeciwnym razie umieść go w komentarzu w kodzie z wynikami.
źródło
Tymczasowe nadużycie tabeli.
W szczególności tego rodzaju rzeczy:
Nie buduj tabeli tymczasowej z zapytania, aby usunąć niepotrzebne wiersze.
I tak, widziałem strony kodu w tej formie w produkcyjnych bazach danych.
źródło
Pogląd przeciwny: nadmierna obsesja na punkcie normalizacji.
Większość systemów SQL / RBDB oferuje wiele funkcji (transakcji, replikacji), które są bardzo przydatne, nawet w przypadku nienormalizowanych danych. Miejsce na dysku jest tanie, a czasem może być prostsze (łatwiejszy kod, szybszy czas programowania) manipulowanie / filtrowanie / wyszukiwanie pobranych danych, niż pisanie schematu 1NF i radzenie sobie z wszystkimi zawartymi w nim problemami (złożone połączenia, nieprzyjemne podselekcje itp.).
Odkryłem, że nadmiernie znormalizowane systemy są często przedwczesną optymalizacją, szczególnie na wczesnych etapach rozwoju.
(więcej przemyśleń na ten temat ... http://writeonly.wordpress.com/2008/12/05/simple-object-db-using-json-and-python-sqlite/ )
źródło
Właśnie złożyłem to razem, w oparciu o niektóre odpowiedzi SQL tutaj na SO.
Poważnym przeciwnikiem jest myślenie, że wyzwalacze dotyczą baz danych, podobnie jak procedury obsługi zdarzeń do OOP. Istnieje przekonanie, że dowolną starą logikę można wprowadzić w wyzwalacze, które zostaną zwolnione, gdy transakcja (zdarzenie) nastąpi na stole.
Nie prawda. Jedną z dużych różnic jest to, że wyzwalacze są synchroniczne - z zemstą, ponieważ są one synchroniczne na określonej operacji, a nie na wierszu. Po stronie OOP dokładnie odwrotnie - zdarzenia to skuteczny sposób na implementację transakcji asynchronicznych.
źródło
Procedury przechowywane lub funkcje bez komentarzy ...
źródło
1) Nie wiem, czy to „oficjalny” anty-wzór, ale nie lubię i staram się unikać literałów łańcuchowych jako magicznych wartości w kolumnie bazy danych.
Przykład z „obrazu” tabeli MediaWiki:
(Po prostu zauważam inną obudowę, kolejną rzeczą, której należy unikać)
Projektuję takie przypadki jak wyszukiwania int w tabelach ImageMediaType i ImageMajorMime z int kluczami podstawowymi.
2) konwersja daty / łańcucha, która zależy od określonych ustawień NLS
bez identyfikatora formatu
źródło
Identyczne podzapytania w zapytaniu.
źródło
Zmieniony widok - widok, który jest zmieniany zbyt często i bez uprzedzenia lub powodu. Zmiana zostanie zauważona w najbardziej nieodpowiednim czasie lub, co gorsza, będzie błędna i nigdy nie zauważona. Być może Twoja aplikacja ulegnie awarii, ponieważ ktoś wymyślił lepszą nazwę dla tej kolumny. Z reguły widoki powinny zwiększać użyteczność tabel podstawowych przy jednoczesnym utrzymaniu umowy z konsumentami. Napraw problemy, ale nie dodawaj funkcji ani gorzej zmieniaj zachowanie, aby utworzyć nowy widok. Aby ograniczyć ryzyko, nie udostępniaj widoków innym projektom i korzystaj z CTE, gdy pozwalają na to platformy. Jeśli twój sklep ma DBA, prawdopodobnie nie możesz zmienić poglądów, ale wszystkie twoje widoki będą nieaktualne i / lub bezużyteczne w takim przypadku.
! Paramed - czy zapytanie może mieć więcej niż jeden cel? Prawdopodobnie, ale następna osoba, która ją przeczyta, nie dowie się o niej aż do głębokiej medytacji. Nawet jeśli nie potrzebujesz ich teraz, są szanse, że tak będzie, nawet jeśli „tylko” to debugowanie. Dodanie parametrów skraca czas konserwacji i utrzymuje SUCHO. Jeśli masz klauzulę where, powinieneś mieć parametry.
Sprawa bez CASE -
źródło
Dwa, które najbardziej mi się podobają i mogą mieć znaczny koszt pod względem wydajności to:
Używanie kursorów zamiast wyrażenia opartego na zestawie. Myślę, że ten występuje często, gdy programista myśli w sposób proceduralny.
Używanie skorelowanych zapytań cząstkowych, gdy sprzężenie z tabelą pochodną może wykonać zadanie.
źródło
Umieszczanie rzeczy w tabelach tymczasowych, szczególnie osoby, które przechodzą z SQL Server na Oracle, mają zwyczaj nadużywania tabel tymczasowych. Wystarczy użyć zagnieżdżonych instrukcji select.
źródło
Programiści, którzy piszą zapytania, nie mając pojęcia, co powoduje, że aplikacje SQL (zarówno zapytania indywidualne, jak i systemy dla wielu użytkowników) są szybkie lub wolne. Obejmuje to ignorancję na temat:
źródło
Używanie SQL jako gloryfikowanego pakietu ISAM (Indexed Sequential Access Method). W szczególności zagnieżdżanie kursorów zamiast łączenia instrukcji SQL w jedną, choć większą, instrukcję. Jest to również liczone jako „nadużycie optymalizatora”, ponieważ tak naprawdę niewiele można zrobić. Można to połączyć z nieprzygotowanymi oświadczeniami dla maksymalnej nieefektywności:
Prawidłowym rozwiązaniem (prawie zawsze) jest połączenie dwóch instrukcji SELECT w jedną:
Jedyną zaletą wersji z podwójną pętlą jest to, że można łatwo dostrzec przerwy między wartościami w tabeli 1, ponieważ pętla wewnętrzna się kończy. Może to być czynnikiem w raportach z łamaniem kontroli.
Ponadto sortowanie w aplikacji jest zwykle nie-nie.
źródło
Używanie kluczy podstawowych jako surogatu dla adresów rekordów i używanie kluczy obcych jako surogatu dla wskaźników osadzonych w rekordach.
źródło