Denormalizacja

Pasek boczny 10.5

procent przetłumaczone

W tym rozdziale dowiesz się:

  • Denormalizacji.
  • Porównaniu bazy danych Mongo z tradycyjnymi relacyjnymi bazami danych.
  • W jakich przypadkach *nie* powinno się denormalizować danych.
  • Denormalizacja danych oznacza przechowywanie danych w formie innej niż “normalna”. Innymi słowy, denormalizacja oznacza posiadanie kilku kopii tych samych danych.

    W ostatnim rozdziale, zdenormalizowaliśmy licznik przechowujący liczbę komentarzy do obiektu posta aby zapobiec wczytywaniu za każdym razem wszystkich komentarzy. Dla przypadku modelowania danych jest to zbędne, ponieważ równie dobrze moglibyśmy policzyć zbiór komentarzy w dowolnej chwili, aby dostać tą wartość (pomijając wpływ na wydajność tego rozwiązania).

    Denormalizacja często oznacz dodatkową pracę dla developera. W naszym przypadku, za każdym razem gdy dodajemy lub usuwamy komentarz, musimy także pamiętać o uaktualnieniu odpowiedniego posta, aby upewnić się, że pole commentsCount ma prawidłową wartość. Jest to dokładnie przyczyna dlaczego relacyjne bazy danych, takie jak MySQL nie są przychylne takim praktykom.

    Jednakże normalne podejście do tego problemu ma także swoje minusy: bez pola commentsCount, potrzebowalibyśmy wysyłać wszystkie komentarze do klienta za każdym razem, tylko po to, aby je policzyć, czyli to co robiliśmy na początku. Denormalizacja pozwala uniknąć tego całkowicie.

    Specjalna publikacja

    Byłoby również możliwe utworzenie specjalnej publikacji, która wysyła wyłącznie liczniki komenterzy, którymi jesteśmy zainteresowani (tj. liczników komentarzy które aktualnie widzimy, za pomocą zapytań aggregate po stronie serwera).

    Jest to jednak warte rozważenia, jeżeli stopień skomplikowania kodu takiej publikacji byłby mniejszy, niż wysiłek włożony w denormalizację…

    Oczywiście takie rozważania są specyficzne dla konkretnych zastosowań: jeżeli piszesz kod, gdzie integralność danych jest najważniejsza, unikanie niezgodności danych ma większy priorytet niż strata na wydajności.

    Wstawianie dokumentów lub używanie wielu kolekcji

    Jeżeli jesteś zaawansowanym użytkownikiem Mongo, mogłeś się zdziwić, że utworzyliśmy drugą kolekcję tylko dla komentarzy: dlaczego po prostu nie wstawiać komentarzy do listy znajdującej się w dokumencie posta?

    Okazuje się, że dla wielu narzędzi które oferuje Meteor, pracowuje się lepiej gdy operujemy na poziomie kolekcji. Na przykład:

    1. Helper {{#each}} jest bardzo wydajny, jeżeli chodzi o iterację po kursorze (wyniku collection.find()). Nie jest to prawdą, gdy iteruje po tablicy objektów w środku większego obiektu.
    2. allow i deny operują na poziomie dokumentu, ułatwia to potwierdzenie, że jakiekolwiek modyfikacje pojedyńczych komentarzy są poprawne i obsługa byłaby bardziej skomplikowana na poziomie posta.
    3. DDP operuje na poziomie atrybutów dokumentu najwyższego poziomu – oznacza to, że jeżeli comments byłyby własnością post, za każdym razem, gdy komentarz byłby dodawany do posta, serwer musiałby wysyłać całą uaktualnioną listę komentarzy tego posta do wszystkich podłączonych klientów.
    4. Publikacje i subskrypcje można o wiele łatwiej kontrolować na poziomie dokumentów. Na przykład, jeżeli chcielibyśmy dzielić na strony komentarze do posta, byłoby to trudne do zrealizowania gdyby komentarze nie były umieszczone w odrębnej kolekcji.

    Mongo proponuje zagnieżdżanie dokumentów aby zredukować liczbę kosztownych zapytań o pobranie dokumentów. Jednakże nie należy się tym zbytnio przejmować biorąc pod uwagę architekturę Meteora: większość czasu pytamy o dokumenty po stronie klienta, gdzie dostęp do bazy danych jest właściwie darmowy.

    Wady denormalizacji

    Istnieje dobry argument na to, że nie należy denormalizować danych. Polecamy przeczytać Why You Should Never Use MongoDB autorstwa Sarah Mei, która przedstawia dobry przykład przeciwko denormalizacji.