PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Archive for the ‘Einstieg’ tag

NoSQL: Ein Einstieg mit MongoDB

with 8 comments

Ein Gastbeitrag von Florian Heinze, Gründer von vsChart.

Für alle die sich fragen, NoSQL – was ist das und wie geht das überhaupt, folgend ein praktischer Einstieg am Beispiel von MongoDB.

Zunächst, was bezeichnet genau NoSQL? Der Begriff ist etwas unglücklich. Denn es geht nicht um die Ablehnung der Abfragesprache SQL, sondern um die Befürwortung von Alternativen zu den dominierenden Relationalen Datenbanken.
Die zwei Kernelemente dieser Bewegung sind aus typischen Anforderungen für moderne Webanwendungen erwachsen: Vereinfachung der Datenhaltung für die Entwicklung und  verbesserte horizontale Skalierbarkeit im Betrieb.

Zur Praxis

Die Installation von MongoDB selber geht recht fix. Dazu holt man sich dann noch die mongo-Eweiterung für PHP per pecl install mongo und fügt extension=mongo.so in der php.ini dazu.

Das reicht schon um loszulegen:

<?php
// automatische Verbindung mit localhost:27017
$mongo = new Mongo();
// $blog ist ein MongoDB-Objekt (vergleichbar mit MySQL-Datenbank, wird automatisch angelegt)
$blog = $mongo->blog;
// $posts ist eine MongoCollection (vergleichbar mit SQL-Tabelle, wird automatisch angelegt)
$posts = $blog->posts;
// schreiben
$posts->insert(array(
    'slug' => 'foo-bar',
    'title' => 'Foo Bar',
    'body' => '<p>Bar foo foo bar …</p>',
    'date' => new MongoDate(),
    'tags' => array( 'footag', 'bartag', 'foobar'),
));

Die Datenbank und Collection (Tabelle im SQL-Sinne) werden zur Laufzeit automatisch erstellt. Da auch die Anmeldung an der Datenbank ohne Authentifizierung auskommt, ist bequemer weise kein vorheriger administrativer Zugriff auf die MongoDB nötig.

Vorteile von dokumentorientierten Datenbanken

Das direkte Speichern nativer Arrays wie im Beispiel ist natürlich überaus praktisch. Strukturen wie man sie oft sowieso schon im eigenen Code verwendet können mit geringen Manipulationen direkt abgespeichert werden. Joins über IDs oder komplizierte Zwischentabellen um m:n Beziehungen darzustellen, wie aus der SQL-Welt, fallen im Idealfall komplett weg (wie oben bei den ‚tags‘).

Der schemalose Ansatz der dokumentenorientierten Datenbanken macht die Entwicklung flexibler denn das umständliche Anlegen neuer Felder oder Tabellen über Administrationswerkzeuge ist nicht mehr nötig. Das macht das Aufspielen neuer Versionen auf Live- oder andere Entwicklungsserver oft deutlich einfacher.

Zwei weitere oft genannte Argumente für NoSQL und somit auch MongoDB sind einfache horizontale Skalierbarkeit und Performancevorteile für viele Anwendungsfälle. Der Trumpf Skalierbarkeit lässt sich aber natürlich erst bei wirklich großen Projekten ausspielen.

Innere Umstellung aus SQL-Sicht

Allerdings muss man den eigenen Entwicklungsansatz auch auf diese neuen Datenmodelle einstellen. Denn z.B. die Performancegewinne bei MongoDB erreicht man zu einem Teil erst dadurch, dass man möglichst versucht ohne „Joins“ auszukommen. Das bedeutet dann in der Praxis das man alle Seitendaten für unseren Blog-Post z.B. in einen einzigen Datenbank-Eintrag schreibt:

