Czy MongoDB jest właściwym wyborem w moim przypadku? [Zamknięte]

9

Zamierzam zbudować swój pierwszy prawdziwy projekt w Railsach, który składa się z aplikacji internetowej złożonej z 3 głównych części:

  • Część statyczna, w której nie jest używana baza danych
  • Część rejestracji użytkownika, która będzie wymagać bazy danych i mogę używać MySQL, ponieważ każdy wiersz użytkownika będzie miał te same pola
  • „Aplikacja”, w której użytkownicy będą mogli tworzyć, organizować, edytować ... elementy w kolekcjach i udostępniać je innym użytkownikom

Będzie kilka typów elementów i każdy będzie miał inne opcje, na przykład mogę mieć elementy „wideo” z następującymi opcjami:

  • ID
  • identyfikator użytkownika
  • id_kolekcji
  • tytuł
  • platforma (jeśli jest osadzona)
  • adres URL (jeśli jest osadzony)
  • nazwa pliku (jeśli hostowany w mojej aplikacji)
  • rozmiar pliku (identyfikator hostowany w mojej aplikacji)

i elementy „mapy”:

  • ID
  • identyfikator użytkownika
  • id_kolekcji
  • tytuł
  • platforma (mapy google, mapy bing ...)
  • Lokalizacja
  • adres URL
  • rozmiar mapy

Jak możesz, podczas gdy dla użytkowników mogę używać MySQL dla przedmiotów, elastyczność MongoDB może być przydatna, ponieważ każdy element może wymagać innych opcji niż inny element

Do tej pory zawsze używałem PHP i MySQL (zawsze na współdzielonym hostingu dla małych projektów), a skalowalność to dla mnie zupełnie nowe słowo.

Mam czas na naukę, ale chciałbym móc zrobić coś konkretnego w ciągu 1 miesiąca.

Dużo czytałem o MongoDB i NoSQL kontra RDMS i MySQL i po wypróbowaniu muszę powiedzieć, że podoba mi się działanie MongoDB: brak tabel, wierszy i dokumentów JSON takich jak:

  • W mojej sytuacji, co byś polecił? dlaczego?
  • Jeśli chodzi o skalowalność, mogą występować problemy z MongoDB? jeśli tak, kiedy (pod względem rozmiaru DB) i czy problemy te mogą znacznie spowolnić moją aplikację?

Edycja: jak będzie działać aplikacja

Ponieważ wielu pytało o to, jak chciałbym, aby aplikacja działała:

  1. Rejestracja użytkownika
  2. On jest zalogowany
  3. Tworzy swoją pierwszą kolekcję na stronie, którą może tworzyć nieskończone przedmioty
  4. Elementy są różnego rodzaju i każdy typ potrzebuje różnych danych, aby zapisać w bazie danych, a typ elementów można dodawać lub modyfikować

Użytkownicy mogą tworzyć w nim inne kolekcje i przedmioty.

Mamy więc CRUD dla kolekcji i przedmiotów w nich zawartych, a każda kolekcja / pozycja jest skierowana do konkretnego użytkownika

Główny problem z MySQL polega na tym, że nie ma on elastycznego schematu, istnieje sposób na rozwiązanie tego (obejście?)?

Myśląc o NoSQL, jedyne wątpliwości, które mam, dotyczą przyłączenia, na przykład biorąc pod uwagę pewną kolekcję, chcę pobrać dane związane z użytkownikiem o polu id = identyfikator_użytkownika w kolekcji

EDYCJA: Pomysł, aby nadal używać MySQL

Utwórz pole w tabeli „przedmiotów” z opcjonalnymi ustawieniami, każde ustawienie podzielone przez | lub inny symbol.

Następnie zapiszę gdzieś strukturę opcjonalnych ustawień każdego elementu, na przykład typ elementu „notatki” potrzebuje dwóch opcjonalnych ustawień „kolor” i „dziwny_zestaw”, kiedy otrzymam dane z MySQL, podzielę pole dla opcjonalnych ustawień na tablica wiedząc, że pierwszy element w tablicy dotyczy „koloru” i tak dalej.

Co myślisz? czy jest problem z tym rozwiązaniem? masz inne pomysły?

