codefather.pl

... by Tadeusz Wójcik

komentarze

No Sql No Problem, czyli MongoDB, NoRM i .NET .

     Pierwsze relacyjne bazy danych powstały w  latach ‘70 ubiegłego wieku, na długo przedtem nim języki programowania zorientowane obiektowo stały się popularne. Obecnie są standardem jeśli chodzi o mechanizm persystencji w programowaniu obiektowym. 

     Jednak o tym, że translacja obiektowego modelu na relacyjny jest  bardzo często procesem karkołomnym, nieprzyjemnym i błędogennym wielu z nas z pewnością doświadczyło na własnej skórze. Jest tak ponieważ model obiektowy z natury hierarchiczny nijak się ma do sztywnej struktury relacyjnej bazy danych (impedance mismatch). Nie zmienia to jednak faktu, że współpraca z RDBMS’ami stanowi i pewnie jeszcze długo stanowić będzie integralną część pracy większości programistów.

     Możemy i powinniśmy korzystać z wszelakiej maści ORM’ów, pozwalających nam mapować obiektowy model na relacyjny, tworzących niejako “wirtualną obiektową bazę danych” bedącą pewnym rodzajem abstrakcji “nałożonym” na bazę relacyjną. Jednakże i one nie są złotym lekarstwem, często stwarzają problemy wydajnościowe ( select n+1, rozległe joiny itp.) i wymagają dużej wiedzy od programisty (lazy loading, zarządzanie sesją itp.).

    A czy nie chciał byś po prostu  nie myśleć o bazie danych? Nie musieć przejmować się ciągłymi migracjami, problemami z wydajnością, normalizacją? Echhhh, gdyby tylko się tak dało, ale dane trzeba gdzieś przechowywać. Potrzebujemy jednak czegoś prostego w użyciu, a jednocześnie wydajnego i stabilnego.

    Poniżej przedstawiony jest bardzo prosty przykład użycia MongoDB wraz z NoRM w aplikacji .NET. (jeśli nie wiesz co oznaczają te tajemnicze nazwy, nic się nie martw-wyjaśnię wszystko za chwilę)