<?php
// erweitern des obig angelegten Dokumentes
$posts->update(
    array( 'slug' => 'foo-bar'), // quasi eine where-Bedingung
    array( '$set' => array( // ohne set $set würde es den ganzen Post ersetzen
        'user' => array(
            'name' => 'Mr. Foo',
            'nick' => 'mrfoo',
        ),
        'comments' => array(
            0 => array(
                'date' => new MongoDate(),
                'name' => 'Ms Comment',
                'mail' => 'ms.comment@example.com',
                'text' => 'Bar foo bar …',
            ),
            1 => array(
                'date' => new MongoDate(),
                'name' => 'Mr Comment',
                'mail' => 'mr.comment@example.com',
                'text' => 'Foo bar foo …',
            ),
        ),
    ))
);
?>

Einiges davon wirkt natürlich nach vielen Jahren SQL-Erfahrung etwas unsauber. Erfahrungen zeigen aber das viele der Einsprüche für die Praxis nicht viel Bedeutung haben.
Der erste und vielleicht auch wichtigste Schritt im Umstieg zu NoSQL-Modellen ist es, den gewohnten Join-Ansatz aus den eigenen Gedanken so weit wie möglich zu verbannen.

Daten abfragen

Die Where-Bedingungen von Abfragen werden ebenfalls als Arrays übergeben. Einfache Abfragen sind so noch recht übersichtlich, aber bei komplexeren Statements geht dadurch manchmal die Orientierung verloren.

Um unser Beispiel abzuschließen, hier eine Abfrage plus vereinfachte Ausgabe:

<?php
$doc = $posts->findOne( array( 'slug' => 'foo-bar'));
echo '<h1>'.$doc['title'].'</h1>';
echo '<em>'.$doc['user']['name'].'/'.date('r', $doc['date']->sec).'</em>';
echo $doc['body'];
echo '<ul>';
foreach( $doc['comments'] as $key => $comment) {
    echo '<li>'.$comment['name'].': '.$comment['text'].'</li>';
}
echo '</ul>';
?>

Vorteile von MongoDB

Weitere Vorteile speziell von MongoDB sind die Indizes die auch auf tief liegende Felder (z.B. comments.date) gelegt werden können.
Ebenfalls hervorzuheben ist das auch große Binärdateien mit GridFS gleich mitverwaltet werden können.
Auch die Dokumentation (PHP) ist für ein jüngeres Projekt sehr gut!

MongoDB hat im Vergleich zu anderen NoSQL-Datenbanken noch eine recht hohe Ähnlichkeit zu SQL-Datenbanken. Das macht den Übergang einfacher.

Alternative: CouchDB

Allgemein ist das NoSQL-Biotop noch sehr unübersichtlich. Es gibt viele verschieden Ansätze (Dokument-, Zeilen- oder Key-Value-orientiert) mit jeweils vielen verschiedenen Produkten.
Ein ähnliches Produkt unter den bekannteren Namen ist CouchDB. Im direktem Vergleich MongoDB vs. CouchDB hat MongoDB Vorteile durch eine bessere echte PHP-API, In-Place-Updates und dem leichteren Umstieg. CouchDB punktet vor allem mit größerer Datensicherheit und unabhängigerer Entwicklercommunity.

Wann lohnt sich NoSQL?

Dokumentenorientierte Datenbank wie MongoDB und CouchDB haben Vorteile wenn viele verschiedene Datenfelder am Ende ein Dokument (z.B. Blog-Eintrag oder CMS-Seite) darstellen und man sich viel Flexibilität in der Entwicklung wünscht.
Weniger geeignet scheinen NoSQL-Systeme für Aufgaben aus dem Rechnungswesen die viele variierende Aggregationen aus Zahlenwerten benötigen.

Fazit

NoSQL ist natürlich auch ein Buzzword und SQL-Datenbanken werden selbstverständlich auch weiterhin gebraucht. Trotz alle dem bringt die NoSQL-Welle viele interessante neue Ansätze die sicherlich in einigen Bereichen in Zukunft zum Standard gehören werden.

Written by Florian Heinze

Dezember 14th, 2010 at 10:42 am

Posted in PHP

Tagged with , ,