Open Source im professionellen Einsatz
Linux-Magazin 09/2004

SQLite: Datenbank-Engine im Kleinformat

Datenspeicher für Sparsame

SQLite bringt zwar die Funktionalität einer relationalen SQL-Datenbank mit, kommt aber ohne aufwändig zu administrierende Server aus. Dieser Artikel vergleicht die Bibliothek mit ihren Konkurrenten und zeigt, wie man sie in eigene Programme einbaut.

922

Beim Stichwort Datenbank denken die meisten wohl an Schwergewichte wie Oracle oder DB 2. Solche auf der Client-Server-Architektur beruhenden Produkte sind für kritische Anwendungen mit großen Datenmengen und viele gleichzeitige Zugriffe konzipiert. Es gibt aber auch Bereiche, in denen dieses System des Guten zu viel ist: So kann der Entwickler eines Routenplaners oder eines Telefon- und Adressbuchs seinen Kunden kaum zumuten, ein komplettes Datenbanksystem zu installieren, einzurichten und zu verwalten.

Desktop-Datenbanken wie SQLite[1] lassen sich dagegen leicht in eigene Programme integrieren, ob direkt über die C-Schnittstelle oder über eines der zahlreichen Skriptsprachen-Interfaces, zum Beispiel in Perl, Python, Ruby, PHP und vielen anderen, siehe[2]. Den konzeptionellen Unterschied zwischen beiden Ansätzen zeigt Abbildung 1. Bei einem Datenbanksystem greifen Anwendungsprogramme nicht direkt auf die Daten zu, sondern kommunizieren mit einem separaten Prozess (dem Datenbank-Managementsystem), der seinerseits die Daten verwaltet.

Abbildung 1: Bei einem Datenbanksystem verwaltet ein Server die Zugriffe, die Desktop-Datenbank macht alles alleine.

Bei einer Desktop-Datenbank liest und schreibt jedes Anwendungsprogramm direkt. Das hat den Vorteil, dass kein Datenbankserver gestartet und administriert werden muss, stößt aber insbesondere im Mehrbenutzerbetrieb schnell an Grenzen. Salopp formuliert ist eine Desktop-Datenbank lediglich ein SQL-Frontend für das Dateisystem (siehe Kasten "Datenbankbegriffe" und[3]).

Datenbankbegriffe

SQL steht für Structured Query Language, die standardisierte Abfragesprache für relationale Datenbanken, siehe[3].

Integrity-Constraints sind Bedingungen, die die logische Korrektheit der Daten gewährleisten.

Foreign-Key-Constraints (Fremdschlüssel) sind die wichtigste Variante der Integrity-Constraints, die korrekte Beziehungen zwischen Tabellen gewährleisten. Um zu testen, ob ein Wert für eine Tabelle gültig ist, bezieht die Datenbank eine andere Tabelle mit ein, daher das "Foreign".

ACID steht für Atomicity Consistency Isolation Durability und bezeichnet die Anforderungen, die Transaktionen erfüllen müssen, damit Daten konsistent bleiben.

SQLite-Komponenten

Sourcecode und vorkompilierte Binaries für diverse Plattformen finden sich als freie Software auf der SQLite-Homepage. Unter Linux lässt sich der Sourcecode problemlos gemäß der »README«-Anleitung übersetzen. Die Dokumentation fehlt dann noch, dafür sorgt ein weiteres »make doc«. Nach der Installation mit »make install« findet der Anwender folgende Komponenten auf seinem System:

  • Den SQL-Interpreter »sqlite« und
  • die C-Bibliothek Libsqlite und die Headerdatei
    »sqlite.h«.

Das Programm »sqlite« dient zur interaktiven Arbeit mit einer SQLite-Datenbankdatei. Als Desktop-Datenbank hat SQLite keine Benutzerverwaltung und kein Berechtigungskonzept, sodass sich Datenbankdateien ohne Login mit dem Befehl »sqlite DBdatei« öffnen und bearbeiten lassen.

Neben den SQL-Kommandos kennt »sqlite« auch Metakommandos, die mit einem Punkt beginnen und einige Operationen ermöglichen, die über die reine Datenmanipulation hinausgehen. Nützlich sind zum Beispiel ».read SQLdatei« zum Ausführen der SQL-Befehle in » SQLDatei« sowie ».tables« zum Anzeigen der vorhandenen Tabellen oder ».dump Tabelle« zum Export einer Tabelle in Form eines SQL-Skripts.

Datenbank mit Bibliothek

Für den Entwickler von größerem Interesse ist die C-Bibliothek Libsqlite, weil sie die Möglichkeit bietet, eigene Programme mit geringem Aufwand um eine Datenspeicherkomponente mit SQL-Zugriff zu erweitern. Wenn keine Select-Kommandos auszuführen sind, reichen drei Funktionen:

  • »sqlite_open()« zum Öffnen einer
    Datenbankdatei
  • »sqlite_close()« zum Schließen einer
    Datenbankdatei
  • »sqlite_exec()« zum Ausführen von
    SQL-Kommandos

Listing 1 zeigt, wie die SQLite-Bibliothek einzusetzen ist. Die Funktion »sqlite_ open()« in Zeile 13 öffnet die Datenbank. In Zeile 22 nimmt die Variable »sql« das SQL-Insert-Statement auf, das »sql_exec()« dann ausführt.

