MongoDB. Baza zorientowana w okół dokumentów. NoSQL. Schema-free.
09:23, 15 listopada 2010 roku
| Opinie, TechnologiaPróbując uruchomić Diasporę doznałem kilku olśnień. Głównym z nich było odkrycie MongoDB. Istnieje cała masa baz danych które powstały dzięki rozwojowi aplikacji WWW jak choćby “key->value store” używane przez Facebooka, a teraz prowadzone przez Apache pod nazwa Apache Cassandra Project. Mówiąc z perspektywy programisty WWW – bazy relacyjne nie wpasowują się w potrzeby moich aplikacji. Klientom dostarczam dokumenty, liczy się szybkość ich generowania. Rządzi XML. W końcu XHTML to jest XML. Dane są hierarchiczne i często ich struktury naturalnie są dynamiczne. Fajnie by więc było gdyby mogły w łatwy sposób być tak przechowywane. Tworzenie kilku tabel dla pięciu rekordów w bazie danych, gdy klient podał trzy numery telefonów zamiast jednego, jest olbrzymim (stosunkowo) narzutem pracy, logiki i skomplikowania. Ile razy widzieliście pola VARCHAR/TEXT w których dane były przechowywane po przecinku? No właśnie. Za dużo.
Dlatego wiele lat temu zakochałem się w PureXML serwowanym przez IBM DB2 od wersji 9.0 . A teraz porzucam moją starą miłość dla zupełnie nowej. Nie oszukujmy się, zmuszenie DB2 do działania według tego jak się chce, a nie jak baza chce, to jest katorga dla osoby która nie spędziła przynajmniej kilku miesięcy na kursach. Narzędzia do obsługi bazy są toporne i bolesne w użyciu. A narzut wiedzy który był mi potrzebny do wykonywania na niej operacji liczył około trzech tysięcy stron A4 (od instalacji, przez używanie do administracji). Nie chce nawet szacować ile czasu zajęło mi instalowanie tej bazy na serwerach i maszynie developerskiej za pierwszym razem.. drugim i kolejnymi trzema. Uczenie się DB2 przyniosło mi sporo wiedzy ogólnej, która przydaje mi się teraz od czasu do czasu, ale to nie jest godna rekompensata zużytego czasu.
Ale dość wstępu. W tym wpisie chcę się skupić na MongoDB, jako, że po kilku ładnych tygodniach testów różnych baz doszedłem do wniosku, że właśnie ten produkt najlepiej spełnia oczekiwania które mamy w Zeno.pl i te które można mieć przy pisaniu mocno obciążonych aplikacji. Z pewnością zbiorę się do napisania wniosków ogólnych dotyczących innych moich odkryć wyniesionych z Diaspory along the way. Ale póki co Mongo i jego NoSQL, Schema-free podejście do życia.
MongoDB
Baza oparta jest o JavaScript i JSON/BSON. Do wykonywania zapytań używa się składni JS i JSON, dane przechowywane są przy użyciu JSONa i BSONa (do danych binarnych). Próg wejścia jest więc znikomy dla każdego kto pisał jakąkolwiek interaktywna aplikację WWW. Jest to ogromny plus. Od instalacji do pierwszych zapytań minęło u mnie kilkanaście minut. Na stronie jest ciekawie zrobiony interaktywny tutorial, dokumentacja jest tworzona na bieżąco i można o niej powiedzieć, że jest kompletna.
Sama instalacja bazy jest prościutka – wystarczy swoim managerem paczek zassać i zainstalować bazę i klienta. Standardowa konfiguracja wystarcza do zabawy i testów. Sterowniki do PHP dostępne są z poziomu PECLa
sudo pecl install mongo
Na stronie podręcznika do PHP dostępny jest opis klas tego sterownika.
Baza jest w stu procentach dynamiczna.
Ma to swoje plusy i minusy. Bazy danych i kolekcje (odpowiedniki tabel) tworzone są dynamicznie – oznacza to, że baza nie krzyczy na nas za literówki. Jeżeli raz napiszemy
db.users.insert({"name": "Zenobius" });
(komenda wstawiająca dokument – odpowiednik rekordu – do kolekcji user z polem – kolumną - name która ma wartość “Zenobius”) to Mongo sprawdzi czy w używanej przez nas bazie jest już kolekcja users, jeżeli nie to ją utworzy. Gdy za drugim razem wpiszemy
db.usrs.find();
(komenda listująca wszystkie dokumenty z kolekcji usrs ) to Mongo nie nakrzyczy na nas, tylko wyświetli pusty zbiór wyników. Gdy wpiszemy
db.usrs.insert( {"name": "Zenobius" } );
to Mongo stworzy kolekcję usrs, wstawi do niej dokument z polem name o wartości Zenobius i będzie się cieszyć z dobrze wykonanego zadania.
Co ciekawe każdy dokument przy insercie dostaje generowany przez bazę identyfikator. Dotyczy to też sterowników do PHP – po wywołaniu inserta obiekt który dodawaliśmy dostaje automatycznie pole _id .
Kolekcje tworzone są dynamicznie. Jestem w stanie wyobrazić sobie godziny spędzone na szukaniu buga polegającego na zjedzeniu literki. Z drugiej strony nazwy kolekcji i baz danych powinny być trzymane w modelu lub pliku konfiguracyjnym i nie zmieniane – więc da się z tym żyć.
Aby stworzyć bazę danych wystarczy użyć polecenia
use <nazwa bazy>
i baza jest gotowa do użycia. Domyślnie przy użyciu wiersza poleceń ( mongo ) używana jest baza test .
Baza jest skalowalna horyzontalnie. Jest to niesamowicie proste do skonfigurowania – wystarczy kilka poleceń na poziomie roota i admina bazy.
Replikacja danych, podobnie jak skalowanie, jest bardzo łatwa do skonfigurowania. Bazę można z łatwością dostosować do swoich potrzeb. Można wymusić zapis na kilku serwerach. Z łatwością w trybie produkcyjnym można przełączać status master i slave, aby zrobić np. backup danych.
Używa UTF8 – tak jak powinien to robić każdy z nas.
Support i interakcja twórców ze społecznością i developerami jest świetna. Przykładem może być współpraca twórców MongoDB po wpadce foursquare opisana na łamach high scalability. Oczywiście twórcy bazy nie mogli sobie pozwolić na zły PR, ale poziom szczegółowości, otwartość i szybkość reakcji sprawiają, że jestem pod wrażeniem.
MongoDB Admin UI
Do MySQLa mamy phpMyAdmina, do Postgresa mamy pgAdmina, do DB2 jest DB2 Developer Workbench. Dla Mongo też jest kilka interfejsów. Ich opis, po angielsku, dostępny jest na blogu Tima, oraz na stronie MongoDB.
Osobiście używałem póki co tylko ob PHPowych, z których o wiele lepszy jest Opricot. Ale jeżeli ktoś z was ma ochotę pobawić się Pythonem lub Ruby i dać znać czy warto – to czekam na komentarze.
Na koniec jeszcze mały cheat-sheet SQL <-> Mongo.
Aplikacje Webowe muszą być dynamiczne. Musimy mieć też możliwość szybkiego wprowadzania w nich zmian aby wyprzedzać konkurencję. Próg wejścia dla Mongo jest niski – wystarczy kilka dni nauki i poruszamy się w jego środowisku swobodnie. Natomiast zyski z użycia Mongo wydają się być spore, jeżeli nie ogromne. Łatwość użycia, szybkość działania, łatwość konfiguracji replikacji i skalowania, prosta składnia – to wszystko rozwiązuje wiele problemów czy pytań które pojawiają się gdy używamy MySQLa czy Postgresa. Dynamiczna struktura dokumentów pozwala z łatwością zapisać w tej bazie wszystko. Fakt, że opiera się na JSON pozwala na bardzo łatwą manipulację danymi z poziomu PHP. Minusem jest mała dostępność bazy na hostingach i potrzeba migracji danych ze starej bazy i przepisanie całego modelu aplikacji. Natomiast jeżeli zaczynamy pisać coś zupełnie nowego to radzę poważnie zastanowić się nad MongoDB.