Zdefiniujmy dwie klasy Post i Comment  :

 
 public class Post
    {
        public string AuthorName { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
        public IList<Tag> Tags{ get; set; }
        public IList<Comment> Comments { get; set; }

    }
    public class Comment
    {
        public string Body { get; set; }
        public string AuthorName { get; set; }
    }

    Tworzymy nowego posta wraz z dwoma komentarzami:

 

 var post=new Post()
              {
                    AuthorName="Codefather"
                    Title= "No Sql No problem",
                    Body = "Some text",
                    Tags = new List<string> {".Net", "c#", "nosql"}
              };

 var rdbmsDefenderComment = new Comment()
                            {
                                  AuthorName = "Rdbms defender",
                                  Body = "nosql sucks"
                            };

 var noSqlDefnederComment = new Comment()
                                    {
                                        AuthorName = "NoSql defender",
                                        Body = "nosql is great"
                                    };

            post.Comments=new List<Comment>
                              {
                                  rdbmsDefenderComment,
                                  noSqlDefnederComment
                              };

   Teraz trzeba naszego świeżo stworzonego posta trzeba jakoś zapisać. Nic prostszego:

using (var mongo = Mongo.Create("mongodb://localhost/CodefatherDB"))
{
   mongo.GetCollection<Post>().Insert(post);
}

   Powyższy kod robi trzy rzeczy:

  • tworzy bazę danych o nazwie CodefatherDB
  • tworzy kolekcję Post’ów (kolekcja to odpowiednik tabeli w MongoDB) 
  • dodaje stworzonego przez nas Post’a do tej kolekcji.

Teraz czas na “wyciągnięcie” naszego posta z bazy danych:

var retrievedPosts = mongo.GetCollection<Post>().AsQueryable()
                                                                             .Where(p => p.Title == "No Sql no problem")
                                                                             .SingleOrDefault();

   Powyższy przykład jest bardzo prosty i zrozumiały (mam nadzieję), obrazuje jednocześnie jak łatwe i przyjemne jest korzystanie MongoDB.

Ale czym MongoDB właściwie jest ?


    MongoDB to opensource’owa skalowalna (auto-sharding), wydajna (nawet bardzo wydajna), dokumentowa baza danych napisana w C++. Mimo swojego młodego wieku (tworzona jest od 2007 roku) zyskała sobie uznanie wielu ważnych graczy internetowego rynku tj: New York Times, SourceForge, FourSquere Github i co ciekawe wielki zderzacz hadronów w CERN pod Genewą (a raczej jego oprogramowanie-więcej informacji).

    MongoDB przechowuje dane (dokumenty) w kolekcjach. Dokumenty to tak naprawdę obiekty JSON (a właściwie BSON), więc można w nich przechowywać bardziej skomplikowane dane (w porówaniu do tabel w RDBMS’ach), tj. inne obiekty (tzw. embedded documents), tablice czy słowniki. Modelowanie danych staje się dzięki temu bardziej naturalnym procesem, dając nam dużą swobodę.

   Tak wygląda wcześniej zapisany nasz post w formacie JSON (w relacyjnej bazie danych były by to zapewne 3 tabele: posty, komentarze i tagi ):

{ Title : “No Sql no problem”, AuthorName: “CodeFather”, Body: “Some text”,

  comments : [{ AuthorName: ““Rdbms defender”, Body: “nosql sucks” },

              { AuthorName : “NoSql defender”, Body: “nosql is great” } ],

tags:[{“.Net”, “c#”, “nosql”}]

}

   MongoDB oferuje również dynamiczne tworzenie baz danych i kolekcji dokumentów,a brak schematu bazy, oznacza koniec problemów z migracjami. 

    Poniższy diagram doskonale obrazuje, gdzie plasuje się MongoDB na tle innych rozwiązań bazodanowych. 

Instalacja MongoDB: czyli szybko sprawnie i bezproblemowo .

1. Pobieramy najnowszą wersję bazy stąd (uwaga: dla systemów 32bit maksymalny rozmiar bazy wynosi 2GB)

2. Rozpakowujemy do dowolnego katalogu na dysku.

3. W katalogu bin znajduje się mongod.exe , który poprostu odpalamy i w tym momencie nasz serwer bazodanowy już działa ! . Jeśli chcemy, MongoDB można bezproblemowo zainstalować jako serwis. 

4. Domyślnie pliki z danymi MongoDB przechowuje w c:\data\db, więc jeśli nie mamy takiego katalogu to musimy go utworzyć lub przy uruchamianiu mongod.exe podać inną ścieżkę (––dbpath [path].)W tym momencie możemy odpalić shella (mongo.exe) i tworzyć z jego poziomu bazy,kolekcje, dokumenty, pisać zapytania itp. Nie jest to jednak zbyt wygodne, nie mówiąc już o współpracy z innymi językami.

  Projekt NoRM (No Object-Relational Mapping)

   NoRM jest biblioteką, pozwalającą na współpracę z MongoDB z poziomu .NET’a.

Główne jej cechy to :

  • silnie typowanie,
  • wsparcie dla Linq
  • Automatyczna serializacja/deserializacja do formatu BSON
  • łatwość użytkowania
  •  szybkość

   Dzięki NoRM i MongoDB, nie ma potrzeby mapowania modelu obiektowego na inny, ponieważ struktura dokumentowa MongoDB jest bardzo zbliżona do struktury obiektowej. W skrócie: Obiekt ~ Dokument.

     Dla mnie najważniejszą zaletą MongoDB i NoRM jest łatwość użycia- to poprostu działa! I to szybkoooooooo !!! Raz spróbujesz i już zawsze będziesz patrzeć na SQL’a z obrzydzeniem :)

      Niestety mongoDB nie jest lekarstwem na wszystko. Nie wspiera transakcji w obrębie kilku dokumentów jednocześnie. Jeśli więc planujesz stworzyć np. system bankowy MongoDB może nie być najlepszym wyborem. Zachęcam do zapoznania się z Use Cases dla tej bazy.

   Tyle tytułem wstępu. W przyszłości postaram zagłębić się w szczegóły i pokazać bardziej zaawansowane przykłady w oparciu o NoRM :)

kategorie:   #MongoDB#.net#NoRM


Wrzuć linka u siebie:


  1. codefather posted this