Seitenanfang

CouchDB - Tests

Dieser Post wurde aus meiner alten WordPress-Installation importiert. Sollte es Darstellungsprobleme, falsche Links oder fehlende Bilder geben, bitte einfach hier einen Kommentar hinterlassen. Danke.


Wie bereits im ersten Post gesagt, ist das Rennen zwischen Postgres und CouchDB weiter offen. Ein paar kurze Tests haben einige weitere Nachteile von CouchDB aufgezeigt.

Falsche SichtweiseAuch wenn ich noch keinen View erstellt habe, ist mir jetzt bereits klar geworden, dass SQL WHERE - Konstrukte mächtiger sind, allerdings musste ich auch mein Verständnis eines CouchDB Views korrigieren.

Ein View ist mitnichten ein Sourcecode der anhand bestimmter Parameter Datenbankdokumente sucht, vielmehr erstellt er den Index.

Der gedankliche - wenn auch auf Seiten CouchDB's nicht tatsächliche - Ablauf ist also wie folgt:

  • Dokument wird gespeichert
    • View-Funktion wird aufgerufen
    • Ergebnis der View-Funktion wird in eine interne Indextabelle geschrieben, dabei wird ein beliebiger Wert des Dokumentes als indizierter Wert gespeichert
  • View wird aufgerufen
    • interner Index wird durchsucht

Dabei kann der View-Aufruf einen Filter auf Basis des indizierten Wertes (vergleichbar mit einer indizierten Spalte bei einer SQL-Datenbank) definieren. Mögliche Filter sind:

  • Ein exakter Wert
  • Eine Liste von Werten
  • Ein Start- und ein Endwert

Wählt der View beispielsweise die Email-Adresse als indiziertes Feld, kann diese durchsucht werden.

Mücke und Elefant

Ein großer Nachteil von CouchDB sind Änderungen an bestehenden Dokumenten, denn bei jeder Änderung muss das komplette (geänderte) Dokument zum Server geschickt werden - bei großen Dokumenten kann dies eine erhebliche CPU- und RAM-Belastung verursachen.

CouchDB eignet sich demnach eher für selten geänderte Informationen.

Umständliche Antworten

DB::CouchDB liefert bei jedem Funktionsaufruf ein DB::CouchDB::Result-Objekt zurück, dass dann auf ->err überprüft werden muss. Besser wären meiner Meinung nach ein true/false Ergebnis und eine ->err bzw. ->errstr für das DB::CouchDB-Objekt.

Anlagen

Gestern Abend, bei den ersten CouchDB-Recherchen haben ich die Anlagen irgendwie übersehen, dabei sind sie ein dicker Pluspunkt.

Jedes CouchDB-Dokument kann durch Anlagen erweitert werden, die nicht indiziert werden können, dafür aber bei einem Update auch nicht neu mitgeschickt werden müssen.

Leider unterstützt DB::CouchDB diese noch nicht. Sollte ich mich bei meinem anstehenden Projekt für CouchDB entscheiden, würde vermutlich ein DB::CouchDB::Attachment-Modul entstehen.

Da in meinem Projekt eine Menge Logfiles gespeichert werden sollen, würden die Anlagen gerade richtig kommen, bei Postgres würde ich TEXT-Spalten dafür verwenden.

Das Test-Script

#!/usr/bin/perl -l

use strict;

use DB::CouchDB;use Data::Dumper;

# Verbindung aufbauenmy $db = DB::CouchDB->new(host => 'localhost', db => 'couchtest');$db->handle_blessed(1);

# Datenbank erstellen, schlägt ab dem 2. Lauf fehlt, das ist aber nicht schlimmmy $result = $db->create_db('couchtest');warn $result->errstr if $result->err;

# Test-Dokument erstellenmy %doc = (foo => 'bar', list => [1,3,5], tree => { bar => 'foo'}, deeptree => { hash1 => [{ key1 => 10},{key2 => 20}], hash2 => { key => "value"}}, null => undef);

# Dokument speichernmy $dbdoc = $db->create_doc(\%doc);die $dbdoc->errstr if $dbdoc->err;print "ID is ".$dbdoc->{id}.' rev is '.$dbdoc->{rev};print Dumper($dbdoc);

