No SQL mit DocumentDB und Azure

Es gibt etwas, was andere total cool finden und Sie nicht den Ansatz einer möglichen Nutzung sehen? Nein ich spreche nicht von der Apple Watch, ich spreche von NoSQL Datenbanken und im besonderen von neuen Azure Dienst DocumentDB. Ein Versuch einer Erklärung für etwas, was die wenigsten vermutlich brauchen werden.

Wenn man wenig weis, hilft immer ein Wikipedia Zitat

NoSQL (englisch für Not only SQL) bezeichnet Datenbanken, die einen nicht-relationalen Ansatz verfolgen und damit mit der langen Geschichte von relationalen Datenbanken brechen. Diese Datenspeicher benötigen keine festgelegten Tabellenschemata und versuchen, Joins zu vermeiden, sie skalieren dabei horizontal. Im akademischen Umfeld werden sie häufig als „strukturierte Datenspeicher“ (engl. structured storage) bezeichnet.

Ein neuer Dokumenten orientierter Vertreter ist documentDB, als Microsoft Azure Service aber nur online Verfügbar. Relativ vereinfacht, werden dabei JSON strukturierte Informationen gespeichert.  Für die Entwicklung steht JavaScript oder auch eine .NET API zur Verfügung.

Abfragen lassen sich mit einer ANSI SQL ähnlichen, reduzierten Syntax oder im .NET Umfeld auch per LINQ durchführen. Sämtliche CRUD Operationen werden unterstützt und lassen sich sogar per REST API ausführen. Unterstützt werden auch Transaktionen, Trigger und Stored Procedures.

Man kann nun stundenlang sinnieren, warum die Aufgabenstellung nicht per RDBMS und SQL Server löst. Microsoft preist documentDB als günstige und skalierbare Lösung. In jedem Fall stößt ein SQL Server bei sehr großen Datenmengen (über 50GB) und/oder vielen Schreiboperationen an Performance Grenzen. In jedem Fall sind Cloud basierte Lösungen für diese Probleme noch anfälliger. Wer rein aus der JavaScript Welt kommt, nutzt documentDB sozusagen als native Datenbank, fern von .net oder SQL.

Stellen wir uns also vor, eine klassische Aufgabenstellung einer Warenwirtschaft mit einer NoSQL Architektur zu lösen. Eine Rechnung stellt dann das Dokument dar. Mit Kopfdaten und Positionen. Die Positionen können sich in der Struktur erheblich unterscheiden. Schrauben haben andere Eigenschaften als Hosen. Einzelne Artikel können sich wiederrum aus Stücklisten zusammen setzen. Alles in einem Dokument und mit erheblich redundanter Datenmenge. Im Ergebnis jedes Document mit unterschiedlicher Struktur innerhalb einer Sammlung.

Zu allererst wendet man sich an das neue Azure Portal und erstellt dort ein documentDB Konto. Das dauert ziemlich lange. Als Ergebnis erhält man einen HTTP Endpunkt und einen Key für die Anmeldung.

documentd4

Als nächstes kann man im Web basierten Management Portal eine oder mehrere Datenbanken hinzufügen. Jede Datenbank enthält Collections (Sammlungen), die auf den ersten Blick Tabellen ähneln- allerdings ohne Struktur. Darin werden die Dokumente gesammelt, z.B. Rechnungen. Aufgrund der Schema Freiheit aber auch gemixt Adressen und Rechnungen.  Eine Sammlung wird immer auf einem Server gehostet, mit Azure typischen zwei zusätzlichen Kopien. Da die Preview Version (stand Feb 2015) ein Limit von 3 Sammlungen aufweist, wird man in der Praxis viel weniger davon nutzen, als bei RDBMS Tabellen und eher um die Daten zu partitionieren.

Auch eine  Sammlung kann man im Portal anlegen. Diese Funktion ist schwer zu finden und erscheint erst nach Auswahl der Datenbank im Azure DocumentDB-Kontobereich. Um den Abschnitt Datenbank zu erreichen, muss man nach unten scrollen.

image