Matteo Pagliazzi
źródło
4
Pytania Matteo dotyczące rekomendacji technologicznych są nie na temat, chyba że przedstawisz nam konkretny problem, który próbujesz rozwiązać. Musisz podać nam trochę więcej informacji na temat swojego projektu i tego, dlaczego uważasz, że musisz użyć innej bazy danych niż MySQL (z tą, którą znasz). Na przykład: Czy istnieją jakiekolwiek obawy dotyczące skalowalności i ile czasu potrzeba na badanie nowych technologii. Zastanów się nad poprawieniem pytania, a jeśli to zrobisz, oflaguj je, by zwrócić uwagę moderatora, abyśmy mogli przejrzeć Twoje zmiany.
yannis

Odpowiedzi:

10

Możemy nie być w stanie Ci pomóc, dopóki nie powiesz nam, co zamierzasz zrobić z aplikacją. Relacyjne bazy danych są dobre dla niektórych rzeczy, a bazy danych NoSQL są dobre dla innych.

Jak ktoś mi kiedyś powiedział tutaj na SO:

relacyjna część relacyjnej bazy danych jest znacznie bardziej zoptymalizowana niż niektóre inne części

Oznacza to, że możesz używać relacyjnej bazy danych również wtedy, gdy wydaje się to pasować do twoich przypadków użycia. Nie poprzestawaj na MongoDB ze względu na jego elastyczność / skalowalność. To jest pierwszy wiersz o MongoDB na Wikipedii:

MongoDB (z „humongous”) to oparty na dokumentach system baz danych NoSQL zorientowany na dokumenty.

Czy naprawdę zamierzasz używać bazy danych zorientowanej na dokumenty? Jeśli w twoich przypadkach użycia jest graficzność, możesz bardzo dobrze wybrać bazę danych grafów takich jak Neo4j. Lub możesz bardzo dobrze używać zarówno SQL, jak i NoSQL razem, jak niektórzy ludzie.

BTW, robię też projekt, w którym używam najlepszych części zarówno SQL, jak i NoSQL.

EDYCJA: Mówię jeszcze raz:

Sprawdź sekcję Neo4j vs Hadoop w tym artykule. To mówi:

Zasadniczo Hadoop i inne sklepy z kluczowymi wartościami dotyczą głównie stosunkowo płaskich struktur danych . Oznacza to, że są niezwykle szybkie i skalowalne w zakresie wyszukiwania prostych obiektów, takich jak wartości, dokumenty, a nawet obiekty.

Odnosząc się do tego samego artykułu, czy naprawdę potrzebujesz płaskiej struktury danych, dla której wybierasz MongoDB? To ostatecznie zależy od szczegółowych przypadków użycia, od tego, jak zostaną wykonane kroki 3 i 4.

Ponadto możesz odnieść się do następujących pytań:

/programming/2124274/mongodb-what-to-know-before-using

/programming/1476295/when-to-use-mongodb-or-other-document-oriented-database-systems

( Na pewno sprawdź najwyższą / wybraną odpowiedź drugiego pytania. Masz dylemat, który może to po prostu rozwiązać ).

Sądzę, że te pytania zawierają wszystkie informacje, które chciałeś poznać. Ostatecznie to Ty musisz zdecydować, czy jest to MongoDb, czy coś innego, możemy po prostu polecić. Jedynymi osobami, które znają Twoje szczegółowe przypadki użycia, są Ty i Twój zespół.

EDYTUJ PONOWNIE (dla części MySQL): Jak rozumiem, planujesz przechować coś w db i oddzielić je za pomocą separatora. To stwarza 2 problemy:

  1. Musisz dodatkowo obsługiwać wszelkie dane wejściowe, które będą miały separator.
  2. Część relacyjnej pamięci relacyjnej bazy danych jest znacznie bardziej zoptymalizowana niż część dopasowująca ciąg. Nie wybrałbym schematu, w którym muszę wykonać dopasowanie ciągów w bazie danych, aby uzyskać określony wynik. Ponownie podkreślam:

    relacyjna część relacyjnej bazy danych jest znacznie bardziej zoptymalizowana niż niektóre inne części (np. dopasowanie ciągów)

  3. Nie używaj atrybutów wielowartościowych. Ludzie na ogół się ich boją.