# Dokument wieder lesenmy $doc2 = $db->get_doc($dbdoc->{id});warn $doc2->errstr if $doc2->err;print Dumper($doc2);

# Dokument updaten$doc2->{updated} = 1;$result = $db->update_doc($doc2->{_id},$doc2);warn $result->errstr if $result->err;print Dumper($result);

# Ein altes Dokument mit über das CouchDB-Webinterface hochgeladener Anlage ladenprint Dumper($db->get_doc('75ee020dffa8b981a2ef662e373725f7'));

 

2 Kommentare. Schreib was dazu

  1. Sid Burn

    Hallo,
    sehr interessanter Post. Interesse an das Thema NoSQL habe ich auch schon länger und verfolge hier ebenfalls die Entwicklung seit längeren, aber bisher meist oberflächlich. Ich selber bin seit ca. 2 Wochen dabei mich mit MongoDB auseinanderzusetzen. Ich selber bin davon bisher beeindruckt, und warum ich das hier schreibe? Die "Probleme" die du mit CouchDB hast, hast du so bei MongoDB nicht. Ich kann dir also nur nahelegen mal über MongoDB zu schauen.

    Beispielsweise erwähnst du das die Abfragemöglichkeiten bei CouchDB nicht so vielseitig sind. Bei MongoDB hat man eine eigene Query Sprache und ich finde sie ziemlich vielseitig. Die Sprache ist dabei rein JSON und im Perl Treiber übergibt man demzufolge auch Perl Datenstrukturen. Natürlich ist ein SQL WHERE immer noch mächtiger aber ich denke das die Query Sprache nahezu das meiste abdeckt was man so benötigt.

    Simple Beispiele aus der JavaScript Shell:
    // i.e., select * from things where x=3 and y="foo"
    db.things.find( { x : 3, y : "foo" } );
    // i.w., select * from things where j != 3 and k > 10
    db.things.find({j: {$ne: 3}, k: {$gt: 10} });

    Man kann auch verschachtelte Dokumente abrufen, arrays, datum abfragen etc. Es gibt auch aggregier funktionen wie group() oder distinct(). Oder eben ganz zum schluss map/reduce über JavaScript Funktionen.

    Bei MongoDB erzeugt man dann auch echte Indexe, und die Queries nutzen halt die Indexe. Hier gibt es auch Unique Constraints.

    Beim Ändern muss man ansonsten nicht das vollständige Dokument hochladen. Um Beispielsweise einen counter in einem Dokument zu erhöhen

    // erhöht feld counter um 2 im dokument mit der _id "abcdef..."
    db.collection.update({_id: "abcdef...", $inc: {counter: 2} })

    Genauso kann man halt nur einzelne Felder updaten, oder zum Beispiel Arrays Elemente/Dokumente hinzufügen.

    Ansonsten bei Fehlern ist es eigentlich am simpelsten wenn eine Exceptions geworfen werden anstatt Fehler manuell zu prüfen. Beim "MongoDB" Modul wird hier in der Regel croak() aufgerufen. Auser du machst explizite Synchrone Writes dann prüfst du einen Rückgabewert. Wenn du Asynchrone writes nutzt kann es dann auch sein das du gar kein fehler bekommst. Zum Beispiel wenn ein Unique Constraint verletzt wird. Das liegt dann am entwickler wo er asynchrone oder synchrone writes nutzt.

    Ich kann dir nur empfehlen mal MongoDB anzuschauen. Die meisten anderen NoSQL Datenbanken sind zwar nett, ich denke aber eher optimal für bestimmte Aufgaben und kein ersatz für ein RDBMS. Bei MongoDB gerade wegen der möglichkeit der doch gut ausgebauten Queries kann dies wirklich als ein ersatz dienen.

    Ich habe mit MongoDB hier angefangen: http://www.mongly.com/

    Dort gibt es ein Interaktives Tutorial (15-30 min) was mich bereits beeindruckt hat. Und darauf eine weiterführende PDF (33 Seiten) was genauer auf das Thema eingeht.

  2. Sebastian

    Danke für die ausführlichen Erläuterungen.
    Auf jeden Fall scheint sich das Mongo-Interface komplett von dem von CouchDB zu unterscheiden, anschauen werde ich es mir auf jeden Fall noch.

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>