Pracuję nad projektem hobby o nazwie Menu / Recipe Management.
Tak wyglądają moje byty i ich relacje.
A Nutrient
ma właściwości Code
iValue
An Ingredient
ma kolekcjęNutrients
A Recipe
ma kolekcję Ingredients
i czasami może mieć kolekcję innychrecipes
A Meal
ma kolekcję Recipes
iIngredients
A Menu
ma kolekcjęMeals
Relacje można przedstawić jako
Na jednej ze stron, dla wybranego menu muszę wyświetlić informacje o skutecznych składnikach odżywczych obliczonych na podstawie jego składników (posiłków, przepisów, składników i odpowiednich składników odżywczych).
W tej chwili używam SQL Server do przechowywania danych i nawiguję łańcuch z mojego kodu C #, zaczynając od każdego posiłku w menu, a następnie agregując wartości odżywcze.
Myślę, że nie jest to skuteczny sposób, ponieważ obliczenia są przeprowadzane za każdym razem, gdy strona jest żądana, a składniki czasami się zmieniają.
Myślałem o posiadaniu usługi w tle, która utrzymuje tabelę o nazwie MenuNutrients ( {MenuId, NutrientId, Value}
) i będzie wypełniać / aktualizować tę tabelę skutecznymi składnikami odżywczymi, gdy którykolwiek ze składników (posiłek, przepis, składnik) zmieni się.
Wydaje mi się, że GraphDB dobrze pasuje do tego wymogu, ale moja ekspozycja na NoSQL jest ograniczona.
Chcę wiedzieć, jakie są alternatywne rozwiązania / podejścia do tego wymogu wyświetlania składników odżywczych w danym menu.
Mam nadzieję, że mój opis scenariusza jest jasny.
źródło
Odpowiedzi:
W zależności od wymagań i architektury mogą istnieć opcje poprawy wydajności:
Możesz użyć widoków indeksowanych (zmaterializowanych) Aby poprawić wydajność odczytu na poziomie RDBMS (serwer Sql).
Zasadniczo wszystko, co musisz zrobić, to:
Utwórz zwykły widok.
Utwórz indeks klastrowany w tym widoku .
Korzystanie z mechanizmu płatności na poziomie aplikacji poprawi wydajność.
Jeśli jest to możliwe i wykonalne, skorzystaj z strategii gotówkowej, takiej jak singleton leniwa gotówka .
NoSql:
Istnieje wiele dobrych artykułów na temat Sql vs NoSql, takich jak ten i ten
Części mnie interesują:
Gdzie używać NoSql:
Po użyciu należy być gotowym do:
Przy podejmowaniu decyzji o użyciu lub nie używać NoSQL, pomocny artykuł na NoSQL DBMS porównanie i zamiaru z nich można znaleźć tutaj , ponieważ niektóre z nich skupiają się na wysokiego brzmi low pisze map-reduce, HA ...
zaglądając w rankingu i popularności , według kategorii mogą być przydatne.
źródło
W rzeczywistości nie musisz używać db db wykresu, po prostu przechowuj wymagane wartości na jednym wyższym poziomie. To jest jak przechowywanie
Order
iOrderItems
. nie musisz obliczać sumy za każdym razem, gdy zamówienie ma zostać wyświetlone. Zamiast tego po prostu obliczasz sumę, VAT i inne rzeczy i przechowujesz je ze sobąOrder
.źródło
Sugeruję przyjrzeć się wzorowi podziału odpowiedzialności za zapytania dowodzenia .
Zasadniczo zamiast tworzyć jeden model do odczytu i zapisu, można utworzyć 2 różne modele. Jeden zoptymalizowany pod kątem aktualizacji, a drugi zoptymalizowany pod kątem zapytań (odczyt, raportowanie ...). Dwa modele są zsynchronizowane (zwykle z ewentualną spójnością) przy użyciu zdarzeń domenowych (patrz DDD).
Zacząłem studiować ten wzór kilka miesięcy temu i to naprawdę zmieniło mój sposób modelowania oprogramowania. Nie jest to łatwe, ponieważ jest to duża zmiana, szczególnie w połączeniu z innymi technikami, takimi jak DDD i Event Sourcing. Ale warto.
Istnieje wiele zasobów dostępnych w sieci, szukaj CQRS i DDD (i ewentualnie Sourcing zdarzeń).
Tego wzorca można używać zarówno w SQL, jak i noSql.
W twoim przypadku możesz uruchomić zdarzenie za każdym razem, gdy zmieniane są składniki odżywcze, aby zaktualizować model odczytu, który jest zoptymalizowany do odczytu. Model odczytu może być na przykład zdenormalizowanym widokiem składników odżywczych menu (dlaczego nie używać db nosql do wydajnego odczytu). Możesz mieć wiele modeli odczytu opartych na zapytaniach, które musisz wykonać.
Takie podejście ma pewne implikacje, ale jest ono bardzo skalowalne i rozszerzalne.
źródło
Zależy to w dużej mierze od tego, jak początkowo uzyskać menu i składniki odżywcze. Jak myślisz, dlaczego to nie będzie skuteczne?
Z tego, co rozumiem, idziesz do DB, dostajesz menu, a następnie idziesz ponownie, dostajesz każdy przepis, a następnie idziesz ponownie i dostajesz każdy składnik i tak dalej. Jest to naprawdę nieefektywne, ponieważ istnieje wiele zapytań i podróży w obie strony do serwera, który jest głównym źródłem opóźnień. Jest to znane jako problem WYBIERZ N + 1.
To, co powinieneś zrobić, to pobrać wszystkie dane w jednym zapytaniu, używając
JOIN
s dla wszystkich tabel od menu aż do składników odżywczych, aby serwer DB mógł użyć wszystkich relacji i indeksów, aby uzyskać wszystkie dane naraz. Aplikacja kliencka C # przetwarza tylko i wyświetla wynik końcowy. Jest to o wiele bardziej wydajne niż przechodzenie jeden po drugim.Zasadniczo, stosując odpowiednie techniki zapytań i odpowiednie indeksy dla zapytań krytycznych, relacyjne bazy danych mogą bardzo dobrze działać na dużych tabelach pod obciążeniem.
źródło
JOIN
s, które nie powinny stanowić obciążenia dla serwera (chyba że mówimy o pobieraniu setek lub tysięcy wierszy), jeśli właściwe indeksowanie jest na miejscu. Nawet w przypadku dużych zbiorów danych zawsze możesz zbudować widok dla całego wyniku, a nawet zindeksować widok, aby wynik był wstępnie obliczony, jeśli wydajność kiedykolwiek stanie się problemem.Wygląda na to, że poświęciłeś trochę czasu na zastanowienie się, jak najlepiej modelować dane, aby można je było łatwo aktualizować i uzyskiwać zapytania. Jednak teraz jesteś w punkcie, w którym musisz zapewnić dostęp do danych. Te dwie rzeczy stanowią odrębne obawy.
Wspomniałeś, że ponowne załadowanie strony powoduje nowe zapytanie do bazy danych. Wspominasz również, że baza danych będzie od czasu do czasu aktualizowana i kiedy chcesz, aby aktualizacje te były wyświetlane na stronie w odpowiednim czasie. Najlepszą metodą zmniejszenia obciążenia związanego z zapytaniami jest ich nie robienie. Jeśli ciągle uruchamiasz te same zapytania i uzyskujesz te same wyniki, dlaczego nie buforujesz ich przez chwilę? Powinieneś być w stanie zaimplementować buforowanie w górę, bez modyfikowania reszty projektu. Poleciłbym przeczytać o odpoczynku. Niezależnie od tego, czy projekt zostanie wdrożony w rdbms lub nosql, problemy z wydajnością tego typu najlepiej rozwiązywać, zmniejszając liczbę razy, kiedy trzeba przejść do bazy danych. Załóżmy, że masz 100 próśb o ten sam przepis w 60 sekund. Jeśli buforujesz przez 60 sekund, trafiasz do bazy danych tylko raz, co oznacza 100-krotną poprawę wydajności. Aby zobaczyć ten sam poziom poprawy po przejściu na nosql, będzie wymagało dużo więcej pracy.
Systemy typu Nosql mogą być świetnym rozwiązaniem, gdy masz ogromne ilości danych lub ekstremalne wymagania dotyczące prędkości odczytu lub zapisu. Jednak ta dodatkowa wydajność wiąże się z kosztem wyrzucenia takich rzeczy, jak integralność referencyjna.
źródło
Wydaje się, że do celów eksperymentu lub wiedzy chcesz wypróbować Graph-DB, ale twój przykład jest wyraźnie przykładem danych hierarchicznych, w których możemy Drill-Down / Up przez węzeł. Nie jestem ekspertem od Graph / Neo DB, ale widzę, że nie ma dużej złożoności w sposobie, w jaki użytkownik / możesz żądać danych z tego schematu. Widzę, że wybór projektu bazy danych / schematu jest bardzo zależny od tego, w jaki sposób i jakiego rodzaju dane będą do niego kierowane. Podczas korzystania z SQLSERVER „Hierarchia I” D jest z mojego punktu widzenia najlepszą opcją umieszczenia tych węzłów jako części drzewa.
źródło
Proponuję myśleć jak maszyna, a nie jak człowiek. Może się to wydawać powtarzalne, ale w tym, w czym są dobre maszyny. Jedną z rzeczy, które musisz sobie zadać, jest: „czy mimo wszystko muszę pobrać każdy obiekt, aby wyświetlić go na mojej stronie?” Jeśli tak, kontynuuj to, co robisz, w porównaniu do pobierania danych, cykle procesora są pomijalne podczas wykonywania prostej matematyki.
źródło