Jest to stosunkowo łatwe, ale wciąż zdarza się cały czas. Klucze obce powinny mieć indeksy. Jeśli używasz pola w WHERE, powinieneś (prawdopodobnie) mieć na nim indeks. Takie indeksy często powinny obejmować wiele kolumn na podstawie zapytań, które należy wykonać.
2. Niewymaganie integralności referencyjnej
Twoja baza danych może się tutaj różnić, ale jeśli twoja baza danych obsługuje integralność referencyjną - co oznacza, że wszystkie klucze obce mają gwarancję wskazywania na istniejącą jednostkę - powinieneś jej używać.
Dość często obserwuje się ten błąd w bazach danych MySQL. Nie wierzę, że MyISAM obsługuje to. InnoDB działa. Znajdziesz osoby, które używają MyISAM lub te, które używają InnoDB, ale i tak go nie używają.
3. Używanie naturalnych, a nie zastępczych (technicznych) kluczy podstawowych
Klucze naturalne to klucze oparte na danych o znaczeniu zewnętrznym, które są (rzekomo) unikalne. Typowymi przykładami są kody produktów, dwuliterowe kody stanów (USA), numery ubezpieczenia społecznego i tak dalej. Klucze zastępcze lub techniczne podstawowe to te, które absolutnie nie mają żadnego znaczenia poza systemem. Są one wymyślone wyłącznie w celu identyfikacji bytu i zazwyczaj są to pola automatycznie inkrementujące (SQL Server, MySQL, inne) lub sekwencje (przede wszystkim Oracle).
Moim zdaniem zawsze powinieneś używać kluczy zastępczych. Ten problem pojawił się w następujących pytaniach:
Jest to nieco kontrowersyjny temat, w sprawie którego nie osiągniesz powszechnej zgody. Chociaż możesz znaleźć ludzi, którzy uważają, że klucze naturalne są w pewnych sytuacjach OK, nie spotkasz się z żadną krytyką kluczy zastępczych poza tym, że są prawdopodobnie niepotrzebne. To dość mały minus, jeśli mnie o to poprosisz.
Często widzisz to w zapytaniach generowanych przez ORM. Spójrz na dane wyjściowe dziennika z Hibernacji, a zobaczysz, że wszystkie zapytania zaczynają się od:
SELECT DISTINCT ...
Jest to skrót do upewnienia się, że nie zwracasz zduplikowanych wierszy, a tym samym nie otrzymujesz zduplikowanych obiektów. Czasami zobaczysz, że ludzie to robią. Jeśli zobaczysz to za dużo, to prawdziwa czerwona flaga. Nie DISTINCTjest to złe lub nie ma prawidłowych aplikacji. Robi to (z obu powodów), ale nie jest to surogat ani przerwa w pisaniu poprawnych zapytań.
Moim zdaniem sytuacja zaczyna się psuć, gdy deweloper buduje solidne zapytanie, łączy tabele i nagle zdaje sobie sprawę, że wygląda na to, że robi zduplikowane (lub nawet więcej) wiersze i jego natychmiastowa odpowiedź ... jego „rozwiązaniem” tego „problemu” jest wrzucenie słowa kluczowego DISTINCT i POOF
wszystkie jego problemy znikają.
5. Preferowanie agregacji nad złączeniami
Innym częstym błędem twórców aplikacji bazodanowych jest nie zdawanie sobie sprawy z tego, o ile droższe agregowanie (tj. GROUP BYKlauzula) można porównać do złączeń.
Aby dać wyobrażenie o tym, jak bardzo jest to rozpowszechnione, pisałem na ten temat kilka razy tutaj i byłem za niego bardzo oceniany. Na przykład:
SELECT userid
FROM userrole
WHERE roleid IN (1, 2, 3)
GROUP by userid
HAVING COUNT(1) = 3
Czas zapytania: 0,312 s
Drugie zapytanie:
SELECT t1.userid
FROM userrole t1
JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2
JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3
AND t1.roleid = 1
Czas zapytania: 0,016 s
Zgadza się. Proponowana wersja dołączenia jest dwadzieścia razy szybsza niż wersja zagregowana.
6. Nie upraszczanie skomplikowanych zapytań poprzez widoki
Nie wszyscy dostawcy baz danych obsługują widoki, ale dla tych, którzy to robią, mogą znacznie uprościć zapytania, jeśli są używane rozsądnie. Na przykład w jednym projekcie użyłem ogólnego modelu Party dla CRM. Jest to niezwykle wydajna i elastyczna technika modelowania, ale może prowadzić do wielu połączeń. W tym modelu były:
Partia : ludzie i organizacje;
Rola strony : działania tych stron, na przykład pracownik i pracodawca;
Relacja ról w partii : jak te role są ze sobą powiązane.
Przykład:
Ted jest Osobą, będącą podtypem Partii;
Ted ma wiele ról, z których jedną jest pracownik;
Intel jest organizacją, będącą podtypem partii;
Intel ma wiele ról, z których jedną jest Pracodawca;
Intel zatrudnia Teda, co oznacza, że istnieje związek między ich rolami.
Jest więc pięć tabel połączonych, by połączyć Teda z jego pracodawcą. Zakładasz, że wszyscy pracownicy to Osoby (nie organizacje) i udostępniasz widok pomocnika:
CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id
I nagle masz bardzo prosty widok danych, które chcesz, ale na bardzo elastycznym modelu danych.
7. Brak dezynfekcji danych wejściowych
To jest ogromne. Teraz lubię PHP, ale jeśli nie wiesz, co robisz, bardzo łatwo jest stworzyć witryny podatne na atak. Nic nie podsumowuje lepiej niż historia małych stołów Bobby'ego .
Dane przekazywane przez użytkownika za pomocą adresów URL, danych formularzy i plików cookie należy zawsze traktować jako wrogie i odkażone. Upewnij się, że otrzymujesz to, czego oczekujesz.
8. Nieużywanie przygotowanych wyciągów
Przygotowane instrukcje mają miejsce podczas kompilowania zapytania pomniejszonego o dane użyte we wstawkach, aktualizacjach i WHEREklauzulach, a następnie dostarczone później. Na przykład:
SELECT * FROM users WHERE username = 'bob'
vs
SELECT * FROM users WHERE username = ?
lub
SELECT * FROM users WHERE username = :username
w zależności od platformy.
Widziałem bazy danych rzucane na kolana. Zasadniczo za każdym razem, gdy nowoczesna baza danych napotka nowe zapytanie, musi je skompilować. Jeśli napotka zapytanie, które było wcześniej widoczne, dajesz bazie danych możliwość buforowania skompilowanego zapytania i planu wykonania. Często wykonując zapytanie, dajesz bazę danych szansę, aby to ustalić i odpowiednio zoptymalizować (na przykład, przypinając skompilowane zapytanie w pamięci).
Korzystanie z przygotowanych instrukcji daje także znaczące statystyki dotyczące częstotliwości korzystania z niektórych zapytań.
Przygotowane wyciągi lepiej ochronią Cię przed atakami iniekcyjnymi SQL.
9. Niewystarczająco normalizujący
Normalizacja bazy danych jest zasadniczo procesem optymalizacji projektu bazy danych lub tego, jak organizujesz dane w tabele.
Właśnie w tym tygodniu natknąłem się na kod, w którym ktoś zaimplementował tablicę i wstawił ją do jednego pola w bazie danych. Normalizacja polegałaby na traktowaniu elementu tej tablicy jako osobnego wiersza w tabeli potomnej (tj. Relacji jeden do wielu).
Może się to wydawać sprzecznością z poprzednim punktem, ale normalizacja, podobnie jak wiele innych rzeczy, jest narzędziem. Jest środkiem do celu, a nie celem samym w sobie. Myślę, że wielu programistów zapomina o tym i zaczyna traktować „środki” jako „koniec”. Testowanie jednostkowe jest tego najlepszym przykładem.
Kiedyś pracowałem nad systemem, który miał ogromną hierarchię dla klientów, która działała w następujący sposób:
Licensee -> Dealer Group -> Company -> Practice -> ...
tak, że musiałeś połączyć około 11 tabel razem, zanim uzyskasz jakieś znaczące dane. To był dobry przykład zbyt daleko posuniętej normalizacji.
Co więcej, ostrożna i przemyślana denormalizacja może przynieść ogromne korzyści w zakresie wydajności, ale musisz być bardzo ostrożny.
Łuk wyłączny jest częstym błędem, gdy tabela jest tworzona z dwoma lub więcej kluczami obcymi, przy czym jeden i tylko jeden z nich może mieć wartość inną niż null. Duży błąd. Z jednej strony utrzymanie integralności danych jest o wiele trudniejsze. W końcu, nawet przy integralności referencyjnej, nic nie stoi na przeszkodzie, aby ustawić dwa lub więcej z tych kluczy obcych (pomimo złożonych ograniczeń sprawdzania).
Zdecydowanie odradzamy tworzenie ekskluzywnych łuków wszędzie tam, gdzie to możliwe, z tego dobrego powodu, że mogą być kłopotliwi w pisaniu kodu i stwarzają więcej trudności konserwacyjnych.
12. W ogóle nie przeprowadzanie analizy wydajności zapytań
Pragmatyzm króluje przede wszystkim, szczególnie w świecie baz danych. Jeśli trzymasz się zasad do tego stopnia, że stały się dogmatem, prawdopodobnie popełniłeś błędy. Weź przykład agregowanych zapytań z góry. Wersja zagregowana może wyglądać „ładnie”, ale jej wydajność jest żałosna. Porównanie wyników powinno zakończyć debatę (ale tak się nie stało), ale bardziej do rzeczy: wypowiadanie tak źle poinformowanych poglądów jest przede wszystkim ignoranckie, a nawet niebezpieczne.
13. Nadmierne poleganie na UNION ALL, a zwłaszcza na konstrukcjach UNION
UNIA w języku SQL łączy jedynie przystające zestawy danych, co oznacza, że mają ten sam typ i liczbę kolumn. Różnica między nimi polega na tym, że UNION ALL jest prostą konkatenacją i powinien być preferowany, gdy tylko jest to możliwe, podczas gdy UNION pośrednio dokona DISTINCT, aby usunąć duplikaty krotek.
Związki, jak DISTINCT, mają swoje miejsce. Istnieją prawidłowe aplikacje. Ale jeśli robisz ich dużo, szczególnie w podkwerendach, prawdopodobnie robisz coś złego. Może to być przypadek złej konstrukcji zapytania lub źle zaprojektowanego modelu danych zmuszającego do robienia takich rzeczy.
UNIA, szczególnie gdy są używane w sprzężeniach lub zależnych podkwerendach, mogą uszkodzić bazę danych. Staraj się ich unikać, gdy tylko jest to możliwe.
14. Używanie warunków LUB w zapytaniach
To może wydawać się nieszkodliwe. W końcu AND są OK. LUB powinno być OK, prawda? Źle. Zasadniczo warunek AND ogranicza zestaw danych, podczas gdy warunek OR go powiększa , ale nie w sposób, który nadaje się do optymalizacji. Zwłaszcza gdy różne warunki OR mogą się przecinać, co zmusza optymalizator do skutecznego wykonania operacji WYRÓŻNIAJĄ wynik.
Zły:
... WHERE a = 2 OR a = 5 OR a = 11
Lepszy:
... WHERE a IN (2, 5, 11)
Teraz Twój optymalizator SQL może skutecznie zamienić pierwsze zapytanie w drugie. Ale może nie. Po prostu nie rób tego.
15. Nie projektuje swojego modelu danych, aby nadawał się do wysokowydajnych rozwiązań
To trudny punkt do oszacowania. Zazwyczaj obserwuje się to przez jego działanie. Jeśli piszesz dziwne zapytania do stosunkowo prostych zadań lub że zapytania o znalezienie stosunkowo prostych informacji nie są wydajne, prawdopodobnie masz słaby model danych.
W pewnym sensie ten punkt podsumowuje wszystkie wcześniejsze, ale jest to raczej przestroga, że robienie rzeczy takich jak optymalizacja zapytań jest często wykonywane jako pierwsze, a drugie. Przed optymalizacją wydajności powinieneś upewnić się, że masz dobry model danych. Jak powiedział Knuth:
Przedwczesna optymalizacja jest źródłem wszelkiego zła
16. Nieprawidłowe użycie transakcji bazy danych
Wszystkie zmiany danych dla określonego procesu powinny mieć charakter atomowy. To znaczy, jeśli operacja się powiedzie, zrobi to w pełni. Jeśli zawiedzie, dane pozostaną niezmienione. - Nie powinno być możliwości wprowadzenia zmian w połowie dokonanych.
Idealnie najprostszym sposobem na osiągnięcie tego jest to, że cały projekt systemu powinien dążyć do obsługi wszystkich zmian danych za pomocą pojedynczych instrukcji INSERT / UPDATE / DELETE. W takim przypadku nie jest wymagana specjalna obsługa transakcji, ponieważ aparat bazy danych powinien to zrobić automatycznie.
Jeśli jednak jakiekolwiek procesy wymagają wykonania wielu instrukcji jako jednostki w celu utrzymania danych w spójnym stanie, konieczna jest odpowiednia kontrola transakcji.
Rozpocznij transakcję przed pierwszym wyciągiem.
Zatwierdź transakcję po ostatnim wyciągu.
W przypadku każdego błędu wycofaj transakcję. I bardzo NB! Nie zapomnij pominąć / przerwać wszystkie instrukcje następujące po błędzie.
Zalecane jest również zwrócenie szczególnej uwagi na subtelności tego, w jaki sposób warstwa łączności bazy danych i silnik bazy danych oddziałują w tym zakresie.
17. Niezrozumienie paradygmatu opartego na zbiorze
Język SQL jest zgodny ze specyficznym paradygmatem dostosowanym do określonych rodzajów problemów. Niezależnie od różnych rozszerzeń specyficznych dla dostawcy, język stara się radzić sobie z problemami, które są trywialne w językach takich jak Java, C #, Delphi itp.
Ten brak zrozumienia objawia się na kilka sposobów.
Niewłaściwe narzucanie zbyt dużej logiki proceduralnej lub imperatywnej dla bazy danych.
Niewłaściwe lub nadmierne użycie kursorów. Zwłaszcza, gdy wystarczy jedno zapytanie.
Niepoprawne założenie, że ma to wpływ na wyzwalanie raz na rząd w aktualizacjach wielorzędowych.
Określ wyraźny podział odpowiedzialności i staraj się używać odpowiedniego narzędzia do rozwiązania każdego problemu.
W oświadczeniach MySQL dotyczących kluczy obcych masz rację, że MyISAM ich nie obsługuje, ale sugerujesz, że samo używanie MyISAM jest złym projektem. Powodem, dla którego użyłem MyISAM, jest to, że InnoDB nie obsługuje wyszukiwania FullText i nie uważam, że jest to nieuzasadnione.
Derek H
1
Muszę zapytać o # 6. Używanie takich widoków jest jedną z moich ulubionych rzeczy, ale ostatnio z przerażeniem dowiedziałem się, że indeksy MySQL w tabelach leżących u podstaw są przestrzegane tylko wtedy, gdy struktura widoku pozwala na użycie algorytmu scalania. W przeciwnym razie używana jest tabela tymczasowa, a wszystkie indeksy są bezużyteczne. Jest to jeszcze bardziej niepokojące, gdy uświadomisz sobie, że wiele operacji powoduje takie zachowanie. To świetny sposób na zamianę zapytania o wartości 0,01 sek na 100 sekund. Czy ktoś jeszcze ma z tym doświadczenie? Sprawdź linki w moim następnym komentarzu.
Peter Bailey,
5
Całkowicie nie zgadzam się z punktem 3. Tak, kraje mogą przestać istnieć, ale kod kraju będzie nadal reprezentował to samo. To samo dotyczy kodów walut lub stanów USA. W takich przypadkach głupio jest używać klucza zastępczego i powoduje to większe obciążenie w zapytaniach, ponieważ konieczne jest dołączenie dodatkowego sprzężenia. Powiedziałbym, że bezpieczniej jest powiedzieć, że prawdopodobnie powinieneś użyć surogatu dla danych specyficznych dla użytkownika (a więc nie krajów, walut i stanów USA).
Thomas
1
RE: # 11 Ograniczenie sprawdzania potrzebne do wymuszenia integralności danych jest banalne. Istnieją inne powody, aby unikać tego projektu, ale potrzeba „złożonego” ograniczenia sprawdzania nie jest jednym z nich.
Thomas
2
Z numerem 3 nie jesteś szczery. Sztuczny klucz ma więcej wad niż „możesz go nie potrzebować”. W szczególności użycie klucza naturalnego daje możliwość kontrolowania kolejności, w jakiej dane w tabeli są zapisywane na dysku. Jeśli wiesz, w jaki sposób twoja tabela będzie przeszukiwana, możesz ją zindeksować, aby wiersze, do których jednocześnie uzyskiwano dostęp, znajdą się na tej samej stronie. Ponadto można wymusić integralność danych za pomocą unikalnego indeksu złożonego. Jeśli będziesz tego potrzebować, musisz dodać go do indeksu sztucznego klucza. Jeśli wspomniany indeks kompozytowy to twój klucz, to 2 ptaki zabijane jednym kamieniem.
Shane H,
110
Kluczowe błędy w projektowaniu i programowaniu baz danych popełniane przez programistów
Samolubny projekt i użycie bazy danych. Programiści często traktują bazę danych jako osobistą składnicę obiektów trwałych bez uwzględnienia potrzeb innych zainteresowanych stron w danych. Dotyczy to również architektów aplikacji. Zły projekt bazy danych i integralność danych utrudniają osobom trzecim pracę z danymi i mogą znacznie zwiększyć koszty cyklu życia systemu. Raportowanie i MIS bywają kiepskim kuzynem w projektowaniu aplikacji i są robione tylko po namyśle.
Nadużywanie zdenormalizowanych danych. Przesadzanie zdormalizowanych danych i próby utrzymania ich w aplikacji to przepis na problemy z integralnością danych. Oszczędnie używaj denormalizacji. Brak chęci dodania złączenia do zapytania nie jest usprawiedliwieniem denormalizacji.
Boisz się pisać SQL. SQL nie jest nauką rakietową i jest całkiem dobry w wykonywaniu swojej pracy. Warstwy mapowania O / R są dość dobre w wykonywaniu 95% zapytań, które są proste i dobrze pasują do tego modelu. Czasami SQL jest najlepszym sposobem na wykonanie zadania.
Dogmatyczne zasady „bez przechowywanych procedur”. Niezależnie od tego, czy uważasz, że procedury przechowywane są złe, tego rodzaju dogmatyczne podejście nie ma miejsca w projekcie oprogramowania.
Niezrozumienie projektu bazy danych. Normalizacja jest twoim przyjacielem i nie jest nauką o rakietach. Łączenie i liczność są dość prostymi pojęciami - jeśli jesteś zaangażowany w tworzenie aplikacji bazodanowych, naprawdę nie ma wymówki, aby ich nie zrozumieć.
Można argumentować, że transakcje należy przeprowadzać w bazie danych transakcji i raportowaniu, a MIS w oddzielnej bazie danych analizy. Dlatego otrzymujesz to, co najlepsze z obu światów i wszyscy są zadowoleni (z wyjątkiem biednego kufla, który musi napisać skrypt transformacji danych, aby zbudować drugi z tych pierwszych).
Chris Simpson
Nie tylko kiepski kubek piszący ETL - każdy, kto korzysta z danych z systemu, zła jakość danych w aplikacji MIS, która jest zapakowana, ponieważ kilka kluczowych relacji nie jest tak naprawdę rejestrowanych u źródła, każdy zaangażowany w niekończące się operacje uzgadniania, które mają miejsce z powodu niskiej jakości danych.
ConcernedOfTunbridgeWells
Nie mogłem więcej nie zgodzić się z punktem pierwszym. Bazy danych są przeznaczone do trwałości, nie służą do komunikacji między procesami. Prawie zawsze istnieją lepsze rozwiązania tego problemu. O ile nie ma wyraźnego wymogu, absolutnie POWINIENEŚ traktować bazę danych tak, jakby nikt poza aplikacją nigdy jej nie użył. Nawet jeśli JEST wyraźny wymóg, przeprowadź na nim analizę historii użytkownika i przyczyny źródłowej, a dość często odkryjesz o wiele lepszy sposób wypełnienia zamiarów wnioskodawcy. Z drugiej strony pracuję w firmie, w której wyrażenie CQRS jest dość powszechne
George Mauer
3
Trywialny przykład: Mam system zarządzania polisami ubezpieczeniowymi i muszę załadować stan 5 milionów roszczeń do systemu reasekuracji cedowanej, aby obliczyć potencjalne kwoty odzyskania. Systemy są starszymi pakietami COTS klient-serwer, zaprojektowanymi do współpracy z nawet starszymi systemami mainframe. Oba muszą zostać uzgodnione do celów kontroli finansowej. Ta praca jest wykonywana raz w miesiącu. Zgodnie z twoją logiką napisałbym serię historii użytkowników określających wymagania i poprosił dostawców, aby zacytowali dodanie opakowania usługi internetowej do ich istniejących produktów.
ConcernedOfTunbridgeWells
2
Wtedy twój DBA jest albo leniwy, albo niekompetentny.
ConcernedOfTunbridgeWells
80
Brak używania kontroli wersji w schemacie bazy danych
Działa bezpośrednio z aktywną bazą danych
Brak czytania i rozumienia bardziej zaawansowanych koncepcji baz danych (indeksów, indeksów klastrowych, ograniczeń, widoków zmaterializowanych itp.)
Niepowodzenie testu skalowalności ... dane testowe składające się tylko z 3 lub 4 rzędów nigdy nie dadzą prawdziwego obrazu rzeczywistej wydajności na żywo
Drugie miejsce, ciężko, # 1 i # 2. Za każdym razem, gdy wprowadzam zmiany do bazy danych, zrzucam jej schemat i wersjonuję; Mam trzy bazy danych, dev, inscenizację i live - NIC nigdy nie jest „testowane” na live DB !!
Ixmatus,
Tutaj w Red Gate podjęliśmy kroki, aby poprawić Twój pierwszy punkt dzięki SQL Source Control! Z rozmów, które przeprowadziłem podczas moich badań, myślę, że ludzie nie rozwijają się już w oparciu o produkcyjne bazy danych, ale często wprowadzane są poprawki „awaryjne”, które zwykle wracają do środowisk programistycznych, co jest kolejnym problemem.
David Atkinson
46
Nadużywanie i / lub zależność od procedur przechowywanych.
Niektórzy twórcy aplikacji postrzegają procedury składowane jako bezpośrednie rozszerzenie kodu warstwy środkowej / interfejsu użytkownika. Wydaje się, że jest to wspólna cecha programistów stosów Microsoft (jestem jedną z nich, ale wyrosłem z niej) i tworzy wiele procedur składowanych, które wykonują złożoną logikę biznesową i przetwarzanie przepływu pracy. Znacznie lepiej jest to zrobić gdzie indziej.
Procedury przechowywane są przydatne, gdy faktycznie udowodniono, że jakiś rzeczywisty czynnik techniczny wymaga ich użycia (na przykład wydajność i bezpieczeństwo) Na przykład utrzymanie agregacji / filtrowania dużych zestawów danych „blisko danych”.
Niedawno musiałem pomóc w utrzymaniu i ulepszeniu dużej aplikacji komputerowej Delphi, której 70% logiki biznesowej i reguł wdrożono w 1400 procedurach przechowywanych SQL Server (reszta w procedurach obsługi zdarzeń interfejsu użytkownika). Był to koszmar, głównie z powodu trudności z wprowadzeniem skutecznego testowania jednostkowego do TSQL, braku enkapsulacji i słabych narzędzi (debuggery, edytory).
Współpracując z zespołem Java w przeszłości szybko przekonałem się, że w tym środowisku często jest coś zupełnie przeciwnego. Pewien architekt Java powiedział mi kiedyś: „Baza danych służy do danych, a nie do kodu”.
W dzisiejszych czasach uważam, że błędem jest nieuwzględnianie przechowywanych procesów w ogóle, ale należy ich używać oszczędnie (nie domyślnie) w sytuacjach, w których zapewniają one użyteczne korzyści (zobacz inne odpowiedzi).
Procedury przechowywane zwykle stają się wyspą krzywdy w każdym projekcie, w którym są używane, dlatego niektórzy programiści stosują zasadę „Brak procedur przechowywanych”. Wygląda więc na to, że istnieje między nimi otwarty konflikt. Twoja odpowiedź stanowi dobry dowód na to, kiedy faktycznie wybrać jeden ze sposobów.
Warren P
Korzyści: bezpieczeństwo - nie musisz dawać aplikacjom możliwości „usuwania * z ...”; usprawnienia - DBA mogą poprawiać zapytania bez konieczności ponownej kompilacji / wdrażania całej aplikacji; analiza - łatwo jest ponownie skompilować kilka procesorów po zmianie modelu danych, aby upewnić się, że są one nadal aktualne; i wreszcie, biorąc pod uwagę, że SQL jest wykonywany przez silnik bazy danych (nie przez aplikację), wówczas koncepcja „bazy danych służy do danych, a nie kodu” jest po prostu opóźniona.
NotMe
Czylibyście wdrożyli logikę biznesową w interfejsie użytkownika, gdzie została ona oddzielona od manipulowanych danych? Nie wydaje się to dobrym pomysłem, zwłaszcza że manipulowanie danymi jest najbardziej wydajne, gdy wykonuje je serwer bazy danych, a nie w obie strony z interfejsu użytkownika. Oznacza to również, że trudniej jest kontrolować aplikację, ponieważ nie można polegać na tym, że baza danych kontroluje jej dane i potencjalnie mogą mieć różne wersje interfejsu użytkownika z różnymi manipulacjami danymi. Niedobrze. Nie pozwalam, aby cokolwiek dotykało moich danych, z wyjątkiem procedury składowanej.
David T. Macknet,
Jeśli zachodzi potrzeba oddzielenia logiki biznesowej od interfejsu użytkownika, można zastosować architektury wielowarstwowe. Lub biblioteka z obiektami biznesowymi i logiką, używana przez różne aplikacje / interfejsy użytkownika. Procedury przechowywane blokują dane / logikę biznesową w konkretnej bazie danych, zmiana bazy danych w tym przypadku jest bardzo kosztowna. Ogromny koszt jest zły.
również
@too: Zmiana bazy danych w większości przypadków jest bardzo kosztowna. Nie przejmuj się pomysłem utraty wydajności i zabezpieczeń zapewnianych przez określony system DBMS. Ponadto dodatkowe warstwy zwiększają złożoność i zmniejszają wydajność, a dodatkowe warstwy są powiązane z określonym językiem. Wreszcie, bardziej prawdopodobne jest, że użyty język zmieni się niż serwer bazy danych.
NotMe,
41
Problem numer jeden? Testują tylko na bazach zabawek. Więc nie mają pojęcia, że ich SQL będzie się czołgał, gdy baza danych się powiększy, a ktoś musi przyjść i naprawić to później (ten dźwięk, który słyszysz, to zgrzytanie moimi zębami).
Rozmiar bazy danych jest istotny, ale większym problemem jest ładowanie - nawet jeśli testujesz na prawdziwym zestawie danych, nie testujesz wydajności swoich zapytań, gdy baza danych jest obciążona produkcyjnie, co może być prawdziwym odkryciem oka.
davidcl
Powiedziałbym, że rozmiar bazy danych jest większym problemem niż ładowanie. Wiele razy widziałem, że brakowało kluczowych indeksów - nigdy nie występował problem z wydajnością podczas testów, ponieważ cała baza danych mieściła się w pamięci
Przez większość czasu chcesz unikać skorelowanych podkwerend. Podkwerenda jest skorelowana, jeśli w podkwerendie znajduje się odwołanie do kolumny z zewnętrznego zapytania. Gdy tak się dzieje, podzapytanie jest wykonywane co najmniej raz dla każdego zwracanego wiersza i może być wykonywane więcej razy, jeśli zostaną zastosowane inne warunki po zastosowaniu warunku zawierającego skorelowane podzapytanie.
Wybacz wymyślony przykład i składnię Oracle, ale powiedzmy, że chciałeś znaleźć wszystkich pracowników, którzy zostali zatrudnieni w którymkolwiek z twoich sklepów od ostatniego razu, gdy sklep dokonał sprzedaży mniejszej niż 10 000 USD dziennie.
select e.first_name, e.last_name
from employee e
where e.start_date >
(select max(ds.transaction_date)
from daily_sales ds
where ds.store_id = e.store_id and
ds.total < 10000)
Podkwerenda w tym przykładzie jest skorelowana z zewnętrznym zapytaniem store_id i zostanie wykonana dla każdego pracownika w twoim systemie. Jednym ze sposobów optymalizacji tego zapytania jest przeniesienie podzapytania do widoku wbudowanego.
select e.first_name, e.last_name
from employee e,
(select ds.store_id,
max(s.transaction_date) transaction_date
from daily_sales ds
where ds.total < 10000
group by s.store_id) dsx
where e.store_id = dsx.store_id and
e.start_date > dsx.transaction_date
W tym przykładzie zapytanie w klauzuli from jest teraz widokiem wbudowanym (ponownie niektóre składnie specyficzne dla Oracle) i jest wykonywane tylko raz. W zależności od modelu danych to zapytanie prawdopodobnie zostanie wykonane znacznie szybciej. Będzie działać lepiej niż pierwsze zapytanie wraz ze wzrostem liczby pracowników. Pierwsze zapytanie mogłoby faktycznie działać lepiej, gdyby było niewielu pracowników i wiele sklepów (a być może wiele sklepów nie miało pracowników), a tabela Daily_sales byłaby indeksowana na store_id. To nie jest prawdopodobny scenariusz, ale pokazuje, w jaki sposób skorelowane zapytanie może być skuteczniejsze niż alternatywa.
Wiele razy widziałem, jak młodsi programiści korelowali podkwerendy i zwykle miało to poważny wpływ na wydajność. Jednak usuwając skorelowane podzapytanie, należy zapoznać się z planem wyjaśniania przed i po, aby upewnić się, że nie pogarsza się wydajność.
Świetna uwaga i aby podkreślić jeden z powiązanych punktów - przetestuj zmiany. Naucz się korzystać z planów wyjaśniania (i zobacz, co właściwie robi baza danych, aby wykonać zapytanie i ile kosztuje), wykonuj testy na dużym zbiorze danych i nie powoduj, że SQL jest zbyt skomplikowany i nieczytelny / niemożliwy do utrzymania w celu optymalizacji co tak naprawdę nie poprawia rzeczywistej wydajności.
Rob Whelan,
21
Z mojego doświadczenia: brak
komunikacji z doświadczonymi DBA.
Używanie programu Access zamiast „prawdziwej” bazy danych. Istnieje wiele wspaniałych małych, a nawet bezpłatnych baz danych, takich jak SQL Express , MySQL i SQLite, które będą działać i skalować znacznie lepiej. Aplikacje często wymagają skalowania w nieoczekiwany sposób.
Chciałbym dodać: Preferowanie „eleganckiego” kodu nad kodem o wysokiej wydajności. Kod najlepiej działający w bazach danych jest często brzydki dla oka twórcy aplikacji.
Wiara w ten nonsens o przedwczesnej optymalizacji. Bazy danych muszą uwzględniać wydajność w pierwotnym projekcie i przy każdym późniejszym rozwoju. Wydajność stanowi 50% projektu bazy danych (40% to integralność danych, a ostatnie 10% to bezpieczeństwo). Bazy danych, które nie są budowane od podstaw w celu działania, będą działać źle po umieszczeniu rzeczywistych użytkowników i rzeczywistego ruchu w bazie danych. Przedwczesna optymalizacja nie oznacza braku optymalizacji! Nie oznacza to, że powinieneś pisać kod, który prawie zawsze będzie działał źle, ponieważ jest ci łatwiej (kursory na przykład, które nigdy nie powinny być dozwolone w produkcyjnej bazie danych, chyba że wszystko inne zawiedzie). Oznacza to, że nie musisz patrzeć na wyciskanie ostatniego kawałka wydajności, dopóki nie musisz. Wiele wiadomo na temat tego, co będzie działać lepiej w bazach danych,
+1 - Programowanie bazy danych obejmuje optymalizację zachowania komponentów mechanicznych. Zauważ jednak, że Knuth twierdzi, że przedwczesna optymalizacja jest źródłem wszelkiego zła przez około 97% czasu (lub słowa o tym skutku). Projektowanie baz danych jest jednym z obszarów, w którym naprawdę trzeba o tym myśleć z góry.
ConcernedOfTunbridgeWells
2
Ahem ... mówisz o optymalizacji, która nie jest przedwczesna. Od samego początku wymagane jest uwzględnienie rzeczywistego użycia w projektowaniu baz danych (a także projekt aplikacji, naprawdę). Reguła Knutha nie jest tak naprawdę trywialna, ponieważ musisz zdecydować, co jest przedwczesne, a co nie - sprowadza się to do „nie przeprowadzania optymalizacji bez danych”. Wcześniejsze decyzje dotyczące wydajności, o których mówisz, zawierają dane - niektóre projekty będą określać niedopuszczalne ograniczenia przyszłej wydajności i będziesz mógł je obliczyć.
Rob Whelan,
13
Nieużywane sparametryzowane zapytania. Są bardzo przydatne w powstrzymywaniu wstrzykiwania SQL .
Jest to konkretny przykład braku dezynfekcji danych wejściowych, wspomniany w innej odpowiedzi.
Tyle, że wprowadzanie dezynfekcji jest nieprawidłowe Odkażanie oznacza umieszczenie go w miejscu, w którym może być niebezpieczne. Parametryzacja oznacza całkowite uniknięcie krzywdy.
Dustin
12
Nienawidzę tego, gdy programiści używają zagnieżdżonych instrukcji select lub nawet funkcji zwracają wynik instrukcji select w części „SELECT” zapytania.
Jestem właściwie zaskoczony, że nie widzę tego nigdzie indziej, być może przeoczyłem to, chociaż @adam ma wskazany podobny problem.
Przykład:
SELECT
(SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
MyTable c
W tym scenariuszu, jeśli MyTable zwraca 10000 wierszy, wynik jest taki, jakby zapytanie uruchomiło tylko zapytania 20001, ponieważ musiało uruchomić zapytanie początkowe plus zapytanie do każdej z pozostałych tabel raz dla każdej linii wyniku.
Programiści mogą uniknąć tej pracy w środowisku programistycznym, w którym zwracają tylko kilka wierszy danych, a tabele podrzędne zwykle zawierają tylko niewielką ilość danych, ale w środowisku produkcyjnym tego rodzaju zapytania mogą być wykładniczo kosztowne, ponieważ więcej dane są dodawane do tabel.
Lepszym (niekoniecznie idealnym) przykładem byłoby coś takiego:
SELECT
s.SomeValue As FirstVal
,o.OtherValue As SecondVal
FROM
MyTable c
LEFT JOIN (
SELECT SomeDate, MAX(SomeValue) as SomeValue
FROM SomeTable
GROUP BY SomeDate
) s ON c.Date = s.SomeDate
LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria
Pozwala to optymalizatorom bazy danych na pomieszanie danych, a nie na żądanie dla każdego rekordu z głównej tabeli, i zwykle znajduję, kiedy muszę naprawić kod w miejscu, w którym ten problem został utworzony, zwykle w końcu zwiększam szybkość zapytań o 100% lub więcej, jednocześnie zmniejszając zużycie procesora i pamięci.
Niewykorzystywanie klastrowanych indeksów lub wybieranie niewłaściwych kolumn do klastrowania.
Nieużywanie typu danych SERIAL (autonumeracja) jako KLUCZA PODSTAWOWEGO do przyłączenia się do KLUCZA OBCEGO (INT) w relacji tabeli nadrzędnej / podrzędnej.
Nie AKTUALIZACJA STATYSTYK w tabeli, gdy wiele rekordów zostało WSTAWIONY lub USUNIĘTY.
Brak reorganizacji (tj. Rozładowywanie, upuszczanie, ponowne tworzenie, ładowanie i ponowne indeksowanie) tabel, gdy wstawiono lub usunięto wiele wierszy (niektóre silniki fizycznie przechowują usunięte wiersze w tabeli z flagą usuwania).
Nie wykorzystuje FRAGMENT NA WYRAŻENIE (jeśli jest obsługiwany) na dużych stołach, które mają wysokie stawki transakcji.
Wybór niewłaściwego typu danych dla kolumny!
Niewłaściwa nazwa kolumny.
Brak dodawania nowych kolumn na końcu tabeli.
Brak tworzenia odpowiednich indeksów do obsługi często używanych zapytań.
tworzenie indeksów na kolumnach z kilkoma możliwymi wartościami i tworzenie niepotrzebnych indeksów.
... więcej do dodania.
Spór: 2) jest właściwie złą praktyką. Rozumiem, do czego zmierzasz - chcesz mieć unikalny indeks w tym numerze automatycznym i użyć go jako klucza zastępczego. Ale klucz podstawowy nie powinien być numerem automatycznym, ponieważ nie jest nim klucz podstawowy: kluczem podstawowym jest „o czym jest ten rekord”, który (z wyjątkiem rzeczy takich jak transakcje sprzedaży) NIE jest numerem automatycznym, ale jakimś unikalnym bitem informacji o modelowanej jednostce.
David T. Macknet,
głównym powodem używania automatycznego numerowania dla klucza podstawowego i obcego jest zagwarantowanie, że połączenie rodzic-dziecko może być utrzymywane bez względu na zmiany w innych kolumnach. używanie innego klucza głównego, takiego jak nazwa klienta lub inne dane, może być ryzykowne!
Frank R.
@David: Stoję skorygowany! .. nie jest konieczne użycie autonumerowania jako klucza podstawowego, nadal można mieć indeksowaną kolumnę szeregową w obiekcie nadrzędnym, dołączając do zastępczego elementu potomnego, aby zagwarantować, że relacja nie zostanie zerwana, mając jednocześnie inny kolumna jako znacząca podstawa do zlokalizowania wiersza!
Frank R.
To kwestia semantyki na koniec dnia ... a Microsoft woli, aby klucze podstawowe były bez znaczenia, a nie znaczące. Dyskusje wokół niego trwają, ale wpadam do „znaczącego” obozu. :)
David T. Macknet,
9
Nie robienie kopii zapasowej przed naprawieniem problemu w produkcyjnej bazie danych.
Używanie poleceń DDL dla przechowywanych obiektów (takich jak tabele, widoki) w procedurach przechowywanych.
Strach przed użyciem przechowywanego proc lub strach przed użyciem zapytań ORM wszędzie tam, gdzie jest to bardziej wydajne / odpowiednie w użyciu.
Ignorowanie użycia profilera bazy danych, który może dokładnie powiedzieć, na co ostatecznie konwertowane jest zapytanie ORM, a tym samym zweryfikować logikę, a nawet debugowanie, gdy nie używa się ORM.
Niewłaściwy poziom normalizacji . Chcesz się upewnić, że dane nie są duplikowane i że dzielisz dane na różne w razie potrzeby. Musisz również upewnić się, że nie przestrzegasz zbytnio normalizacji, ponieważ wpłynie to negatywnie na wydajność.
Jak daleko jest za daleko? Jeśli żadne dane nie są duplikowane, w jaki sposób możesz je kontynuować?
finnw
Normalizacja polega na usunięciu zbędnych danych i zwiększeniu elastyczności w porównaniu ze zmniejszoną wydajnością i zwiększoną złożonością. Znalezienie właściwej równowagi wymaga doświadczenia i zmienia się z czasem. Zobacz en.wikipedia.org/wiki/Database_normalization, aby uzyskać informacje o tym, kiedy denormalizować
Nathan Voxland
8
Traktowanie bazy danych jako mechanizmu przechowywania (tj. Gloryfikowanej biblioteki kolekcji), a tym samym podporządkowanie jej aplikacji (ignorowanie innych aplikacji, które współużytkują dane)
Następstwem tego jest odciążanie aplikacji od zbyt dużej ilości zapytań, zamiast trzymania jej w db, do którego należy. LINQ jest szczególnie zły w tym zakresie.
3Dave
8
Odrzucenie ORM jak Hibernacja z ręki, z powodów takich jak „to zbyt magiczne” lub „nie na moim bazie danych”.
Zbyt mocno polegasz na ORM, takim jak Hibernacja, i próbujesz wbić go tam, gdzie nie jest to właściwe.
1 - Niepotrzebne użycie funkcji dla wartości w klauzuli where z wynikiem nieużywania tego indeksu.
Przykład:
where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate
zamiast
where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1
I w mniejszym stopniu: brak dodawania indeksów funkcjonalnych do tych wartości, które ich potrzebują ...
2 - Brak dodawania ograniczeń kontrolnych w celu zapewnienia ważności danych. Ograniczenia mogą być stosowane przez optymalizator zapytań, i NAPRAWDĘ pomagają upewnić się, że możesz ufać niezmiennikom. Po prostu nie ma powodu, aby ich nie używać.
3 - Dodawanie do tabel nietypowych kolumn z czystego lenistwa lub presji czasu. Rzeczy zwykle nie są zaprojektowane w ten sposób, ale ewoluują w ten sposób. Rezultat końcowy bez wątpienia to mnóstwo pracy nad uporządkowaniem bałaganu, gdy ugryzie Cię utrata integralności danych w przyszłych ewolucjach.
Pomyśl o tym, przeprojektowanie tabeli bez danych jest bardzo tanie. Tabela z kilkoma milionami rekordów bez integralności ... nie tak tanio przeprojektować. Tak więc wykonanie poprawnego projektu podczas tworzenia kolumny lub tabeli jest amortyzowane w pikach.
4 - nie tyle sama baza danych, co irytująca. Nie dbając o jakość kodu SQL. Fakt, że SQL jest wyrażony w tekście, nie pozwala ukryć logiki w stosach algorytmów manipulacji ciągami. Zupełnie możliwe jest pisanie SQL w tekście w sposób, który jest w rzeczywistości czytelny dla innych programistów.
To zostało powiedziane wcześniej, ale: indeksy, indeksy, indeksy . Widziałem tak wiele przypadków słabo działających aplikacji internetowych dla przedsiębiorstw, które zostały naprawione po prostu wykonując małe profilowanie (aby zobaczyć, które tabele były często atakowane), a następnie dodając indeks do tych tabel. Nie wymaga to nawet dużo wiedzy na temat pisania SQL, a wypłata jest ogromna.
Unikaj powielania danych, takich jak plaga. Niektóre osoby opowiadają się za tym, że niewielkie powielanie nie zaszkodzi i poprawi wydajność. Hej, nie mówię, że musisz torturować swój schemat do Trzeciej Normalnej Formy, dopóki nie będzie tak abstrakcyjny, że nawet DBA nie będzie wiedział, co się dzieje. Po prostu zrozum, że za każdym razem, gdy powielasz zestaw nazw, kodów pocztowych lub kodów wysyłkowych, kopie ostatecznie nie będą ze sobą zsynchronizowane. To się stanie. A potem będziesz się kopał podczas uruchamiania cotygodniowego skryptu konserwacji.
Na koniec: zastosuj jasną, spójną, intuicyjną konwencję nazewnictwa. W ten sam sposób, w jaki dobrze napisany fragment kodu powinien być czytelny, dobry schemat SQL lub zapytanie powinny być czytelne i praktycznie powiedzieć ci, co robi, nawet bez komentarzy. Podziękujesz sobie za sześć miesięcy, kiedy będziesz musiał utrzymywać stoły. "SELECT account_number, billing_date FROM national_accounts"jest nieskończenie łatwiejszy w obsłudze niż „WYBIERZ ACCNTNBR, BILLDAT FROM NTNLACCTS”.
Najczęstszy błąd, jaki widziałem od dwudziestu lat: brak planowania. Wielu programistów utworzy bazę danych i tabele, a następnie będzie stale modyfikować i rozszerzać tabele podczas tworzenia aplikacji. Efektem końcowym jest często bałagan, nieefektywny i trudny do wyczyszczenia lub uproszczenia później.
Mogę sobie wyobrazić okropności, które pojawiają się w takich sytuacjach ... Bazy danych schematów są znacznie lepiej przystosowane do szybkiego prototypowania i iteracyjnego rozwoju, ale jak wszystko inne, taka elastyczność wiąże się z różnymi kompromisami.
Zsolt Török
4
a)
Twarde kodowanie wartości zapytań w łańcuchu b) Umieszczenie kodu zapytania bazy danych w akcji „OnButtonPress” w aplikacji Windows Forms
„Umieszczenie kodu zapytania DB w akcji„ OnButtonPress ”w aplikacji Windows Form” Jaki jest błąd bazy danych?
rekurencyjny
@recursive: to ogromna luka w iniekcji SQL. Każdy może wysłać dowolny serwer SQL na serwer i zostanie on uruchomiony dosłownie.
Bill Karwin
Uzgodnione z @recursive. To naprawdę nie ma nic wspólnego z problemami z DB.
p.campbell
b) jest błędem architektury. Oczywiście kodowanie zapytań bezpośrednio w aplikacji jest złym pomysłem.
3Dave
4
Nie zwracanie wystarczającej uwagi na zarządzanie połączeniami bazy danych w aplikacji. Następnie dowiadujesz się, że aplikacja, komputer, serwer i sieć są zatkane.
Niezrozumienie modelu współbieżności baz danych i jego wpływu na rozwój. Po fakcie łatwo jest dodawać indeksy i dostosowywać zapytania. Jednak aplikacje zaprojektowane bez odpowiedniego uwzględnienia punktów aktywnych, rywalizacji o zasoby i poprawnego działania (zakładając, że to, co właśnie przeczytałeś, jest nadal ważne!) Mogą wymagać znacznych zmian w bazie danych i warstwie aplikacji, aby je poprawić później.
Nie można prawidłowo prowadzić drążka bez zrozumienia, jak działa sprzęgło. Nie możesz zrozumieć, jak korzystać z bazy danych, nie rozumiejąc, że tak naprawdę piszesz tylko do pliku na dysku twardym.
Konkretnie:
Czy wiesz, czym jest Indeks klastrowany? Czy pomyślałeś o tym, projektując swój schemat?
Czy wiesz, jak prawidłowo używać indeksów? Jak ponownie wykorzystać indeks? Czy wiesz, co to jest indeks ubezpieczenia?
Tak świetnie, masz indeksy. Jak duży jest 1 wiersz w twoim indeksie? Jak duży będzie indeks, gdy masz dużo danych? Czy to z łatwością zmieści się w pamięci? Jeśli nie, jest bezużyteczny jako indeks.
Czy kiedykolwiek używałeś EXPLAIN w MySQL? Świetny. Teraz bądź ze sobą szczery: Czy zrozumiałeś nawet połowę tego, co widziałeś? Nie, prawdopodobnie nie. Napraw to.
Czy rozumiesz pamięć podręczną zapytań? Czy wiesz, co sprawia, że zapytanie jest nie do buforowania?
Czy korzystasz z MyISAM? Jeśli POTRZEBUJESZ wyszukiwania pełnotekstowego, MyISAM jest badziewne. Użyj Sfinksa. Następnie przejdź do Inno.
Lepszą analogią może być to, że nie można właściwie rozwiązać problemów z manualną skrzynią biegów bez zrozumienia sprzęgła. Wiele osób prawidłowo prowadzi zmianę biegów, nie wiedząc, jak działa sprzęgło.
Michał Wielkanocny,
3
Używanie ORM do robienia aktualizacji zbiorczych
Wybieranie większej liczby danych niż potrzeba. Ponownie, zwykle wykonywane przy użyciu ORM
Wypalanie sqls w pętli.
Brak dobrych danych testowych i zauważenie spadku wydajności tylko w przypadku danych na żywo.
Odpowiedzi:
1. Nieużywanie odpowiednich wskaźników
Jest to stosunkowo łatwe, ale wciąż zdarza się cały czas. Klucze obce powinny mieć indeksy. Jeśli używasz pola w
WHERE
, powinieneś (prawdopodobnie) mieć na nim indeks. Takie indeksy często powinny obejmować wiele kolumn na podstawie zapytań, które należy wykonać.2. Niewymaganie integralności referencyjnej
Twoja baza danych może się tutaj różnić, ale jeśli twoja baza danych obsługuje integralność referencyjną - co oznacza, że wszystkie klucze obce mają gwarancję wskazywania na istniejącą jednostkę - powinieneś jej używać.
Dość często obserwuje się ten błąd w bazach danych MySQL. Nie wierzę, że MyISAM obsługuje to. InnoDB działa. Znajdziesz osoby, które używają MyISAM lub te, które używają InnoDB, ale i tak go nie używają.
Więcej tutaj:
3. Używanie naturalnych, a nie zastępczych (technicznych) kluczy podstawowych
Klucze naturalne to klucze oparte na danych o znaczeniu zewnętrznym, które są (rzekomo) unikalne. Typowymi przykładami są kody produktów, dwuliterowe kody stanów (USA), numery ubezpieczenia społecznego i tak dalej. Klucze zastępcze lub techniczne podstawowe to te, które absolutnie nie mają żadnego znaczenia poza systemem. Są one wymyślone wyłącznie w celu identyfikacji bytu i zazwyczaj są to pola automatycznie inkrementujące (SQL Server, MySQL, inne) lub sekwencje (przede wszystkim Oracle).
Moim zdaniem zawsze powinieneś używać kluczy zastępczych. Ten problem pojawił się w następujących pytaniach:
Jest to nieco kontrowersyjny temat, w sprawie którego nie osiągniesz powszechnej zgody. Chociaż możesz znaleźć ludzi, którzy uważają, że klucze naturalne są w pewnych sytuacjach OK, nie spotkasz się z żadną krytyką kluczy zastępczych poza tym, że są prawdopodobnie niepotrzebne. To dość mały minus, jeśli mnie o to poprosisz.
Pamiętaj, że nawet kraje mogą przestać istnieć (na przykład Jugosławia).
4. Pisanie zapytań wymagających
DISTINCT
pracyCzęsto widzisz to w zapytaniach generowanych przez ORM. Spójrz na dane wyjściowe dziennika z Hibernacji, a zobaczysz, że wszystkie zapytania zaczynają się od:
Jest to skrót do upewnienia się, że nie zwracasz zduplikowanych wierszy, a tym samym nie otrzymujesz zduplikowanych obiektów. Czasami zobaczysz, że ludzie to robią. Jeśli zobaczysz to za dużo, to prawdziwa czerwona flaga. Nie
DISTINCT
jest to złe lub nie ma prawidłowych aplikacji. Robi to (z obu powodów), ale nie jest to surogat ani przerwa w pisaniu poprawnych zapytań.Od Dlaczego nienawidzę DISTINCT :
5. Preferowanie agregacji nad złączeniami
Innym częstym błędem twórców aplikacji bazodanowych jest nie zdawanie sobie sprawy z tego, o ile droższe agregowanie (tj.
GROUP BY
Klauzula) można porównać do złączeń.Aby dać wyobrażenie o tym, jak bardzo jest to rozpowszechnione, pisałem na ten temat kilka razy tutaj i byłem za niego bardzo oceniany. Na przykład:
Z instrukcji SQL - „dołącz” vs „grupuj według i mając” :
6. Nie upraszczanie skomplikowanych zapytań poprzez widoki
Nie wszyscy dostawcy baz danych obsługują widoki, ale dla tych, którzy to robią, mogą znacznie uprościć zapytania, jeśli są używane rozsądnie. Na przykład w jednym projekcie użyłem ogólnego modelu Party dla CRM. Jest to niezwykle wydajna i elastyczna technika modelowania, ale może prowadzić do wielu połączeń. W tym modelu były:
Przykład:
Jest więc pięć tabel połączonych, by połączyć Teda z jego pracodawcą. Zakładasz, że wszyscy pracownicy to Osoby (nie organizacje) i udostępniasz widok pomocnika:
I nagle masz bardzo prosty widok danych, które chcesz, ale na bardzo elastycznym modelu danych.
7. Brak dezynfekcji danych wejściowych
To jest ogromne. Teraz lubię PHP, ale jeśli nie wiesz, co robisz, bardzo łatwo jest stworzyć witryny podatne na atak. Nic nie podsumowuje lepiej niż historia małych stołów Bobby'ego .
Dane przekazywane przez użytkownika za pomocą adresów URL, danych formularzy i plików cookie należy zawsze traktować jako wrogie i odkażone. Upewnij się, że otrzymujesz to, czego oczekujesz.
8. Nieużywanie przygotowanych wyciągów
Przygotowane instrukcje mają miejsce podczas kompilowania zapytania pomniejszonego o dane użyte we wstawkach, aktualizacjach i
WHERE
klauzulach, a następnie dostarczone później. Na przykład:vs
lub
w zależności od platformy.
Widziałem bazy danych rzucane na kolana. Zasadniczo za każdym razem, gdy nowoczesna baza danych napotka nowe zapytanie, musi je skompilować. Jeśli napotka zapytanie, które było wcześniej widoczne, dajesz bazie danych możliwość buforowania skompilowanego zapytania i planu wykonania. Często wykonując zapytanie, dajesz bazę danych szansę, aby to ustalić i odpowiednio zoptymalizować (na przykład, przypinając skompilowane zapytanie w pamięci).
Korzystanie z przygotowanych instrukcji daje także znaczące statystyki dotyczące częstotliwości korzystania z niektórych zapytań.
Przygotowane wyciągi lepiej ochronią Cię przed atakami iniekcyjnymi SQL.
9. Niewystarczająco normalizujący
Normalizacja bazy danych jest zasadniczo procesem optymalizacji projektu bazy danych lub tego, jak organizujesz dane w tabele.
Właśnie w tym tygodniu natknąłem się na kod, w którym ktoś zaimplementował tablicę i wstawił ją do jednego pola w bazie danych. Normalizacja polegałaby na traktowaniu elementu tej tablicy jako osobnego wiersza w tabeli potomnej (tj. Relacji jeden do wielu).
Pojawiło się to również w Najlepszej metodzie przechowywania listy identyfikatorów użytkowników :
Ale brak normalizacji występuje w wielu formach.
Więcej:
10. Zbyt duża normalizacja
Może się to wydawać sprzecznością z poprzednim punktem, ale normalizacja, podobnie jak wiele innych rzeczy, jest narzędziem. Jest środkiem do celu, a nie celem samym w sobie. Myślę, że wielu programistów zapomina o tym i zaczyna traktować „środki” jako „koniec”. Testowanie jednostkowe jest tego najlepszym przykładem.
Kiedyś pracowałem nad systemem, który miał ogromną hierarchię dla klientów, która działała w następujący sposób:
tak, że musiałeś połączyć około 11 tabel razem, zanim uzyskasz jakieś znaczące dane. To był dobry przykład zbyt daleko posuniętej normalizacji.
Co więcej, ostrożna i przemyślana denormalizacja może przynieść ogromne korzyści w zakresie wydajności, ale musisz być bardzo ostrożny.
Więcej:
11. Korzystanie z ekskluzywnych łuków
Łuk wyłączny jest częstym błędem, gdy tabela jest tworzona z dwoma lub więcej kluczami obcymi, przy czym jeden i tylko jeden z nich może mieć wartość inną niż null. Duży błąd. Z jednej strony utrzymanie integralności danych jest o wiele trudniejsze. W końcu, nawet przy integralności referencyjnej, nic nie stoi na przeszkodzie, aby ustawić dwa lub więcej z tych kluczy obcych (pomimo złożonych ograniczeń sprawdzania).
Od praktycznego przewodnika po projektach relacyjnych baz danych :
12. W ogóle nie przeprowadzanie analizy wydajności zapytań
Pragmatyzm króluje przede wszystkim, szczególnie w świecie baz danych. Jeśli trzymasz się zasad do tego stopnia, że stały się dogmatem, prawdopodobnie popełniłeś błędy. Weź przykład agregowanych zapytań z góry. Wersja zagregowana może wyglądać „ładnie”, ale jej wydajność jest żałosna. Porównanie wyników powinno zakończyć debatę (ale tak się nie stało), ale bardziej do rzeczy: wypowiadanie tak źle poinformowanych poglądów jest przede wszystkim ignoranckie, a nawet niebezpieczne.
13. Nadmierne poleganie na UNION ALL, a zwłaszcza na konstrukcjach UNION
UNIA w języku SQL łączy jedynie przystające zestawy danych, co oznacza, że mają ten sam typ i liczbę kolumn. Różnica między nimi polega na tym, że UNION ALL jest prostą konkatenacją i powinien być preferowany, gdy tylko jest to możliwe, podczas gdy UNION pośrednio dokona DISTINCT, aby usunąć duplikaty krotek.
Związki, jak DISTINCT, mają swoje miejsce. Istnieją prawidłowe aplikacje. Ale jeśli robisz ich dużo, szczególnie w podkwerendach, prawdopodobnie robisz coś złego. Może to być przypadek złej konstrukcji zapytania lub źle zaprojektowanego modelu danych zmuszającego do robienia takich rzeczy.
UNIA, szczególnie gdy są używane w sprzężeniach lub zależnych podkwerendach, mogą uszkodzić bazę danych. Staraj się ich unikać, gdy tylko jest to możliwe.
14. Używanie warunków LUB w zapytaniach
To może wydawać się nieszkodliwe. W końcu AND są OK. LUB powinno być OK, prawda? Źle. Zasadniczo warunek AND ogranicza zestaw danych, podczas gdy warunek OR go powiększa , ale nie w sposób, który nadaje się do optymalizacji. Zwłaszcza gdy różne warunki OR mogą się przecinać, co zmusza optymalizator do skutecznego wykonania operacji WYRÓŻNIAJĄ wynik.
Zły:
Lepszy:
Teraz Twój optymalizator SQL może skutecznie zamienić pierwsze zapytanie w drugie. Ale może nie. Po prostu nie rób tego.
15. Nie projektuje swojego modelu danych, aby nadawał się do wysokowydajnych rozwiązań
To trudny punkt do oszacowania. Zazwyczaj obserwuje się to przez jego działanie. Jeśli piszesz dziwne zapytania do stosunkowo prostych zadań lub że zapytania o znalezienie stosunkowo prostych informacji nie są wydajne, prawdopodobnie masz słaby model danych.
W pewnym sensie ten punkt podsumowuje wszystkie wcześniejsze, ale jest to raczej przestroga, że robienie rzeczy takich jak optymalizacja zapytań jest często wykonywane jako pierwsze, a drugie. Przed optymalizacją wydajności powinieneś upewnić się, że masz dobry model danych. Jak powiedział Knuth:
16. Nieprawidłowe użycie transakcji bazy danych
Wszystkie zmiany danych dla określonego procesu powinny mieć charakter atomowy. To znaczy, jeśli operacja się powiedzie, zrobi to w pełni. Jeśli zawiedzie, dane pozostaną niezmienione. - Nie powinno być możliwości wprowadzenia zmian w połowie dokonanych.
Idealnie najprostszym sposobem na osiągnięcie tego jest to, że cały projekt systemu powinien dążyć do obsługi wszystkich zmian danych za pomocą pojedynczych instrukcji INSERT / UPDATE / DELETE. W takim przypadku nie jest wymagana specjalna obsługa transakcji, ponieważ aparat bazy danych powinien to zrobić automatycznie.
Jeśli jednak jakiekolwiek procesy wymagają wykonania wielu instrukcji jako jednostki w celu utrzymania danych w spójnym stanie, konieczna jest odpowiednia kontrola transakcji.
Zalecane jest również zwrócenie szczególnej uwagi na subtelności tego, w jaki sposób warstwa łączności bazy danych i silnik bazy danych oddziałują w tym zakresie.
17. Niezrozumienie paradygmatu opartego na zbiorze
Język SQL jest zgodny ze specyficznym paradygmatem dostosowanym do określonych rodzajów problemów. Niezależnie od różnych rozszerzeń specyficznych dla dostawcy, język stara się radzić sobie z problemami, które są trywialne w językach takich jak Java, C #, Delphi itp.
Ten brak zrozumienia objawia się na kilka sposobów.
Określ wyraźny podział odpowiedzialności i staraj się używać odpowiedniego narzędzia do rozwiązania każdego problemu.
źródło
Kluczowe błędy w projektowaniu i programowaniu baz danych popełniane przez programistów
Samolubny projekt i użycie bazy danych. Programiści często traktują bazę danych jako osobistą składnicę obiektów trwałych bez uwzględnienia potrzeb innych zainteresowanych stron w danych. Dotyczy to również architektów aplikacji. Zły projekt bazy danych i integralność danych utrudniają osobom trzecim pracę z danymi i mogą znacznie zwiększyć koszty cyklu życia systemu. Raportowanie i MIS bywają kiepskim kuzynem w projektowaniu aplikacji i są robione tylko po namyśle.
Nadużywanie zdenormalizowanych danych. Przesadzanie zdormalizowanych danych i próby utrzymania ich w aplikacji to przepis na problemy z integralnością danych. Oszczędnie używaj denormalizacji. Brak chęci dodania złączenia do zapytania nie jest usprawiedliwieniem denormalizacji.
Boisz się pisać SQL. SQL nie jest nauką rakietową i jest całkiem dobry w wykonywaniu swojej pracy. Warstwy mapowania O / R są dość dobre w wykonywaniu 95% zapytań, które są proste i dobrze pasują do tego modelu. Czasami SQL jest najlepszym sposobem na wykonanie zadania.
Dogmatyczne zasady „bez przechowywanych procedur”. Niezależnie od tego, czy uważasz, że procedury przechowywane są złe, tego rodzaju dogmatyczne podejście nie ma miejsca w projekcie oprogramowania.
Niezrozumienie projektu bazy danych. Normalizacja jest twoim przyjacielem i nie jest nauką o rakietach. Łączenie i liczność są dość prostymi pojęciami - jeśli jesteś zaangażowany w tworzenie aplikacji bazodanowych, naprawdę nie ma wymówki, aby ich nie zrozumieć.
źródło
źródło
Nadużywanie i / lub zależność od procedur przechowywanych.
Niektórzy twórcy aplikacji postrzegają procedury składowane jako bezpośrednie rozszerzenie kodu warstwy środkowej / interfejsu użytkownika. Wydaje się, że jest to wspólna cecha programistów stosów Microsoft (jestem jedną z nich, ale wyrosłem z niej) i tworzy wiele procedur składowanych, które wykonują złożoną logikę biznesową i przetwarzanie przepływu pracy. Znacznie lepiej jest to zrobić gdzie indziej.
Procedury przechowywane są przydatne, gdy faktycznie udowodniono, że jakiś rzeczywisty czynnik techniczny wymaga ich użycia (na przykład wydajność i bezpieczeństwo) Na przykład utrzymanie agregacji / filtrowania dużych zestawów danych „blisko danych”.
Niedawno musiałem pomóc w utrzymaniu i ulepszeniu dużej aplikacji komputerowej Delphi, której 70% logiki biznesowej i reguł wdrożono w 1400 procedurach przechowywanych SQL Server (reszta w procedurach obsługi zdarzeń interfejsu użytkownika). Był to koszmar, głównie z powodu trudności z wprowadzeniem skutecznego testowania jednostkowego do TSQL, braku enkapsulacji i słabych narzędzi (debuggery, edytory).
Współpracując z zespołem Java w przeszłości szybko przekonałem się, że w tym środowisku często jest coś zupełnie przeciwnego. Pewien architekt Java powiedział mi kiedyś: „Baza danych służy do danych, a nie do kodu”.
W dzisiejszych czasach uważam, że błędem jest nieuwzględnianie przechowywanych procesów w ogóle, ale należy ich używać oszczędnie (nie domyślnie) w sytuacjach, w których zapewniają one użyteczne korzyści (zobacz inne odpowiedzi).
źródło
Problem numer jeden? Testują tylko na bazach zabawek. Więc nie mają pojęcia, że ich SQL będzie się czołgał, gdy baza danych się powiększy, a ktoś musi przyjść i naprawić to później (ten dźwięk, który słyszysz, to zgrzytanie moimi zębami).
źródło
Nie używa indeksów.
źródło
Niska wydajność spowodowana skorelowanymi podzapytaniami
Przez większość czasu chcesz unikać skorelowanych podkwerend. Podkwerenda jest skorelowana, jeśli w podkwerendie znajduje się odwołanie do kolumny z zewnętrznego zapytania. Gdy tak się dzieje, podzapytanie jest wykonywane co najmniej raz dla każdego zwracanego wiersza i może być wykonywane więcej razy, jeśli zostaną zastosowane inne warunki po zastosowaniu warunku zawierającego skorelowane podzapytanie.
Wybacz wymyślony przykład i składnię Oracle, ale powiedzmy, że chciałeś znaleźć wszystkich pracowników, którzy zostali zatrudnieni w którymkolwiek z twoich sklepów od ostatniego razu, gdy sklep dokonał sprzedaży mniejszej niż 10 000 USD dziennie.
Podkwerenda w tym przykładzie jest skorelowana z zewnętrznym zapytaniem store_id i zostanie wykonana dla każdego pracownika w twoim systemie. Jednym ze sposobów optymalizacji tego zapytania jest przeniesienie podzapytania do widoku wbudowanego.
W tym przykładzie zapytanie w klauzuli from jest teraz widokiem wbudowanym (ponownie niektóre składnie specyficzne dla Oracle) i jest wykonywane tylko raz. W zależności od modelu danych to zapytanie prawdopodobnie zostanie wykonane znacznie szybciej. Będzie działać lepiej niż pierwsze zapytanie wraz ze wzrostem liczby pracowników. Pierwsze zapytanie mogłoby faktycznie działać lepiej, gdyby było niewielu pracowników i wiele sklepów (a być może wiele sklepów nie miało pracowników), a tabela Daily_sales byłaby indeksowana na store_id. To nie jest prawdopodobny scenariusz, ale pokazuje, w jaki sposób skorelowane zapytanie może być skuteczniejsze niż alternatywa.
Wiele razy widziałem, jak młodsi programiści korelowali podkwerendy i zwykle miało to poważny wpływ na wydajność. Jednak usuwając skorelowane podzapytanie, należy zapoznać się z planem wyjaśniania przed i po, aby upewnić się, że nie pogarsza się wydajność.
źródło
Z mojego doświadczenia: brak
komunikacji z doświadczonymi DBA.
źródło
Używanie programu Access zamiast „prawdziwej” bazy danych. Istnieje wiele wspaniałych małych, a nawet bezpłatnych baz danych, takich jak SQL Express , MySQL i SQLite, które będą działać i skalować znacznie lepiej. Aplikacje często wymagają skalowania w nieoczekiwany sposób.
źródło
Zapomniałem skonfigurować relacji między tabelami. Pamiętam, że musiałem to wyczyścić, kiedy zacząłem pracować u mojego obecnego pracodawcy.
źródło
Korzystanie z Excela do przechowywania (dużych ilości) danych.
Widziałem firmy posiadające tysiące wierszy i korzystające z wielu arkuszy (z powodu limitu wierszy 65535 w poprzednich wersjach programu Excel).
Excel doskonale nadaje się do raportów, prezentacji danych i innych zadań, ale nie powinien być traktowany jako baza danych.
źródło
Chciałbym dodać: Preferowanie „eleganckiego” kodu nad kodem o wysokiej wydajności. Kod najlepiej działający w bazach danych jest często brzydki dla oka twórcy aplikacji.
Wiara w ten nonsens o przedwczesnej optymalizacji. Bazy danych muszą uwzględniać wydajność w pierwotnym projekcie i przy każdym późniejszym rozwoju. Wydajność stanowi 50% projektu bazy danych (40% to integralność danych, a ostatnie 10% to bezpieczeństwo). Bazy danych, które nie są budowane od podstaw w celu działania, będą działać źle po umieszczeniu rzeczywistych użytkowników i rzeczywistego ruchu w bazie danych. Przedwczesna optymalizacja nie oznacza braku optymalizacji! Nie oznacza to, że powinieneś pisać kod, który prawie zawsze będzie działał źle, ponieważ jest ci łatwiej (kursory na przykład, które nigdy nie powinny być dozwolone w produkcyjnej bazie danych, chyba że wszystko inne zawiedzie). Oznacza to, że nie musisz patrzeć na wyciskanie ostatniego kawałka wydajności, dopóki nie musisz. Wiele wiadomo na temat tego, co będzie działać lepiej w bazach danych,
źródło
Nieużywane sparametryzowane zapytania. Są bardzo przydatne w powstrzymywaniu wstrzykiwania SQL .
Jest to konkretny przykład braku dezynfekcji danych wejściowych, wspomniany w innej odpowiedzi.
źródło
Nienawidzę tego, gdy programiści używają zagnieżdżonych instrukcji select lub nawet funkcji zwracają wynik instrukcji select w części „SELECT” zapytania.
Jestem właściwie zaskoczony, że nie widzę tego nigdzie indziej, być może przeoczyłem to, chociaż @adam ma wskazany podobny problem.
Przykład:
W tym scenariuszu, jeśli MyTable zwraca 10000 wierszy, wynik jest taki, jakby zapytanie uruchomiło tylko zapytania 20001, ponieważ musiało uruchomić zapytanie początkowe plus zapytanie do każdej z pozostałych tabel raz dla każdej linii wyniku.
Programiści mogą uniknąć tej pracy w środowisku programistycznym, w którym zwracają tylko kilka wierszy danych, a tabele podrzędne zwykle zawierają tylko niewielką ilość danych, ale w środowisku produkcyjnym tego rodzaju zapytania mogą być wykładniczo kosztowne, ponieważ więcej dane są dodawane do tabel.
Lepszym (niekoniecznie idealnym) przykładem byłoby coś takiego:
Pozwala to optymalizatorom bazy danych na pomieszanie danych, a nie na żądanie dla każdego rekordu z głównej tabeli, i zwykle znajduję, kiedy muszę naprawić kod w miejscu, w którym ten problem został utworzony, zwykle w końcu zwiększam szybkość zapytań o 100% lub więcej, jednocześnie zmniejszając zużycie procesora i pamięci.
źródło
W przypadku baz danych opartych na SQL:
... więcej do dodania.
źródło
Nie robienie kopii zapasowej przed naprawieniem problemu w produkcyjnej bazie danych.
Używanie poleceń DDL dla przechowywanych obiektów (takich jak tabele, widoki) w procedurach przechowywanych.
Strach przed użyciem przechowywanego proc lub strach przed użyciem zapytań ORM wszędzie tam, gdzie jest to bardziej wydajne / odpowiednie w użyciu.
Ignorowanie użycia profilera bazy danych, który może dokładnie powiedzieć, na co ostatecznie konwertowane jest zapytanie ORM, a tym samym zweryfikować logikę, a nawet debugowanie, gdy nie używa się ORM.
źródło
Niewłaściwy poziom normalizacji . Chcesz się upewnić, że dane nie są duplikowane i że dzielisz dane na różne w razie potrzeby. Musisz również upewnić się, że nie przestrzegasz zbytnio normalizacji, ponieważ wpłynie to negatywnie na wydajność.
źródło
Traktowanie bazy danych jako mechanizmu przechowywania (tj. Gloryfikowanej biblioteki kolekcji), a tym samym podporządkowanie jej aplikacji (ignorowanie innych aplikacji, które współużytkują dane)
źródło
źródło
1 - Niepotrzebne użycie funkcji dla wartości w klauzuli where z wynikiem nieużywania tego indeksu.
Przykład:
zamiast
I w mniejszym stopniu: brak dodawania indeksów funkcjonalnych do tych wartości, które ich potrzebują ...
2 - Brak dodawania ograniczeń kontrolnych w celu zapewnienia ważności danych. Ograniczenia mogą być stosowane przez optymalizator zapytań, i NAPRAWDĘ pomagają upewnić się, że możesz ufać niezmiennikom. Po prostu nie ma powodu, aby ich nie używać.
3 - Dodawanie do tabel nietypowych kolumn z czystego lenistwa lub presji czasu. Rzeczy zwykle nie są zaprojektowane w ten sposób, ale ewoluują w ten sposób. Rezultat końcowy bez wątpienia to mnóstwo pracy nad uporządkowaniem bałaganu, gdy ugryzie Cię utrata integralności danych w przyszłych ewolucjach.
Pomyśl o tym, przeprojektowanie tabeli bez danych jest bardzo tanie. Tabela z kilkoma milionami rekordów bez integralności ... nie tak tanio przeprojektować. Tak więc wykonanie poprawnego projektu podczas tworzenia kolumny lub tabeli jest amortyzowane w pikach.
4 - nie tyle sama baza danych, co irytująca. Nie dbając o jakość kodu SQL. Fakt, że SQL jest wyrażony w tekście, nie pozwala ukryć logiki w stosach algorytmów manipulacji ciągami. Zupełnie możliwe jest pisanie SQL w tekście w sposób, który jest w rzeczywistości czytelny dla innych programistów.
źródło
To zostało powiedziane wcześniej, ale: indeksy, indeksy, indeksy . Widziałem tak wiele przypadków słabo działających aplikacji internetowych dla przedsiębiorstw, które zostały naprawione po prostu wykonując małe profilowanie (aby zobaczyć, które tabele były często atakowane), a następnie dodając indeks do tych tabel. Nie wymaga to nawet dużo wiedzy na temat pisania SQL, a wypłata jest ogromna.
Unikaj powielania danych, takich jak plaga. Niektóre osoby opowiadają się za tym, że niewielkie powielanie nie zaszkodzi i poprawi wydajność. Hej, nie mówię, że musisz torturować swój schemat do Trzeciej Normalnej Formy, dopóki nie będzie tak abstrakcyjny, że nawet DBA nie będzie wiedział, co się dzieje. Po prostu zrozum, że za każdym razem, gdy powielasz zestaw nazw, kodów pocztowych lub kodów wysyłkowych, kopie ostatecznie nie będą ze sobą zsynchronizowane. To się stanie. A potem będziesz się kopał podczas uruchamiania cotygodniowego skryptu konserwacji.
Na koniec: zastosuj jasną, spójną, intuicyjną konwencję nazewnictwa. W ten sam sposób, w jaki dobrze napisany fragment kodu powinien być czytelny, dobry schemat SQL lub zapytanie powinny być czytelne i praktycznie powiedzieć ci, co robi, nawet bez komentarzy. Podziękujesz sobie za sześć miesięcy, kiedy będziesz musiał utrzymywać stoły.
"SELECT account_number, billing_date FROM national_accounts"
jest nieskończenie łatwiejszy w obsłudze niż „WYBIERZ ACCNTNBR, BILLDAT FROM NTNLACCTS”.źródło
Nie wykonanie odpowiedniego zapytania SELECT przed uruchomieniem zapytania DELETE (szczególnie w produkcyjnych bazach danych)!
źródło
Najczęstszy błąd, jaki widziałem od dwudziestu lat: brak planowania. Wielu programistów utworzy bazę danych i tabele, a następnie będzie stale modyfikować i rozszerzać tabele podczas tworzenia aplikacji. Efektem końcowym jest często bałagan, nieefektywny i trudny do wyczyszczenia lub uproszczenia później.
źródło
a)
Twarde kodowanie wartości zapytań w łańcuchu b) Umieszczenie kodu zapytania bazy danych w akcji „OnButtonPress” w aplikacji Windows Forms
Widziałem oba.
źródło
Nie zwracanie wystarczającej uwagi na zarządzanie połączeniami bazy danych w aplikacji. Następnie dowiadujesz się, że aplikacja, komputer, serwer i sieć są zatkane.
źródło
Myśląc, że są DBA i projektantami danych / projektantami, gdy nie mają formalnej indoktrynacji w tych obszarach.
Myśląc, że ich projekt nie wymaga DBA, ponieważ wszystko jest łatwe / trywialne.
Niewłaściwe rozróżnienie między pracą, która powinna zostać wykonana w bazie danych, a pracą, która powinna zostać wykonana w aplikacji.
Nie sprawdzam poprawności kopii zapasowych lub nie tworzysz kopii zapasowej.
Osadzanie surowego SQL w kodzie.
źródło
Oto link do filmu pt. „ Klasyczne błędy w tworzeniu baz danych i pięć sposobów na ich przezwyciężenie ” autorstwa Scotta Walza
źródło
Niezrozumienie modelu współbieżności baz danych i jego wpływu na rozwój. Po fakcie łatwo jest dodawać indeksy i dostosowywać zapytania. Jednak aplikacje zaprojektowane bez odpowiedniego uwzględnienia punktów aktywnych, rywalizacji o zasoby i poprawnego działania (zakładając, że to, co właśnie przeczytałeś, jest nadal ważne!) Mogą wymagać znacznych zmian w bazie danych i warstwie aplikacji, aby je poprawić później.
źródło
Nie rozumiem, jak DBMS działa pod maską.
Nie można prawidłowo prowadzić drążka bez zrozumienia, jak działa sprzęgło. Nie możesz zrozumieć, jak korzystać z bazy danych, nie rozumiejąc, że tak naprawdę piszesz tylko do pliku na dysku twardym.
Konkretnie:
Czy wiesz, czym jest Indeks klastrowany? Czy pomyślałeś o tym, projektując swój schemat?
Czy wiesz, jak prawidłowo używać indeksów? Jak ponownie wykorzystać indeks? Czy wiesz, co to jest indeks ubezpieczenia?
Tak świetnie, masz indeksy. Jak duży jest 1 wiersz w twoim indeksie? Jak duży będzie indeks, gdy masz dużo danych? Czy to z łatwością zmieści się w pamięci? Jeśli nie, jest bezużyteczny jako indeks.
Czy kiedykolwiek używałeś EXPLAIN w MySQL? Świetny. Teraz bądź ze sobą szczery: Czy zrozumiałeś nawet połowę tego, co widziałeś? Nie, prawdopodobnie nie. Napraw to.
Czy rozumiesz pamięć podręczną zapytań? Czy wiesz, co sprawia, że zapytanie jest nie do buforowania?
Czy korzystasz z MyISAM? Jeśli POTRZEBUJESZ wyszukiwania pełnotekstowego, MyISAM jest badziewne. Użyj Sfinksa. Następnie przejdź do Inno.
źródło
źródło