c0da
źródło
głównie zamierzałem użyć MongoDB do jego elastycznego schematu, ale mam pewne wątpliwości, ponieważ nie dołączył. W każdym razie w mojej aplikacji będę mieć bazę danych dla użytkowników, a następnie podstawowy interfejs, w którym każdy element jest powiązany z użytkownikiem i kolekcję elementów
Matteo Pagliazzi
Nie musisz dołączać do Mongo, ale musisz zaplanować swój schemat. Myśl w kategoriach przedmiotów zamiast tabel, jeśli używasz mongo. Zastanów się, jak uzyskasz dostęp do swoich obiektów.
ltfishie
8

Często widzę to pytanie. Zawsze wydaje się, że jest to uważane za albo. MongoDB to świetne nowe narzędzie. Czasami wydaje się to również błyszczącym narzędziem do wszystkiego i może to być zły wybór z mojego doświadczenia.

Myślę, że najlepsza kombinacja jest zdecydowanie ZARÓWNO i chciałbym pochwalić twoje podejście do korzystania z mylsql do niektórych części, takich jak użytkownicy, ale używaj MongoDB do innych części, ponieważ uważam, że uwierzytelnianie i autoryzacja najlepiej wykonywać za pomocą mySQL i są mnóstwo przykładów i modułów, które robią to naprawdę dobrze.

W przypadku kawałka „duża liczba elementów” warto rozważyć użycie mongoDB, jeśli wolumin jest duży i / lub w większości odczytuje i / lub zawiera nieustrukturyzowane dane.

Radziłbym nie opierać swojej decyzji na elastyczności Mongo bez schematu. Schematy SQL i SQL powstały z potrzeby posiadania uporządkowanych danych i możliwości wykonywania obliczeń i transformacji, które są możliwe tylko przy takiej strukturze. Nauczyłem się tego od 5 lat pracy w roli hurtowni danych. Chciałbym tylko spojrzeć na MongoBD w kwestii wydajności. Jeśli jesteś lub oczekujesz dużej liczby użytkowników i żądań, powiedzmy 100 000 użytkowników i 20 żądań na sekundę, użyłbym mongoDB, w przeciwnym razie spróbowałbym pozostać z sql. W wielu przypadkach używałbym mySQL do niewielkiego wolumenu, a następnie, gdy obsługują go wolumeny, przychody i infrastruktura, przestawiłem się na Oracle, zanim włączyłem mongoDB. Zgadzam się, że nie powinieneś próbować radzić sobie z problemami z woluminem, zanim ich doświadczysz, jednak jeśli masz dobry pomysł, dokąd zmierzasz i nie Jeśli chcesz ponownie napisać coś do połowy, warto wybrać odpowiednie technologie już na samym początku. Pamiętaj tylko, że jeśli naprawdę masz tak dużą głośność, na wszystkich poziomach stosu będzie ogromna liczba opcji i technologii, z których będziesz chciał skorzystać.

Luźno ustrukturyzowane dane mają swoje wady. Korzystam z analogii parkingu tutaj. żadna linia podziału nie jest świetna dla pierwszych 3 wjeżdżających samochodów, ale wraz ze wzrostem liczby wjeżdżających samochodów zaczyna się dziać dezorganizacja, a próby zaparkowania lub łatwego liczenia samochodów i pozostawienia wolnych pasów stają się koszmarem. Uporządkowanie tego wymaga pracy z przodu - wyznaczenie linii, dzielników i przepływów ruchu itp., Ale się opłaca. Czasami rzeczy się zmieniają (samochody stają się większe) i trzeba wprowadzić pewne zmiany - odmalować linie. Plus tylko standardowy czas przestoju dla corocznych napraw i konserwacji.

Aspekt projektowania schematu będzie prawdopodobnie największą przeszkodą dla tradycyjnych użytkowników mysql. Myślę, że strona MongoDb na temat projektowania schematów pomaga w tym. Moja ostatnia uwaga jest taka, że ​​każda technologia dodana do miksu zwiększa złożoność. Często są wielcy zwolennicy danego utworu, którzy powiedzą, że „musisz” go użyć, ale odkryłem, że naprawdę dużym czynnikiem jest to, ile jest kawałków. Implikuje to więcej możliwych punktów awarii, a przede wszystkim więcej wiedzy potrzebnej każdemu, kto będzie musiał wiedzieć, jak nad nią pracować.

