Podczas korzystania z ORM, na co należy zwrócić uwagę w projekcie bazy danych

19

Na co należy zwrócić uwagę przy projektowaniu bazy danych, gdy wiadomo, że do bazy danych można uzyskać dostęp za pomocą Wikipedii Object Relational Mapper (ORM) ? Zobacz także Entity Framework NHibernate lub LLBLGenPro.

Jako przykład zwrócę uwagę na limit 2100 parametrów w wywołaniu RPC SqlServer. Jest to problem podczas używania LLBLgen i łączenia tabel, gdy używane są złożone klucze podstawowe. Zobacz MSDN artykuł na temat kluczy złożonych .

BozoJoe
źródło
4
Bez obrazy, ale „łączenie tabel z więcej niż 1 kluczem podstawowym” .. to redefiniuje jedną z podstawowych zasad tabeli, pojedynczą PK na tabelę. Co dokładnie miałeś na myśli?
Marian
W jaki sposób osiąga to limit parametru 2100? Czy masz tabele z tyloma kolumnami? Zakładam również, że masz na myśli „mapowanie obiektowo-relacyjne”, a nie „modelowanie ról obiektowych”
John Saunders,
Limit 2100 parametrów jest czasem problemem, jeśli przekażesz dużą listę wartości do SQL IN (tablica LINQ.Contains (członek)). Jednak tak naprawdę nie ma to nic wspólnego z projektowaniem baz danych; to raczej problem ze wzorcem zapytania. Najłatwiejszym obejściem dla ORM, które „cierpią” z tego powodu, jest wstawienie listy do [stałej] tabeli tymczasowej i dołączenie do niej i / lub użycie podzapytania, które wybiera elementy, z których mają być wysyłane zapytania, skąd pochodzą. (przekazywanie tysięcy elementów do SQL IN jest ogólnie złe, niezależnie od tego, czy używasz mapera OR, czy nie).
KristoferA
@John, tak Object Relational Mapping
BozoJoe
4
@BozoJoe: tabela może - z definicji - mieć tylko jeden klucz podstawowy. Nie ma DBMS, który pozwala zdefiniować więcej niż jeden klucz podstawowy dla pojedynczej tabeli.
a_horse_w_no_name

Odpowiedzi:

17

Przejdź przez standardowe techniki normalizacyjne, głównie do 3. normalnej postaci. Niektóre ORM mogą wykrywać relacje zdefiniowane na poziomie bazy danych, więc nie musisz ręcznie.

Naprawdę poszedłbym w drugą stronę i zapytałbym, co powinienem wiedzieć o ORM. Upewnij się, że wiesz: - Jak profilować zapytania? - Jak mogę zastąpić ORM i napisać własne zapytanie? - Czy zamiast tego mogę użyć zapisanych proc?

Baza danych powinna być niezależna od ORM, ponieważ jest bardziej niż prawdopodobne, że przetrwa ona przed aplikacją.

Eric Humphrey - lotsahelp
źródło
+1: „Baza danych powinna być niezależna od ORM”. Trzymaj się standardów projektowania baz danych, a dobre ORM również będą zadowolone.
MicSim,
12
  1. Nigdy nie pozwól ORM tworzyć ani aktualizować schematu. Zawsze używaj wygenerowanego kodu SQL jako szablonu, ale przejrzyj go przed wprowadzeniem zmiany (widziałem, jak nasz ORM tworzy nadmiarowe indeksy, używa złych typów danych ... wszystkie te złe rzeczy)

  2. Bądź świadomy tego, czego Twoja ORM nie może zrobić. Django przez jakiś czas nie wspierał grupy przez ORM, co było uciążliwe (nadal jest, starsze systemy zabawy!). Zatem świadomość ograniczeń ORM jest koniecznością dla DBA, nawet jeśli to nie one piszą kod dla ORM

  3. Od czasu do czasu chwyć powolne dzienniki, agreguj je przez mysqlslowlog i spójrz na około 10 najlepszych. Zasadniczo pokaże Ci zapytania, które zajęły najwięcej czasu. Kwerenda, która zajęła średnio tylko 1 sekundę, ale wykonała 50 000 razy w ciągu ostatniego miesiąca, wystawiałaby się na ten zbiorczy raport jak obolały kciuk;)

Nie powiedziałbym, że idź tak ekstremalnie, jak całkowicie zrzucić ORM. Jeśli programiści używający ORM nie są DBA, prawdopodobnie będą pisać SQL równie zły lub gorszy niż ORM. Więc w końcu spadnie na DBA, aby zobaczyć, co się dzieje.

