Artikel top billede

(Foto: Computerworld)

Programmering med NoSQL - del 3

Denne gang kigger vi nærmere på CouchDB, der er en meget populær og udbredt NoSQL-database.

Af Kenneth Geisshirt, Alt om Data

Denne artikel er oprindeligt bragt på Alt om Data. Computerworld overtog i november 2022 Alt om Data. Du kan læse mere om overtagelsen her.

Bruger du Ubuntu Linux som styre- system på din desktop, er du bruger af CouchDB. Ubuntu One er en tjeneste, som Canonical (firmaet bag Ubuntu Linux) tilbyder Ubuntu-brugerne.

Denne tjeneste gør det muligt at gemme data (filer, kontakter, bogmærker og så videre) hos Canonicals datacentre. Derved kan du synkronisere dine computeres data og tage backup. Denne tjeneste benytter i stor udstrækning CouchDB som underliggende database.

Hvordan virker CouchDB?

CouchDB er en dokument-orienteret database. Som de andre NoSQL-databaser har CouchDB ikke en fastlagt struktur. Det giver en stor fleksibilitet, idet applikationsudviklerne lettere kan ændre datastrukturer i løbet af applikationens livsforløb uden at skulle ændre på databasen.

Tricket er at gemme al data i json-formatet. Json (JavaScript Object Notation) er et platformsuafhængigt dataformat, som stammer fra web-udviklingsmiljøerne. Ideen er at tage objekter (oprindelig kun JavaScript-objekter) og serialisere dem som tekststrenge.

I dag understøttes langt de fleste programmeringssprog, herunder php og json. Man kan sige, at CouchDB er en objekt-database, idet den gemmer objekter, dog som tekststrenge. SQL-databaser har en vigtig egenskab, som du også finder i CouchDB: acid (atomicity, consistency, isolation, durability).

I første afsnit af denne serie bragte vi en længere diskussion af acid, men den korte version er, at en operation/transaktion enten gennemføres fuldstændigt eller overhovedet ikke. Det er et meget stærkt krav for en database.

Endvidere er CouchDB en distribueret database, men det er ikke et krav. Hver instans af CouchDB vil have de samme data, og der vil ske en løbende synkronisering mellem instanserne. CouchDB har en række muligheder for at rette op på konflikter (inkonsistens) mellem de forskellige instanser.

Udviklet i Erlang

At vælge Erlang som programmeringssprog til at udvikle CouchDB er nok lidt overraskende. Erlang er et funktionsprogrammeringssprog, som har fejltolerance som en af sine mærkesager. Ved at bruge Erlang får CouchDB-udviklerne en masse forærende i form af distribuerede, fejltolerante systemapplikationer.

Oprindelig blev Erlang udviklet af Ericsson og brugt til software til telefoncentraler. En telefoncentral skal kunne passe sig selv, uden at en tekniker skal ud og reboote den, når den går ned.

RESTful

Selve kommunikationen med CouchDB sker ved hjælp af enten http eller https. Det er nok verdens mest udbredte protokoller, og der findes implementationer af http til ethvert programmeringssprog.

Http er en tilstandsløs protokol. Det betyder, at serveren ikke husker noget fra forespørgsel til forespørgsel. Det giver en masse fordele, for eksempel skal web-serveren ikke bruge tid og plads (hukommelse eller harddisk) på at gemme informationer om klienterne. Ulempen er, at der skal sendes en del information med i hver forespørgsel, da klienten hver gang skal bygge hele tilstanden op.

Egentlig er http en meget rig protokol. Der er flere operationer, herunder get, put, post og delete. Get og post er mest kendt blandt web-udviklere, da de bruges til at sende data (i forms) tilbage fra browseren til serveren.

RESTful er et forsøg på at komme ud over http’s tilstandsløse virkemåde. Det er en forkortelse for Representational State Transfer, og det dækker over at bruge et særligt mønster i url sammen med http-operationerne til at repræsentere tilstanden, for eksempel bruges get til at hente enten oversigter eller enkelte dataobjekter, mens put bruges til at ændre eller opdatere objekter.

Installation

Under Ubuntu Linux er det ikke svært at installere CouchDB. Du kan nøjes med kommandoen sudo apt-get install couchdb.

CouchDB bruger, som allerede nævnt, http som underliggende protokol. Det er muligt at tilgå databasen direkte med en web-browser, og du bør altid afslutte installationen med at tjekke, om CouchDB virker. På port 5984 finder du databasen, og url’en http://127.0.0.1:5984/_utils/index.html kan bruges, hvis du har installeret CouchDB på din desktop-computer (ellers udskift ip-adressen 127.0.0.1 med serverens ip-adresse).

Under en standard Ubuntu Linux-installation finder du CouchDB’s filer i folderen /var/lib/couchdb, hvis du har behov for at tage backup. For at komme i gang skal du oprette en database. På administrationssiden (den tidligere omtalte url) finder du et link ved navn Create Database. Det klikker du på, og du kan nu oprette en database. Til denne artikel hedder databasen aod_journal.

I denne serier foretrækker vi, at alle kodeeksemplerne er skrevet i php. Der findes flere mere eller mindre avancerede biblioteker til håndtering af CoucnDB fra php. Men ser du på http://wiki.apache.org/couchdb/Getting_started_with_PHP, finder du en lille klasse ved navn ’CouchSimple’.