fyi Rick Obsorne ma niesamowity schemat porównawczy, który jest dość wyjątkowy!

Michael Durrant
źródło
to mój pierwszy prawdziwy projekt w szynach: to hobby, a na razie nie wiem, czy to będzie sukces, czy porażka. Moim pierwszym celem jest zapoznanie się z szynami, aby nie mówić o ruchu. Odczyty nie będą najważniejsze, będę też miał wiele nowych danych i zaktualizowałem jeden ...
Matteo Pagliazzi,
1
fajną rzeczą w mongodb jest to, że nie ma ustalonego schematu, więc dla projektu hobbystycznego jest mniej prac konfiguracyjnych. Schemat może ewoluować wraz z upływem czasu i nie musisz robić dodatkowego kroku, aktualizując tabele SQL.
Kevin,
nie jestem pewien co do mojej -1 lub dlaczego 0 złych rad lub się nie zgadzam?
Michael Durrant
W każdym razie, jeśli jest to twój pierwszy projekt w szynach, trzymałbym się mySQL. W szynach jest wiele rzeczy do nauczenia, o wiele więcej niż 1 miesiąc, gdy zaczniesz odsuwać zasłony.
Michael Durrant
@ Michael
3

Widzę tutaj wiele poprawnych argumentów dla NoSQL kontra MySQL. Jedno brakujące łącze dotyczy jednak skalowania: jeśli chcesz naprawdę skalować i chcesz to zrobić przy użyciu własnej bazy danych, będziesz potrzebować DUŻEJ wiedzy na temat baz danych. Istnieje zbyt wiele horrorów, w których ludzie nie próbowali wdrożyć systemu, który będzie skalowany w nieskończoność.

Jeśli naprawdę zdecydujesz się na trasę NoSQL (i jesteś gotowy na ponoszenie związanych z tym kosztów - jak brak dołączeń), Zastanów się nad AWS DynamoDB (http://aws.amazon.com/dynamodb/). Tutaj możesz zapomnieć o skalowaniu całej bazy danych i skoncentrować się na swojej aplikacji. Powodzenia.

Oświadczenie: Jestem programistą w zespole AWS DynamoDB, ale naprawdę wierzę w nasz produkt. Wypróbuj to :)

Subu Sankara Subramanian
źródło
1

Twój projekt zapisuje w bazie danych dwa różne rodzaje obiektów:

  • Obiekt użytkownika (który zawsze ma pola).
  • Obiekty aplikacji (które mogą mieć różne pola). Aplikacja będzie należeć tylko do jednego użytkownika.

Kolekcja mogłaby mnie wykonać jako inny obiekt, podobnie jak tag służący do grupowania różnych aplikacji. Dla argumentu załóżmy, że nie ma żadnych kolekcji, a użytkownicy mają tylko listę aplikacji.

Chociaż myślę, że jest to możliwe do osiągnięcia w MySQL, w MongoDB będziesz mieć większą elastyczność pod względem struktury obiektów aplikacji i prawdopodobnie prawdopodobnie bardziej naturalnie odwzoruje twoją reprezentację w bazie danych, co uprości kod.

W MySQL będziesz miał problemy z obsługą różnych formatów dla różnych aplikacji, ale jest to możliwe. Jakieś pomysły:

  • Możesz utworzyć tabelę pośrednią ze wszystkimi wspólnymi informacjami między wszystkimi obiektami (identyfikator, identyfikator_użytkownika, tytuł itp.), A następnie typem, dzięki czemu możesz wyszukać ją w innej tabeli z tylko nietypowymi polami dla tego formatu (np. nazwa_pliku i rozmiar_pliku dla plików). Musisz utworzyć inną tabelę dla każdego innego formatu. Jeśli obie tabele są indeksowane przez app_id (klucz podstawowy), będzie to wystarczająco szybkie, ponieważ dostęp do tabeli za pomocą wartości indeksowanej jest szybki.
  • Możesz kodować dane w jakimś formacie i przechowywać w standardzie. Np. Zakoduj nietypowe dane w JSON jako ciąg i zapisz je w polu VARCHAR. Uważaj na wielkość tego pola, aby nie zabrakło miejsca. Format może być złożony (JSON) lub prosty (tylko wartości oddzielone przecinkami)
  • Możesz utworzyć różne „ogólne” pola, takie jak int1, int2, str1, str2, i zdefiniować, że str1 dla typu aplikacji to „nazwa_pliku”, a dla innego typu może to być „lokalizacja”.