Aber genau das macht NoSQL eben aus, das die Struktur und damit das Datenbank Schema nicht am Anfang steht. Deshalb wird in der Praxis häufig der Code die Aufgabe übernehmen die Collections anzulegen.

Abfragen kann man die Daten direkt im Azure Portal, per Dokument Explorer oder per Abfrage Explorer.

image

Die Abfragen erlauben ähnlich einem SQL Query Tool die Dokumente anhand der Attribute zu selektieren und zeigt die Ergebnisse als JSON an.

image

Hier sieht man das documentDB intern GUID ähnliche ID Werte verwendet.

Wesentliche Part der Struktur geschieht im Code. Wie von mir gewohnt per ASP.NET Webforms und VB.NET. Im Visual Studio Projekt muss per Nuget eine Referenz auf die Documents Clients Assembly eingefügt werden. Da im Stadium Prerelease (oder Preview) nur unter Auswahl der passenden DropDownliste auffindbar.

documentdb7

Es wird ein Client Objekt instanziiert, das später die Methoden für den Datenbank Zugriff kapselt.

 

   1:  Private Url As String = "https://ppedv.documents.azure.com:443/"
   2:  Private key As String = "w9t7JWW...qeZzKMS7pAmbspSKK5gw=="
   3:  Private _client As DocumentClient = New DocumentClient(New Uri(Url), key)

 

So lässt sich die Datenbank und darin die Document Collection per Code erzeugen.

   1:  _client.CreateDatabaseAsync(New Database With {.Id = "miniSAP"})
   2:  ...
   3:    col = Await _client.CreateDocumentCollectionAsync(
   4:                  db.SelfLink,
   5:                  New DocumentCollection With {.Id = "Rechnungen"})

 

Fehlen nur noch Rechnungen. Diese werden im folgenden Code Schnipsel aus zwei TextBoxen und einer passenden Klasse erzeugt.

   1:  Dim p = New rechnung With {
   2:                                   .firma = TextBox1.Text,
   3:                                   .betrag = TextBox2.Text,
   4:                                   .datum = Date.Now}
   5:   
   6:  Await _client.CreateDocumentAsync(col.SelfLink, p)

 

Natürlich will man die Daten auch anzeigen. Webforms hilft per ModelBinding, setzt dann allerdings wieder ein typisierte Liste voraus. Der HTML Code der ASPX Seite.

   1:  <asp:ListView ID="ListView1" ItemType="documentdb1.rechnung" 
   2:              SelectMethod="ListView1_GetData"
   3:               runat="server">
   4:              <ItemTemplate>
   5:                  <%#Item.firma%><br />
   6:              </ItemTemplate>
   7:  </asp:ListView>

 

Etwas komplexer ist die Codebehind Logik. Datenbank abfragen, Rechnungsliste abfragen und dann per SQL das oder die passenden Dokumente laden.

   1:  Public Async Function ListView1_GetData() As Threading.Tasks.Task(Of List(Of rechnung))
   2:          Dim db As Database
   3:          db = _client.CreateDatabaseQuery().Where(
   4:  Function(x) x.Id.Equals("miniSAP")).AsEnumerable().FirstOrDefault()
   5:   
   6:          Dim col As DocumentCollection
   7:          col = _client.CreateDocumentCollectionQuery(db.SelfLink).Where(
   8:  Function(c) c.Id.Equals("Rechnungen")).ToArray).FirstOrDefault
   9:   
  10:          Dim q = _client.CreateDocumentQuery(Of rechnung)
(col.SelfLink, "select * from Rechnungen").ToList
  11:   
  12:          Return q
  13:  End Function

 

Azure DocumentDB  macht die ORM Brücke Entity Framework überflüssig. Die Objekte stecken eben in der Datenbank. Die Programmierung geht leicht von der Hand. Allerdings muss der Entwickler komplett umdenken und das wird das größere Problem darstellen. Zusätzlich stellt sich die Frage was wir gewonnen haben. In diesem Fall nichts. Wenn man aber Amazon ist und pro Sekunde hunderte derartige Transaktionen durchführen will, könnte documentDB das Leben leichter machen. Dieser Azure Service steht  noch am Anfang.

Danke an Rainer Stropek für review.

Kommentare sind geschlossen