Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:dydaktyka:ztb:2010:projekty:nosql_couch:start [2010/06/30 01:09] ztb2010 |
pl:dydaktyka:ztb:2010:projekty:nosql_couch:start [2010/07/06 23:33] ztb2010 |
snanek //posiadający konto w domenie// gmail.com | snanek //posiadający konto w domenie// gmail.com |
| |
//Wstępna wersja wstępu do projektu.// | ====== Wstęp ====== |
| |
| CouchDB to nierelacyjny, zorientowany na dokumnety, system zarządzania bazami danych, napisany w języku Erlang, nastawiony na wysoką dostępność (wykorzystanie algorytmu Map/Reduce) i replikowalność danych (automatyczna replikacja). W przeciwieństwie do systemów relacyjnych, pojedynczy rekord nie jest związany z określoną strukturą danych - zamiast tego ma on postać tablicy haszującej zapisanej w formacie JSON, w której wartości mogą być dowolnego typu prostego - w tym także typu tablicowego. |
| |
| W świecie oprogramowania komercyjnego, mimo stosunkowo niskiego numeru wersji (0.10), system ten zyskuje coraz większą popularność. Stosują go m.in. Engine Yard, czy nawet BBC [9]. Obecnie (czerwiec 2010), trwają prace edytorskie nad pierwszymi wydaniami książek pomocnych w nauce i zrozumieniu CouchDB. |
====== Praca z CouchDB ====== | ====== Praca z CouchDB ====== |
| |
1. Instalacja pakietu CouchDB w systemie operacyjnym GNU/Linux Ubuntu: | Instalacja pakietu CouchDB w systemie operacyjnym GNU/Linux Ubuntu: |
| |
''$sudo aptitude install couchdb'' | ''$sudo aptitude install couchdb'' |
| |
2. Uruchomienie CouchDB z poziomu konta superużytkownika: | Uruchomienie CouchDB z poziomu konta superużytkownika: |
| |
''$ sudo couchdb'' | ''$ sudo couchdb'' |
| |
''Apache CouchDB is running as process 31654. Time to relax.'' | ''Apache CouchDB is running as process 31654. Time to relax.'' |
| |
Alternatywnie, można program uruchamiać z poziomu konta zwykłego użytkownika, wcześniej upewniając się, że użytkownik będzie miał dostęp do zapisu w katalogu /var/lib/couchdb/0.8.0 (lub innym, odpowiadającym ustawieniom CouchDB i lokalnemu środowisku systemowemu). | Alternatywnie, można program uruchamiać z poziomu konta zwykłego użytkownika, wcześniej upewniając się, że użytkownik będzie miał dostęp do zapisu w katalogu /var/lib/couchdb/0.8.0 (lub innym, odpowiadającym ustawieniom CouchDB i lokalnemu środowisku systemowemu). |
| |
3. Sprawdzenie poprawności instalacji | Sprawdzenie poprawności instalacji |
| |
| |
3.a. Z konsoli | Z konsoli: |
| |
''$curl -X PUT http://127.0.0.1:5984/albums'' | ''$curl -X PUT http://127.0.0.1:5984/albums'' |
| |
''{"ok":true}'' | ''{"ok":true}'' |
| |
3.b. Przy użyciu przeglądarki internetowej | Przy użyciu przeglądarki internetowej: |
| |
Wejście na stronę www: | Wejście na stronę www: |
''{"couchdb":"Welcome","version":"0.8.0-incubating"}'' | ''{"couchdb":"Welcome","version":"0.8.0-incubating"}'' |
| |
====== Podsumowanie ====== | W domyślnej instalacji serwera CouchDB znalazło się także miejsce na wizualny panel administracyjny. Dostęp do niego można uzyskać, wchodząc pod adres: |
| |
| ''http://localhost:5984/_utils/'' |
| ====== Praca z danymi ====== |
| W CouchDB istnieje możliwość wyszukiwania i agregowania danych. |
| |
| Przykładowo, aby wyszukać dokuemnty, których wartość parametru "test" równa się "titletest", należy po utworzeniu widoku ''test'' o treści: |
| |
| <code javascript> |
| function(doc) |
| { |
| if(doc.test == "titletest") |
| { |
| emit( doc.test, doc ); |
| } |
| } |
| </code> |
| |
| i wejściu na adres: |
| |
| ''http://localhost:5984/testdb/_view/test/tt?count=10&group=true'' |
| |
| Otrzymujemy następujący rezultat: |
| |
| <code javascript> |
| {"total_rows":1,"offset":0,"rows":[ |
| {"id":"test","key":"titletest","value":{"_id":"test","_rev":"1510238268","test":"titletest","title":"tretete"}} |
| ]} |
| </code> |
| |
======= Zalety ======= | ======= Zalety ======= |
* wersjonowanie dokumentów dostępne "od ręki" | * wersjonowanie dokumentów dostępne "od ręki" |
* komunikacja poprzez łatwy w implementacji i wykorzystaniu protokół http (mechanizm REST [2]) | * komunikacja poprzez łatwy w implementacji i wykorzystaniu protokół http (mechanizm REST [2]) |
* dane przekazywane w "lekkiej" formie plików YAML | * dane przekazywane w "lekkiej" formie plików JSON |
| * brak sztywnej struktury danych - o formacie przechowywanej informacji decyduje użytkownik systemu (programista) w chwili tworzenia lub aktualizacji wpisu |
======= Wady======= | ======= Wady======= |
| |
* konieczność budowania własnych rozwiązań, które mają na celu zabezpieczanie nieautoryzowanego dostępu do bazy danych | * konieczność budowania własnych rozwiązań, które mają na celu zabezpieczanie nieautoryzowanego dostępu do bazy danych |
* trudności z łączeniem danych wielu rekordów (brak skutecznego odpowiednika operatorów typu JOIN) | * trudności z łączeniem danych wielu rekordów (brak skutecznego odpowiednika operatorów typu JOIN) |
| * słabe możliwości konfiguracji zabezpieczeń danych, pomimo ich istnienia [10] |
| |
======= Możliwości wykorzystania======= | ======= Możliwości wykorzystania======= |
* aplikacje internetowe korzystające ze sporej ilości dokumentów o zmiennej strukturze (np. portale internetowe) [1] | * aplikacje internetowe korzystające ze sporej ilości dokumentów o zmiennej strukturze (np. portale internetowe) [1] |
* oprogramowanie, które wymaga dostępności wszystkich wersji i historii zmian danego dokumentu lub rekordu | * oprogramowanie, które wymaga dostępności wszystkich wersji i historii zmian danego dokumentu lub rekordu |
| |
======= Kiedy stosować? ======= | ======= Kiedy stosować? ======= |
| |
* Struktura danych przechowywanych w aplikacji ma charakter "drzewiasty" - tj. nie ma, lub występują w ograniczonym stopniu relacje pomiędzy rekordami przechowywanymi w bazie danych. Przykładem typu wpisu, którego przechowywanie w formie, w jakiej odbywa się to w CouchDB jest rekord pacjenta - zawiera on tablice z diagnozami, stosowanymi terapiami, ale nie ma powiązania z innymi rekordami w bazie danych. | * Struktura danych przechowywanych w aplikacji ma charakter "drzewiasty" - tj. nie ma, lub występują w ograniczonym stopniu relacje pomiędzy rekordami przechowywanymi w bazie danych. Przykładem typu wpisu, którego przechowywanie w formie, w jakiej odbywa się to w CouchDB, jest rekord pacjenta - zawiera on tablice z diagnozami, stosowanymi terapiami, ale nie ma powiązania z innymi rekordami w bazie danych. |
* W przypadku replikacji bazy danych, ważniejsza jest dostępność danych i łatwość ich replikacji od spójności informacji pomiędzy serwerami. Taka sytuacja ma często miejsce w przypadku witryn internetowych i ogólnie oprogramowania, w którym przeważają operacje odczytu nad operacjami zapisu. | * W przypadku replikacji bazy danych, gdy ważniejsza jest wysoka dostępność danych (wysoki uptime) i łatwość ich replikacji od spójności informacji pomiędzy serwerami. Taka sytuacja ma często miejsce w przypadku witryn internetowych i ogólnie w oprogramowaniu, w którym przeważają operacje odczytu nad operacjami zapisu. |
====== Projekt ====== | * W przypadku, kiedy niezbędna jest wysoka wydajność aplikacji, a relacyjna baza danych okazuje się być wąskim gardłem w aplikacji, warto rozważyć przejście na system CouchDB, ze względu na możliwość automatycznej replikacji. Źródła[8] wskazują na łatwość uzyskiwania znaczącej wydajności (>2500 req/s) nawet przy użyciu standardowej konfiguracji, przy niewielkim użyciu pamięci operacyjnej. |
| * Interesujące wydaje się wykorzystanie łatwości pracy z CouchDB w przypadku platform, dla których nie istnieją dobre biblioteki do pracy z RDBMS, lub mają one ograniczoną funkcjonalność. CouchDB, dzięki wykorzystaniu mechanizmu REST, może być obsługiwany na dowolnej platformie, która posiada biblioteki do obsługi protokołu HTTP i przetwarzania plików JSON. |
| |
Celem projektu jest napisanie prostej aplikacji w oparciu o zorientowany na dokumenty system zarządzania bazami danych //CouchDB//. Aplikacja będzie umożliwiała wzorców tworzenie serii dokumentów (//formularzy//), a następnie tworzenie samych dokumentów (//rekordów//) w formie podobnej, jak można to robić np. w programach do zarządzania dokumentami. | ======= Kiedy nie stosować? ======= |
| |
Całość zostanie zaimplementowana w języku //Ruby//, z wykorzystaniem mikroframeworka do tworzenia aplikacji internetowych //SinatraRB//[4]. W tym przypadku framework zapewni w zasadzie jedynie funkcjonalność dynamicznego serwera http i mapowania adresów na odpowiednie akcje. Do komunikacji zostanie wykorzystana przykładowa biblioteka klienta, pochodząca z wiki twórców CouchDB[4]. | * Stosowanie CouchDB nie jest dobrym pomysłem, w sytuacji, kiedy w budowanym systemie informatycznym ponad wydajność ważniejsza jest spójność danych, jak ma to miejsce np. w systemach informatycznych zarządzania przedsiębiorstwem. |
| * Nie warto stosować CouchDB jako zamiennika systemów relacyjnych w sytuacji, kiedy istnieją skomplikowane zależności między danymi (liczne tabele lub klasy rekordów, wiele odwołań do kolumn w innych tabel, liczne funkcje agregujące). |
| |
| ======= Podsumowanie ======= |
| |
| CouchDB jest dojrzałym systemem baz danych, nastawionym na łatwość programowania, wysoką wydajność i sprawną replikację danych. Jest to także dobra alternatywa dla systemów relacyjnych w sytuacji, kiedy w strukturze danych dominującą rolę odgrywa jedna klasa rekordów i nie potrzeba skomplikowanych operacji raportowych. Osobiście, będę chciał zastosować ten system w aplikacji internetowej, w której zdecydowanie przeważać będą operacje odczytu danych. |
| ====== Zarys projektu ====== |
| |
| Celem projektu jest napisanie prostej aplikacji w oparciu o zorientowany na dokumenty system zarządzania bazami danych //CouchDB//. Aplikacja umożliwia tworzenie dokumentów (//rekordów//). |
| |
| Całość zostanie zaimplementowana w języku //Ruby//, z wykorzystaniem mikroframeworka do tworzenia aplikacji internetowych //SinatraRB//[4]. W tym przypadku framework zapewnia w zasadzie jedynie funkcjonalność dynamicznego serwera http i mapowania adresów na odpowiednie akcje (''FrontController''). Do komunikacji została wykorzystana przykładowa biblioteka klienta, pochodząca z wiki twórców CouchDB[4]. |
| |
Aby uprościć tworzenie warstwy widoku aplikacji, zostaną wykorzystane następujące biblioteki: | Aby uprościć tworzenie warstwy widoku aplikacji, zostaną wykorzystane następujące biblioteki: |
* jQuery | * jQuery |
* jQueryUI | * jQueryUI |
| ====== Funkcjonalność i uruchamianie aplikacji ====== |
| |
| System umożliwia: |
| |
| **przeglądanie listy dostępnych dokumentów** |
| |
| {{:pl:dydaktyka:ztb:2010:projekty:nosql_couch:scr1.png?640|}} |
| |
| |
| **tworzenie nowego dokumentu** |
| |
| {{:pl:dydaktyka:ztb:2010:projekty:nosql_couch:scr2.png?640|}} |
| |
| |
| **przeglądanie dokumentów i usuwanie bieżącego dokumentu** |
| |
| {{:pl:dydaktyka:ztb:2010:projekty:nosql_couch:scr3.png?640|}} |
| |
| |
| **Kod programu:** {{:pl:dydaktyka:ztb:2010:projekty:nosql_couch:keep_informed.tar.gz|keep_informed.tar.gz}} |
| |
| |
| Do uruchomienia potrzebny jest pakiet CouchDB działający na porcie 5987 maszyny lokalnej (lub wedle konfiguracji) oraz 'rubygems' w wersji 1.3.6 wraz z gemem 'sinatra' w wersji 1.0.0. |
| |
| Aplikację uruchamia się przy użyciu komendy w katalogu głównym źródeł: |
| |
| ''ruby app.rb'' |
| |
| i wejściu pod adres: |
| |
| ''http://localhost:4567'' |
| |
| (lub stosownie do parametrów uruchomienia). |
| |
| ====== Komunikacja z CouchDB ====== |
| |
| <code ruby> |
| # based upon a document at http://wiki.apache.org/couchdb/Getting_started_with_Ruby |
| require 'net/http' |
| |
| module Couch |
| class Server |
| def initialize(host, port, options = nil) |
| @host = host |
| @port = port |
| @options = options |
| end |
| |
| def delete(uri) |
| request(Net::HTTP::Delete.new(uri)) |
| end |
| |
| def get(uri) |
| request(Net::HTTP::Get.new(uri)) |
| end |
| |
| def put(uri, json) |
| req = Net::HTTP::Put.new(uri) |
| req["content-type"] = "application/json" |
| req.body = json |
| request(req) |
| end |
| |
| def post(uri, json) |
| req = Net::HTTP::Post.new(uri) |
| req["content-type"] = "application/json" |
| req.body = json |
| request(req) |
| end |
| |
| def request(req) |
| res = Net::HTTP.start(@host, @port) { |http|http.request(req) } |
| unless res.kind_of?(Net::HTTPSuccess) |
| handle_error(req, res) |
| end |
| res |
| end |
| |
| private |
| |
| def handle_error(req, res) |
| e = RuntimeError.new("#{res.code}:#{res.message}\nMETHOD:#{req.method}\nURI:#{req.path}\n#{res.body}") |
| raise e |
| end |
| end |
| end |
| </code> |
| |
| Jest to minimalistyczny klient, pozwalający na najbardziej niskopoziomową pracę z CouchDB. Istnieją dużo bardziej zaawansowane biblioteki dla wielu języków programowania[11]. |
| |
| Przykładowe wywołanie akcji pobierania dokumentu, aby go wyświetlić może wyglądać następująco: |
| <code ruby> |
| request = COUCH.get("/#{CONFIGURATION['database']}/#{params['id']}") |
| @document = JSON.load(request.body) |
| </code> |
| |
| Gdzie ''params['id']'' to przekazany do aplikacji identyfikator żądanego dokumentu |
| |
====== Bibliografia ====== | ====== Bibliografia ====== |
* [6] http://news.cnet.com/8301-13846_3-10412528-62.html?tag=mncol;title | * [6] http://news.cnet.com/8301-13846_3-10412528-62.html?tag=mncol;title |
* [7] http://news.cnet.com/8301-13846_3-10451248-62.html | * [7] http://news.cnet.com/8301-13846_3-10451248-62.html |
* [8] http://s3.amazonaws.com/data.tumblr.com/tumblr_kzjk0rvrer1qb4af9o1_1280.png?AWSAccessKeyId=0RYTHV9YYQ4W5Q3HQMG2&Expires=1276519367&Signature=Gy20aGtjIZbbUGgNA4yIPagxTl4%3D | * [8] http://qconsf.com/sf2008/file?path=/qcon-sanfran-2008/slides//JanLehnardt_CouchDB_in_a_real_world_setting.pdf |
| * [9] http://wiki.apache.org/couchdb/CouchDB_in_the_wild |
| * [10] http://books.couchdb.org/relax/reference/security |
| * [11] http://wiki.apache.org/couchdb/Related_Projects#Libraries |