Próbuję znaleźć odpowiednik kluczy obcych i indeksów w bazach danych NoSQL KVP lub Document. Ponieważ nie ma tabel przestawnych (do dodawania kluczy oznaczających relację między dwoma obiektami), jestem naprawdę zaskoczony, w jaki sposób można byłoby odzyskać dane w sposób, który byłby przydatny dla normalnych stron internetowych.
Powiedzmy, że mam użytkownika, który zostawia wiele komentarzy w całej witrynie. Jedynym sposobem, w jaki mogę wymyślić, aby śledzić komentarze użytkowników, jest
- Osadź je w obiekcie użytkownika (co wydaje się całkiem bezużyteczne)
- Utwórz i utrzymuj
user_id:comments
wartość zawierającą listę kluczy każdego komentarza [komentarz: 34, komentarz: 197, itd.], Abym mógł je pobrać w razie potrzeby.
Jednak biorąc pod uwagę drugi przykład, wkrótce trafisz na mur z cegły, gdy użyjesz go do śledzenia innych rzeczy, takich jak klucz o nazwie „active_comments”, który może zawierać 30 milionów identyfikatorów, co sprawia, że zapytanie każdej strony kosztuje TONĘ aktywne komentarze. Byłby również bardzo podatny na warunki wyścigowe, ponieważ wiele stron może próbować aktualizować go w tym samym czasie.
Jak mogę śledzić relacje, takie jak poniższe, w bazie danych NoSQL?
- Wszystkie komentarze użytkownika
- Wszystkie aktywne komentarze
- Wszystkie posty oznaczone [słowo kluczowe]
- Wszyscy uczniowie w klubie - lub wszystkie kluby, do których należy uczeń
A może źle o tym myślę?
źródło
Odpowiedzi:
Wszystkie odpowiedzi na pytanie, jak przechowywać asocjacje „wiele do wielu” w sposób „NoSQL” sprowadzają się do tego samego: nadmiarowego przechowywania danych.
W NoSQL nie projektujesz bazy danych na podstawie relacji między jednostkami danych. Projektujesz swoją bazę danych na podstawie zapytań, które będziesz wykonywać względem niej. Użyj tych samych kryteriów, których użyłbyś do denormalizacji relacyjnej bazy danych: jeśli ważniejsze jest, aby dane były spójne (pomyśl o wartościach na liście oddzielonej przecinkami zamiast o znormalizowanej tabeli), zrób to w ten sposób.
Ale to nieuchronnie optymalizuje się dla jednego rodzaju zapytań (np. Komentarze dowolnego użytkownika do danego artykułu) kosztem innych typów zapytań (komentarze do dowolnego artykułu danego użytkownika). Jeśli Twoja aplikacja wymaga jednakowej optymalizacji obu typów zapytań, nie powinieneś denormalizować. Podobnie, nie powinieneś używać rozwiązania NoSQL, jeśli chcesz używać danych w sposób relacyjny.
Istnieje ryzyko, że w przypadku denormalizacji i nadmiarowości zbędne zestawy danych nie będą ze sobą zsynchronizowane. Nazywa się to anomalią . Kiedy używasz znormalizowanej relacyjnej bazy danych, RDBMS może zapobiegać anomaliom. W zdenormalizowanej bazie danych lub w NoSQL odpowiedzialność za pisanie kodu aplikacji w celu zapobiegania anomaliom spoczywa na użytkowniku.
Można by pomyśleć, że byłoby wspaniale, gdyby baza danych NoSQL wykonała ciężką pracę polegającą na zapobieganiu anomaliom za Ciebie. Jest paradygmat, który może to zrobić - paradygmat relacyjny.
źródło
Podejście couchDB sugeruje, aby emitować odpowiednie klasy rzeczy w fazie mapy i podsumowywać je w reduktorze. Tak więc możesz zmapować wszystkie komentarze i emitować
1
dla danego użytkownika, a później wydrukować tylko te. Wymagałoby to jednak dużej ilości miejsca na dysku, aby zbudować trwałe widoki wszystkich danych możliwych do śledzenia w CouchDB. btw mają również tę stronę wiki o związkach: http://wiki.apache.org/couchdb/EntityRelationship .Z drugiej strony Riak ma narzędzie do budowania relacji. To jest link. Możesz wprowadzić adres powiązanego (tutaj komentarza) dokumentu do dokumentu „root” (tutaj dokument użytkownika). Ma jedną sztuczkę. Jeśli jest rozpowszechniany, może być modyfikowany jednorazowo w wielu lokalizacjach. Spowoduje to konflikty iw rezultacie ogromne drzewo zegara wektorowego: / ..nie tak źle, nie tak dobrze.
Riak ma też jeszcze jeden „mechanizm”. Posiada 2-warstwową przestrzeń nazw kluczy, tzw. Bucket and key. Na przykład, jeśli mamy klub A, B i C oraz studenta StudentX, StudentY, możesz zachować następującą konwencję:
i aby odczytać relację, po prostu wypisz klucze w podanych zasobnikach. Co z tym jest nie tak? Jest cholernie wolno. Rzemiosło nigdy nie było priorytetem. Mimo to jest coraz lepiej. przy okazji. nie marnujesz pamięci, ponieważ ten przykład
{true}
może być powiązany z jednym pełnym profilem Studenta X lub Y (tutaj konflikty nie są możliwe).Jak widzisz NoSQL! = NoSQL. Musisz przyjrzeć się konkretnej implementacji i samodzielnie ją przetestować.
Wspomniane wcześniej magazyny kolumnowe wyglądają na dobrze dopasowane do relacji… ale wszystko zależy od Twoich potrzeb A, C i P;) Jeśli nie potrzebujesz A i masz mniej niż Peta bajtów, po prostu zostaw to, śmiało z MySql lub Postgres.
powodzenia
źródło
user: userid: comments jest rozsądnym podejściem - potraktuj to jako odpowiednik indeksu kolumny w SQL, z dodatkowym wymogiem, że nie możesz wykonywać zapytań dotyczących niezindeksowanych kolumn.
Tutaj musisz pomyśleć o swoich wymaganiach. Lista zawierająca 30 milionów pozycji nie jest nierozsądna, ponieważ jest powolna, ale ponieważ jest niepraktyczne, aby cokolwiek z nią zrobić. Jeśli Twoim prawdziwym wymaganiem jest wyświetlenie kilku ostatnich komentarzy, lepiej przechowywać bardzo krótką listę, która jest aktualizowana za każdym razem, gdy dodawany jest komentarz - pamiętaj, że NoSQL nie ma wymagań normalizacji. Warunki wyścigu są problemem w przypadku list w podstawowym magazynie wartości kluczy, ale generalnie albo twoja platforma prawidłowo obsługuje listy, możesz zrobić coś z blokadami, albo tak naprawdę nie przejmujesz się nieudanymi aktualizacjami.
Tak samo jak w przypadku komentarzy użytkowników - utwórz indeksowe słowo kluczowe: posty
Więcej tego samego - prawdopodobnie lista klubów jako własność studenta i indeks na tym polu, aby uzyskać wszystkich członków klubu
źródło
Ty masz
Cóż, w relacyjnej bazie danych normalną rzeczą do zrobienia w relacji jeden do wielu jest normalizacja danych. To jest to samo, co zrobiłbyś w bazie danych NoSQL. Po prostu zindeksuj pola, z których będziesz pobierać informacje.
Na przykład ważne dla Ciebie indeksy to
Jeśli korzystasz z NosDB (bazy danych NoSQL opartej na platformie .NET z obsługą SQL), Twoje zapytania będą wyglądać następująco
Sprawdź wszystkie obsługiwane typy zapytań w ich ściągach SQL lub w dokumentacji.
źródło