Der er her tale om en meget enkelt måde at kommunikere med CouchDB på. Den er nok ikke anvendelig i større applikationer, men brug klassen til at lære, hvordan CouchDB kan bruges sammen med din applikation. I eksemplerne nedenfor bruges klassen. Selve klassen er erklæret i en fil for sig, navnet er couchsimple.php, og den skal blot placeres sammen med dine andre php-filer.

Oprettelse af forbindelse

Som i forrige afsnit i serien vil kodeeksempler vise, hvordan et journaliseringssystem kan bruge NoSQL-databaser til at gemme dokumenter og billeder. Alle tre eksempler bruger klassen ’SimpleCouch’, som er omtalt tidligere.

Ved oprettelse af et objekt i denne klasse sker der egentlig ikke så meget, kun at en række parametre sættes. Metoden send udfører det egentlig arbejde. Navnet på metoden refererer til, at der sendes en forespørgsel, og ikke at der sendes data til CouchDB. En mere avanceret klasse vil nok vælge at have forskellige metoder til henholdsvis get, put, post og delete.

Gem billede

Med et ’SimpleCouch’-objekt kan du gøre klar til at sende et billede til database. Kodeeksemplet i infoboksen Gem_billede.php kan du se, hvor enkelt det er at gemme et billede i CouchDB. Eftersom CouchDB gemmer data i json-format, er det en fordel at oversætte php-objekter til json.

Metoden send har tre argumenter. Det første er http-operationen. Med put gemmes data i databasen. I hvilken database og under hvilket id angiver du ved hjælp af det andet argument. Det er nemlig den sidste del af en url (efter angivelse af vært og port).

Mellem de to første skråstreger (/) finder du navnet på databasen, som i vores tilfælde er aod_journal. Navnet svarer præcist til det navn, du angav, da du oprettede databasen tidligere. Den sidste halvdel af det andet argument er det id, du ønsker at give dit dokument. I dette tilfælde er id billede_kneth valgt, men du skal huske, at hvert nye dokument skal have et unikt id.

Det tredje og sidste argument er det objekt, som repræsenterer data, som du ønsker at gemme. I infoboksen Gem_billede.php kan du se, at vi gemmer selve billedet, et id-felt samt et tidsstempel. Feltet _id bruger CouchDB internt, og du vil se senere, at det er nødvendigt at kende.

Metoden send returnerer et objekt (som tekststreng i json-format), med hvilket du kan se, om det gik godt med at gemme billedet.

Få overblik

Som allerede nævnt har CoucbDB et RESTful-interface. Det betyder, at http-operationen get kan bruges til at få oversigter. Er url’en navnet på databasen efterfulgt af det magiske _all_docs (i vores tilfælde er url’en /aod_journal/_all_docs), vil du få en oversigt over alle dokumenterne i databasen.

Sådan kan du trække en oversigt over alle dokumenter ud af databasen:

include_once “couchsimple.php”;

$options[‘host’] = “localhost”;
$options[‘port’] = 5984;
$couch = new CouchSimple($options);
$resp = $couch->send(“GET”, “/aod_journal/_all_docs”);
$a = json_decode($resp);
$total = $a->total_rows;
foreach($a->rows as $row) {
print $row->id.” “.$row->key.”n”;
}

Returværdien fra send er et objekt (igen i json-format).

Objektet indeholder for eksempel attributten total_rows, som angiver, hvor mange dokumenter som der er i databasen. Den vigtigste attribut er nok rows, som er et array med informationer om dokumenterne. Der er ikke tale om, at attributten indeholder dokumenterne, men kun deres unikke id’er samt en række andre oplysninger.

Hent billede

Med en oversigt over alle dokumenterne i databasen kan dine brugere udvælge et dokument og hente det. Id’erne i oversigten skal bruges til at specificere, hvilket dokument som ønskes hentet. Igen kommer http-operationen get i brug.

include_once ”couchsimple.php”;

$options[’host’] = ”localhost”;
$options[’port’] = 5984;
$couch = new CouchSimple($options);
$resp = $couch->send(”GET”, ”/aod_journal/billede_kneth”);
$billede = json_decode($resp);

print $billede->_id.” dateret ”.date(”d M Y”, $billede->timestamp).”n”;
$data = base64_decode($billede->data);
$handle = fopen(”test.jpg”, ”w”);
fwrite($handle, $data);
fclose($handle);

Som du kan se angiver du url’en til dokumentet. Url’en består dels af databasenavnet og dels af dokumentets id. Metoden send giver dig dokumentet i json-format. En enkel konvertering fra json til et php-objekt kan gøres med json_decode. Dette php-objekt vil have attributter, som afspejler de data-elementer, som du brugte til at gemme billedet.

Næste gang

Du finder mere information om CouchDB på projektets hjemmeside (http://www.couchdb.org). I næste og sidste afsnit i serien om NoSQL kommer du til at stifte bekendtskab med en tredje NoSQL-database. Den hedder MongoDB, og den minder på mange måder om de andre NoSQL-databaser, som du allerede har set, men den har sine helt egne fordele.