Na MongoDB może to być tak proste, jak użycie dwóch kolekcji MongoDB, jednej dla użytkowników, a drugiej dla aplikacji. Zakładając pewien limit (co nie jest tak, jak to opisałeś, ale tylko dla powiedzenia), możesz nawet przechowywać aplikacje w obiekcie użytkownika, jako listę. Przechowywanie i wyszukiwanie danych jest bardziej naturalne, ponieważ możesz przechowywać dowolny rodzaj obiektu, bez względu na to, jakie pola. Możesz wyszukiwać według user_id, aby uzyskać wszystkie aplikacje należące do użytkownika. Na MongoDB i tak tracisz możliwość wykonywania zapytań dołączających, ale w tym przypadku myślę, że podstawowe zapytania będą pobierać użytkownika i aplikacje powiązane z tym użytkownikiem. Jeśli planujesz robić wiele rzeczy, takich jak „daj użytkownikom, którzy mają więcej niż dwie kolekcje z trzema aplikacjami lub mniej na każdej z nich”, musisz wygenerować to nie jako zapytanie o dołączenie, ale jako proces w kodzie i będzie mniej naturalny niż w relacyjnej bazie danych i może zająć więcej czasu. Jeśli chcesz wyszukać parametry (np. Daj mi wszystkie aplikacje należące do konkretnego użytkownika; daj mi wszystkie aplikacje typu X), na MongoDB jest to dość łatwe i nie trzeba używać złączeń.

Nie jestem pewien wsparcia MongoDB na Railsach. Używam go w Pythonie i JavaScript.

EDYCJA: Dodano komentarz na temat czasu dostępu do dwóch tabel i innej opcji MySQL

Khelben
źródło
nie podoba mi się druga opcja używania MySQL do przechowywania opcjonalnych ustawień, ponieważ myślę, że może załadować każdy wiersz z wieloma niepotrzebnymi bajtami ... dla drugiego: bardzo spowolni moją aplikację, aby załadować dwa wiersze z dwóch różnych tabel, aby załadować jeden przedmiot?
Matteo Pagliazzi,
proszę zobaczyć moją ostatnią aktualizację
Matteo Pagliazzi,
Jeśli chodzi o twoje pytanie dotyczące prędkości, nie powinno być dużo wolniejsze (uzyskujesz do niego dostęp poprzez indeksowaną unikalną wartość). Zredagowałem również swoją odpowiedź, ponieważ ostatnio edytowana propozycja jest podobna do pierwszego pomysłu i dodałem inną opcję.
Khelben
1

Powiedziałbym, że korzystasz z technologii, którą znasz najlepiej, zwłaszcza jeśli jest to prawdziwy projekt i chcesz go szybko wypchnąć. Korzystanie z MySQL i Mongo będzie miało swoje zalety i bóle głowy. Pracując z oboma, dodam również, że migracja z MySQL do Mongo nie jest bardzo trudna, jeśli przestrzegasz dobrych zasad projektowania.

Powiedziawszy to, jednym z dobrych powodów, aby wybrać MongoDB w twoim przypadku, są twoje dane. Jak już wspomniałeś, będziesz mieć kilka różnych typów wpisów do swoich kolekcji: mapa, wideo i tak dalej. Jeśli miałbyś wdrożyć to za pomocą RDBMS, masz 3 podejścia:

  • table-per-type: każda tabela zawiera kolumny specyficzne dla każdego typu obiektów

    Wady : N zapytanie do przeszukiwania wszystkich typów danych.

    Zalety : dobry projekt OO, łatwy w utrzymaniu

  • pojedyncza tabela: jedna ogromna tabela zawierająca wszystkie możliwe atrybuty dla wszystkich typów, przy czym większość z nich jest pusta dla każdego konkretnego wpisu

    Wady : Zmiana dowolnego obiektu będzie wymagać zmiany tabeli, co jest bolesne, gdy stół staje się duży. Trudne w utrzymaniu.

    Zalety : Łatwy do wdrożenia.

  • tabela podstawowa z metadanymi: masz pojedynczą tabelę z podstawowymi atrybutami, powiedzmy tytuł, daty i tabelę metadanych z parami klucz-wartość dla dodatkowych atrybutów

    Wady : Dwa zapytania, aby uzyskać wszystkie dane dla jednego obiektu.

    Zalety : wyjątkowo elastyczny, niezbyt trudny do wdrożenia.