Die Routine »sqlite_open()« legt das Datenbank-File an, wenn es noch nicht existiert. Wer das nicht möchte, muss vorher prüfen, ob es die Datei schon gibt, zum Beispiel mit der Posix-C-Funktion »access()«. Beim SQL-Statement »SELECT« wird es komplizierter, weil dessen Ergebnis im Allgemeinen eine komplette Tabelle ist. Die übliche Lösung für dieses Problem in SQL-Programmierschnittstellen sind so genannte Statement-Cursors, die in der SQLite-Dokumentation Virtual Machines heißen. Damit durchläuft der Anwender zeilenweise die als Ergebnis gelieferte Tabelle. Die SQLite-Bibliothek stellt dafür drei Funktionen bereit:

  • »sqlite_compile()« zum Anlegen eines
    Statement-Cursors
  • »sqlite_step()« zum Navigieren in der
    Ergebnistabelle
  • »sqlite_finalize()« zum Zerstören des
    Statement Cursors

Auch dafür findet sich ein Beispiel in Listing 1, Zeilen 31 bis 50. Den Statement-Cursor legt »sql_compile()« an. Wenn kein Fehler auftritt, dann arbeitet »sqlite_step()« das Ergebnis ab, bis keine Zeilen mehr übrig sind (siehe Zeile 43).

Neben der C-Bibliothek enthält die SQLite-Distribution einen ODBC-Treiber, der unter anderem den Zugriff aus Office-Paketen auf SQLite-Daten ermöglicht[4]. Das ist aber mit Vorsicht zu genießen, weil SQLite keine Foreign-Key-Constraints unterstützt (siehe Kasten "Datenbankbegriffe"), sodass ein Schreibzugriff des Endanwenders zum Beispiel mit Microsoft Access schnell zum Datenchaos führen kann.

Listing 1:
Libsqlite-Beispiel

01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <sqlite.h>
04 
05 sqlite *db;           /*Datenbank-Objekt*/
06 sqlite_vm *dbcursor;  /*zum Abarbeiten Select-Ergebnis*/
07 char *dberr = 0;      /*Fehlermeldungen*/
08 char *sql, *sqltail;  /*SQL-Kommandos*/
09 
10 /*
11  * Datenbankdatei öffnen
12  */
13 if (! (db = sqlite_open("test.db", 0, &dberr)) ) {
14    printf("Hoppla: %sn", dberr);
15    free(dberr);
16    return 1;
17 }
18 
19 /*
20  * Beispiel für Nicht-Select Statement
21  */
22 sql = "INSERT INTO person (nr,name) VALUES (1,'Melitta Beutel')";
23 if (SQLITE_OK != sqlite_exec(db, sql, NULL, NULL, &dberr)) {
24    printf("Huch: %sn", dberr);
25    free(dberr);
26 }
27 
28 /*
29  * Beispiel für Select-Statement
30  */
31 sql = "SELECT nr, name FROM person WHERE name LIKE '%Beutel'";
32 /* Lege Statement-Cursor an (Konstruktor) */
33 if (SQLITE_OK != sqlite_compile(db, sql, &sqltail,
34                                 &dbcursor, &dberr)) {
35     printf("Oha: %sn", dberr);
36     free(dberr);
37 } else {
38     int ncols;        /*Anzahl zurückgegebener Spalten*/
39     char **colnames;  /*Spaltennamen*/
40     char **values;    /*Spalteninhalte*/
41 
42         /* arbeite Ergebnis mit Cursor ab */
43     while (SQLITE_ROW == sqlite_step(dbcursor, &ncols,
44                                      &values, &colnames)) {
45         printf("nr='%s', name='%s'n", value[i]);
46     }
47 
48         /* Speicher von Cursor freigeben (Destruktor) */
49     sqlite_finalize(dbcursor, NULL);
50 }
51 
52 /*
53  * Datenbank schließen
54  */
55 sqlite_close(db);

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • SQLite 3.8.0 optimiert Performance

    SQLite 3.8.0 unterstützt partielle Indizes, bringt einen verbesserten Next Generation Query Planner mit sowie eine "notindexed"-Option für das virtuelle Volltext-Tabellenmodul FTS4.

  • OmniDB wird Open Source

    OmniDB, ein Webtool zum Management von relationalen Datenbanken steht laut der Ankündigung der Entwickler nun unter der GPL.

  • Perl-Snapshot

    Viele Ubuntu-User wissen gar nicht, dass ihnen der Zeitgeist-Daemon heimlich über die Schulter schaut und ihre Desktop-Aktionen mitprotokolliert. Einige Perl-Skripte bereiten die Lauscherberichte auf und bringen interessante Tatsachen über die Usergewohnheiten ans Tageslicht.

  • Vollautomatik

    Das Security-Framework Metasploit scannt ganze Netzwerke auf Schwachstellen und wird dabei vor allem in Windows-LANs fündig. Indem es zahlreiche Exploits durchprobiert, gibt es Admins und Linux-Advokaten nebenbei gute Argumente für die Migration zu freier Software.

  • Datenbank-Visualisierung DBvis 9.0 erschienen

    Nach 18 Monaten hat der Hersteller des Datenbankvisualisierungstools DBviz eine neue Version herausgegeben.

comments powered by Disqus

Ausgabe 10/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.