TechieGurl
źródło
1
I rozważ umieszczenie bardzo złożonej logiki w przechowywanym proc. ORM mogą wywoływać przechowywane procy i dla bardzo złożonej logiki łatwiej jest dostroić wydajność proc.
HLGEM
7

Jest kilka rzeczy, które od razu zauważam w starszej bazie danych, która różni się od bazy danych utworzonej przez ORM, takie jak Sequel i ActiveRecord dla Ruby.

  1. Zastosowanie klucza podstawowego we wszystkich nazywanych tabelach 'id'. Tak, można to zmienić, ale idjest to ustawienie domyślne.
  2. Zastosowanie liczby mnogiej w tabelach.
  3. Zastosowanie podkreślenia („snakecase”) do oddzielenia słów tworzących opisową nazwę tabel i pól.
  4. Zastosowanie _iddołączania do kluczy obcych: układ jest zwykle podobny referenced_table_id.

Od lat piszę SQL ręcznie, ponieważ nie ufałem ORM, ale w ciągu ostatnich dwóch lub trzech zacząłem używać dwóch wcześniej wspomnianych ORM i jestem pod wrażeniem, jak dobrze integrują się z istniejącymi bazami danych, i jak dobrze potrafią rozszyfrować bazę danych, jeśli ich konwencje są przestrzegane, lub poświęcam czas, aby dać im wskazówki potrzebne do zrozumienia starszej wersji DB.

Nie wiem, czy istnieją jakieś wspólne wytyczne dotyczące projektowania schematów do dobrej zabawy z ORM, ale myślę, że wszyscy skorzystalibyśmy dzięki pewnym standardom. Na pewno jest czas i miejsce na ORM, szczególnie jeśli używasz dobrego języka OO i masz napięty harmonogram.

Blaszany Człowiek
źródło
1
FYI: istnieją narzędzia do radzenia sobie z różnicami konwencji nazewnictwa dla wielu twórców map OR. Mam dodatek do programu Visual Studio, który zajmuje się tym w przypadku Entity Framework i Linq-to-SQL z nazewnictwem opartym na regułach; więcej informacji na ten temat można znaleźć na stronie huagati.com/dbmltools .
KristoferA,
1
Identyfikator to antipattern SQL do nazewnictwa pola id i nie należy go używać.
HLGEM
Chcesz wyjaśnić, dlaczego? Jak radzimy sobie z relacjami między tabelami, gdy musimy przeprowadzać wyszukiwania typu jeden do wielu i wiele do jednego? W ORMach, których używam, nieużywanie identyfikatora zdecydowanie nie działa.
Tin Man
2

Zależy to (:)) nieco od używanego mapera OR, więc poświęć trochę czasu na zbadanie, jakie właściwości db obsługuje maper OR lub obsługuje.

Np. Mapery OR Microsoft nie obsługują wszystkich wbudowanych typów danych SQL Server, nie obsługują niektórych nowszych / zaawansowanych funkcji TSQL (rekurencyjne zapytania, wskazówki dotyczące optymalizacji itp. Przychodzą mi do głowy).

Teoretycznie dobry maper OR powinien być wystarczająco elastyczny, aby pokonać (i pozwolić na mapowanie) dobrze zaprojektowanego schematu relacyjnej bazy danych na dobrym modelu obiektowym. W rzeczywistości mamy jeszcze trochę do zrobienia, zanim wszystkie elementy układanki znajdą się na miejscu; chociaż wielu twórców map OR obsługuje zaawansowane mapowanie, często odbywa się to kosztem skomplikowanych zapytań i problemów z wydajnością.

Aby uzyskać dobrą wydajność db (i aby zachować zdrowie psychiczne dba :)) należy nadal postępować zgodnie z najlepszymi praktykami, jeśli chodzi o projektowanie schematu db; najpierw normalizuj i denormalizuj tam, gdzie jest to konieczne [/ jeśli]. Po stronie kodu nie przesadzaj z modelem obiektu ; nawet jeśli program odwzorowujący OR obsługuje złożone modele dziedziczenia i jednostki, które łączą wiele tabel razem, są to również obszary, w których ryzykujesz problemy z nadmiernie złożonymi zapytaniami trafiającymi do bazy danych itp. Profil, profil, profil, a nie tylko przyjmowanie ORM wygenerowane zapytania za pewnik. Należy pamiętać, że zapytania generowane przez program odwzorowujący OR można często modyfikować tak jak normalne zapytania SQL, a dwa funkcjonalnie równoważne zapytania po stronie obiektu (np. Zapytania linq) mogą czasami powodować bardzo różne zapytania SQL.

KristoferA
źródło