Używałem każdego z tych podejść wcześniej i mogę powiedzieć, że żadne nie jest tak naturalne w pracy z Mongo. Twoje dane prawdopodobnie będą wyglądały mniej więcej tak:

{_id:"collection1",
 name:"My first Collection",
 owner: "user123243342",
 entries: [
    {type:"video",
     url: "http://www.youtube.com/234324",
     tags: ["roadtrip", "fun", "camera"]
     },
    {type:"map",
     coordinates: [LOC: [38, –102], LOC: [43, –33], LOC: [228, –102]],
     description: "Road trip to nowhere",
 ]
}

Ale tak naprawdę nie musisz się martwić o projekt schematu, ponieważ obiekty domeny można bezpośrednio utrwalić jako takie. MongoDB jest w zasadzie magazynem obiektów, o który możesz zapytać.

Zauważyłem, że pominąłem dyskusję na temat porównania wydajności między MySql i Mongodb. Chociaż zawsze powinieneś pamiętać o wydajności, nie będziesz w stanie skutecznie podejmować decyzji, chyba że znasz schemat dostępu do danych. Każdy dobry projekt prawdopodobnie przejdzie kilka iteracji refaktoryzacji w miarę rozwoju i pojawiania się nowych wyzwań. Nie martw się wydajnością przedwcześnie, wybierz narzędzie, które znasz najlepiej i zacznij kodować.

Edytować

Aby odpowiedzieć na konkretne pytanie dotyczące używania MySQL i utrzymywania atrybutów w tym samym polu za pomocą „|”. Nie rób tego Takie podejście daje więcej problemów niż rozwiązuje. Przede wszystkim nie będzie można wyszukiwać poszczególnych atrybutów za pomocą MySql. Po drugie, dodaje zbyt dużej złożoności do warstwy dostępu do danych. Zamiast tego należy zastosować metodę typu na tabelę lub metadane. Jeśli wcześniej pracowałeś z WordPress, używa on metadanych:

  • tabela użytkowników + usemeta dla użytkownika
  • stół postowy + słupek postmeta

To sprawia, że ​​struktura danych jest niezwykle elastyczna i nadal umożliwia zapytania z rozsądną szybkością.

ltfishie
źródło
nie podoba mi się opcja metadanych ... ale myślę nad pojedynczą tabelą z polami pozostawionymi
zerowymi,
Podejście z pojedynczym stołem jest prawdopodobnie najgorszym ze wszystkich. Chociaż możesz zrobić wszystko w jednym zapytaniu, każda zmiana dowolnego typu danych będzie wymagać tabeli zmian. I to jest mysql, kiedy twój stół staje się duży.
ltfishie
0

Poniższy artykuł zawiera dobre wyniki porównujące MySQL i MongoDB pod względem wyboru, pobierania i wstawiania, biorąc pod uwagę ilość danych w bazie danych i ilość pobranych danych. Wyniki pokazują świetne wyniki MongoDB w zakresie „wstawek”, ale w innych przypadkach MySQL wygrywa. Patrz poniżej:

http://www.moredevs.ro/mysql-vs-mongodb-performance-benchmark/

Miałem doświadczenie w korzystaniu z MongoDB, które uważam za dobre rozwiązanie. Użyłem go do wstawiania tysięcy kolekcji każdego dnia. W połączeniu z rozwiązaniem Solr (rozwiązanie pamięci podręcznej, aktualizowanym raz dziennie) mogę w razie potrzeby odzyskać dane MongoDB według identyfikatora kolekcji, więc nie muszę wybierać w locie. Biorąc pod uwagę, że masz do czynienia z wieloma wstawkami i nie musisz się martwić o wybranie i pobranie, MongoDB może być świetnym pomysłem, będzie to zależeć od każdego przypadku i zrobić dobrą analizę.

Rogerio Hilbert
źródło