[A] Einführung in die Einbindung von Datenbanken in C++



  • Hallo

    Das ist der Entwurf für meinen Artikel. Konkret geht es hier im ersten Teil um die Theorie, um die beantwortung der ersten beiden themenbestimmenden Fragen. Der zweite Teil mit der Einführung in die Praxis kommt natürlich auch bald.
    Ich würde mich über Feedback freuen!

    Einführung in die Einbindung von Datenbanken in C++

    Dieser Artikel beschreibt den Einsatz von externen aktiven Datenbanken, konkret diese Fragen :

    • Was genau ist eine Datenbank?
    • Warum und Wann sollte man Datenbanken verwenden? Was spricht dagegen?
    • Was gibt es für konkrete Datenbanken, und wie binde ich sie in C++ ein?
    • Was für Möglichkeiten bieten DBS über einer einfachen Datenspeicherung hinaus?

    1 Was sind Datenbanken?

    Datenbanken sind eine der ältesten Einsatzbereiche von Computern, und neben dem Berechnen von komplexen mathematischen Formeln wohl die große Stärke der digitalen IT.
    Datenbanken findet man heutzutage (aber schon seit längerem) hinter jeder größeren Internetseite die einen Online-Shop betreibt, die über ein Content Management System gepflegt wird oder einfach nur ein Nachschlagewerk samt Suche anbietet. Auch lokal arbeiten Datenbanken im Hintergrund, angefangen von Outlook bis hin zu ausgewachsenen Implementationen für Contact Relation Management in großen Firmen.
    Schon als Endbenutzer ist es also wahrscheinlich mit Datenbanken zu arbeiten ohne es im besonderen zu merken. Es ist also vorteilhaft für Programmierer zu wissen wie man mit Datenbanken umgeht.
    Ein modernes DBS soll unabhängig von der technischen Umsetzung folgende Möglichkeiten haben :

    • Speicherung von strukturierten Daten in genau definierten Containern
    • Relationalität, was bedeutet das zwischen einzelnen Containern Beziehungen definiert werden können
    • Client-Server Prinzip, um die Benutzeranwendung und die Datenhaltung zu trennen
    • Wahrung der Datenkonsistenz unabhängig vom Client nach den Regeln die der Entwickler festgelegt hat
    • Zugriff über ein sprach- und plattformunabhängiges Protokoll, das möglichst flexibel verwendet werden kann
    • Serverseitige Filterung und Sortierung der Daten, was 3 Vorteile bietet : der Client braucht sich nicht darum zu kümmern, das Übertragungsvolumen wird gesenkt und der Server kann von vorbereiteten Optimierungen profitieren
    • Zugriffskontrolle, die jedem Benutzer genau definierte Rechte zuweist

    Ein DBS besteht also aus zwei Teilen, dem Server und dem Client. Der Server verwaltet die eigentlichen Daten im lokalen Dateisystem, während der Client vom User gesteuert den Server anspricht und abfragt. Die Kommunikation zwischen Server und Client läuft dabei meistens mittels TCP/IP, was das DBS damit Netzwerk- und Internetfähig macht.
    Es gibt aber auch einige DBS die bewußt nicht über Netzwerkschnittstellen kommunizieren, oder gar keinen aktiven Server besitzen. Sondern diese werden auf dem lokalen Computer direkt über eingebunde Bibliotheken gesteuert. Damit wird effektiv die Client-Server Fähigkeit geopfert um ein möglichst schlankes Programm ohne extra Server zu erzeugen. Solche DBS nennt man auch embedded.

    1.1 Was ist SQL?

    Wie schon erwähnt stammt das Datenbank-Prinzip noch aus Zeiten als vor allem mittels Konsolen-Terminals gearbeitet wurde. Auch heute bieten viele DBS einen Konsolenzugang an, zu erreichen über einen mitgelieferten Minimalclient oder gar über Telnet. Dadurch kann man den Server über eine Komnmandozeile steuern, was heute nur noch von Entwicklern und Administratoren genutzt wird.
    Doch das der Kommandozeile zugrundeliegende Protokoll ist dann auch die Basis für die Kommunikation zwischen jedem anderem, GUI-fähigen Client und dem Server. Jeder noch so schicke und bequeme Datenbank-Client wandelt intern alle Aufgaben in die alten Kommandozeilen um und sendet diese an den Server.
    Um das Protokoll zu verallgemeinern wurde SQL eingeführt. Es definiert eine standardisierte Syntax die alle nötigen Datenbank-Aktionen beschreiben kann : Eintragen, Aktualisieren und Löschen von Datensätzen, Ausführen von Abfragen mit hohem Komplexitätspotential, Manipulation der Datenstrukturen sowie Benutzerverwaltung. Da SQL ja auch per Hand in die Kommandozeile eingegeben werden können soll ist es textbasierend und von Menschen lesbar.
    Die Details von SQL sprengen den Rahmen dieses Artikels, deshalb sei hier verwiesen auf das Datenbank-Forum oder externe Tutorials und Referenzen.

    Wer sich mit den Hintergründen des C++ Standards auskennt wird ahnen das auch SQL nicht monolithisch ist. Auch hier gibt es mehrere Versionen die über die Jahre entstanden sind. Es gibt Herstellerspezifische Erweiterungen und Änderungen. Manche DBS bieten gar nur einen (am häufigsten benutzen) Teil des Standards. Viele Hersteller von DBS bieten deshalb eine umfangreiche Dokumentation an die alle Möglichkeiten und Funktionen erklären, oft auch inklusive einer spezifischen SQL-Referenz.

    1.2 Vergleich mit einem Dateisystem

    Es gibt durchaus Ähnlichkeiten des Datenbank-Prinzips mit dem des Dateisystems. Auch Dateisysteme sind strukturiert, sind teilweise netzwerkfähig (über das Einbinden von Netzwerkressourcen in das lokale Dateisystem) und erlauben die Vergabe von Benutzerrechten.
    Man kann die Datensätze einer Datenbank mit den Dateien eines lokalen Laufwerks vergleichen, und auch die hierarchische Verzeichnisstruktur ist abbildbar. Allerdings definieren Datenbanken eine wesentliche strengere Einteilung (Hierarchie von oben nach unten) :

    • Server (manchmal auch Host genannt), meistens mittels IP-Nummer und -Port identifiziert
    • Datenbank als inhaltlich abgeschlossene Datensammlung. Jede SQL-Anweisung operiert innerhalb einer Datenbank, niemals über die Grenzen einer Datenbank hinaus
    • Schema als Gruppierung von Tabellen, ähnlich den Namespaces von C++
    • Tabelle als eigentlicher Datencontainer

    Nicht alle DBS implementieren alle Ebenen. Einige lassen die Schemas weg, bei embedded DBS fällt die Server-Identifikation weg und die Datenbank entspricht einer lokalen Datei.

    Es gibt aber auch Unterschiede zwischen Dateisystem und Datenbank. Der wichtigste ist das Datensätze im Gegensatz zu Dateien eine genaue innere Form haben. Zu jeder Tabelle gehört nämlich eine Reihe von Spalten mit festgelegtem Typ und sonstigen Attributen. Es gibt eine ganze Reihe von grundlegenden Spaltentypen wie VARCHAR, INT, DECIMAL oder DATE. Und genau wie C++ beim Kompilieren darauf achtet das Wert und Variablentyp zueinander passen, achtet auch die Datenbank darauf das nur Datensätze in die Tabelle kommen deren Werte den Spaltentypen entsprechen.
    Dafür speichert die Datenbank keine weiteren Metadaten zu Datensätzen wie man es vom Dateisystem gewohnt ist, wie zum Beispiel Dateiname oder Änderungsdatum. Alles was zu einem Datensatz gehört wird als Spalte angegeben.

    Wichtig : Datenbanken kennen keinen "Papierkorb" oder Bestätigungsnachfragen. Jede Änderung, jedes Löschen wird sofort und unwiderruflich ausgeführt.

    2 Entscheidung für oder gegen ein DBS

    Viele Programmierer erstellen im Laufe ihrer Ausbildung auch mal eine einfachste Adressverwaltung. Es geht darum Dateizugriff, Datenstrukturen und Kontrollstrukturen zu üben. Der Kern ist meistens eine Klasse für eine Adresse

    enum Gender {gFemale, gMale};
    
    class Address
    {
      std::size_t number; // Eindeutige Nummer für jeden Eintrag, größer 0
      std::string country;
      std::string city;
      std::string postcode;
      std::string street;
      std::string lastname;
      std::string firstname;
      time_t birthdate;
      Gender gender;
      std::size_t partner; // Nummer des Lebenspartners, 0 wenn nicht vorhanden
    };
    
    std::vector<Address> adresses; // interne Liste der vorhandenen Adressem
    

    Die Daten werden über std::fstream in eine Datei geschrieben, sei es binär oder textorientiert im CSV-Format. Zusammen ergibt das eine funktionierende Anwendung, in die man noch Such- und Sortieralgorithmen einbauen kann. Für den alltäglichen Einsatz wird man aber schnell die Funktionalität ausbauen müßen.

    2.1 Gründe für ein DBS

    Was gibt es also für Gründe die einen Wechsel zu einem externen DBS nahelegen?

    • Steigende Datenmenge und -komplexität
      Wenn man zehntausende Datensätze, verteilt auf mehrere relationale Tabellen, verwalten will kommt schnell an die praktischen Grenzen einer selbstgeschriebenen Datenhaltung im Speicher oder einer Datei. Genau diese Verwaltung und Speicherung ist die Basis eines jeden DBS. Für ein modernes DBS sind auch Millionen Datensätze kein Problem. Als Anwendungsprogrammierer braucht man im eigenen Programm nur noch die Daten im Speicher behalten die grade angezeigt werden.
    • Hohe Ansprüche an Datenkonsistenz
      Für viele professionelle Anwendungen ist die Wahrung der Datenkonsistenz noch wichtiger als die Anwendungsstabilität. Ein DBS kann unabhängig von der Anwendung zusätzliche Überprüfungen vornehmen. Das kann einzelne Felder betreffen (Eigenschaften Unique oder Required), Beziehungen zwischen Tabellen (über Foreign Keys), selber implementierte Funktionen (mittels Trigger und Stored Procedures) bis hin zu der zusammenfassung von einzelnen Aktionen zu einem Block (Transactions). Wichtig ist das das DBS diese Überprüfung unabhängig vom Client macht, selbst ein schlecht programmierter Client kann keine Änderung am DBS vornehmen die das DBS nicht zulassen darf.
    • Netzwerkfunktionalität
      Wichtige Daten sollen oft für mehrere Benutzer an verschiedenen Orten verfügbar sein. Hier bieten alle DBS (außer die genannten embedded DBS) bereits ein LAN- und WAN-fähigen IP-Zugang an, erlauben also eine transparente Netzwerkfunktionalität. Ob Client und Server auf dem selben Rechner (localhost, 127.0.0.1) laufen, auf einen Server im lokalen Netzwerk zugegriffen werden soll oder gar ein öffentlicher Server im Internet verwendet soll ist für den Anwendungsentwickler nicht wichtig, ein einfaches Ändern der Serveradresse im Client reicht aus.
    • Benutzerverwaltung
      Wer eine Datenbank für viele Benutzer im Netzwerk freigibt will sicher nicht allen User alle Zugriffsrechte gewähren. Hier haben DBS bereits eine eingebaute Benutzerverwaltung mitsamt sehr stark abstufbarer Benutzerrechte.
    • Standardisierung durch SQL
      SQL ist eine sehr verbreitete erprobte Sprache mit vielen Möglichkeiten, die einem Anwendungsentwickler sehr viel Planung und Arbeit im Vergleich zu einer selbstgeschriebenen Verwaltung abnimmt.
    • Verschiedene Clients
      Mit der Auslagerung der Daten in ein DBS sind die Daten auch zugänglich für andere Clients. Als Beispiel die Angebotsdatenbank eines Internet-Shops, die einerseits über einen Client in C++ für die internen Mitarbeiter verwaltet wird, aber gleichzeitig über einen Webserver mit PHP auch direkt für die Kunden aus dem Internet zugänglich ist. Beide Clients arbeitet direkt zusammen, aber haben außer dem DBS keine weiteren Verbindungen nötig.
    • Zusätzliche Funktionen des DBS
      Ein gutes DBS bietet nicht nur eine rein passive Speicherung, sondern weitere reaktive Funktionen wie Views, Trigger, Funktionen oder Sequenzen. In einem gut designten Datenbankschema nimmt das DBS viele Aufgaben vom Client ab. Je komplexer das Schema werden soll desto mehr lohnt es sich alle Möglichkeiten des DBS auszureizen.

    2.2 Gründe gegen ein DBS

    Was spricht gegen ein DBS von der Stange?

    • Zusätzliche externe Software
      Ein Datenbank-Server ist eine zusätzliche, nicht gerade kleine Software die installiert, konfiguriert und gewartet werden muß. Für eine einfache Adressdatenbank doch sehr aufwändig. Dieser Nachteil läßt sich mit eines embedded DBS auschalten, aber dafür verliert man auch die Netzwerkfunktionalität.
    • Komplexität
      Wer zum ersten mal mit einem DBS arbeitet muß sich erstmal mit den Möglichkeiten und Eigenheiten vertraut machen, der Lernaufwand ist hoch. Wer aber sich einmal damit vertraut gemacht hat wird schnell die Ähnlichkeit zwischen einzelnen DBS feststellen und dann bei weiteren Datenbank-Programmen umso schneller und sicherer zum Ziel kommen.
    • Größerer Planungsaufwand
      Beim Design eines Datenbank-Schemas kann man als Anfänger vieles ungewollt falsch machen. Es ist sehr wichtig das Datenbank-Konzept fertig geplant zu haben bevor auch nur eine Programmzeile geschrieben wurde. Größere konzeptionelle Änderungen im laufenden Betrieb sind aufwendig und zeitraubend.
    • Sicherheit
      Da die meisten DBS öffentlich erhaltbare Software sind und für viele sehr wichtige Daten eingesetzt werden sind sie ein beliebtes Angriffsziel. Für veraltete Versionen eines DBS gibt es wahrscheinlich schon Beschreibungen von Sicherheitslücken, so das ein öffentliches DBS immer von einem Administrator auf dem neuesten Stand werden muß. Dazu kommen noch die allgemeinen Angriffe wie Traffic-Sniffen (bedingt durch das textbasierte nicht verschlüsselte SQL-Protokoll) oder SQL-Injektion. Ein DBS ist nicht automatisch sicher, nur dann wenn je nach Anwendungszweck auch eine vernünftige Konfiguration verwendet wird.
    • Mangelde Spezialisierungsmöglichkeiten
      Nicht alle Datensammlungen sind geeignet für ein DBS. Zum Beispiel wenn die Daten sich nicht ein festes Muster aufteilen lassen und deshalb keine Tabellen mit festen Spalten verwendet werden können. Oder das der geringe aber doch meßbare Overhead durch Protokoll und Server doch noch zu hoch ist. Für solche Zwecke ist eine maßgeschneiderte Einzellösung vorzuziehen.


  • Hi akari.

    Der Artikel gefällt mir bis jetzt sehr gut (auch wenn ich persönlich nicht so viel Neues gelernt habe), er liest sich ziemlich gut und gibt eine schöne Übersicht.
    Was ich ein wenig ändern würde, ist der Titel ("Einführung in die Einbindung von Datenbanken in C++"). Denn in dem Theorieteil geht es ja nicht um C++, sondern um Datenbanken allgemein; insofern verspricht der Titel weniger als im Artikel zu finden ist.
    Mein Vorschlag (nur leicht abgewandelt): "Einführung in Datenbanken und deren Einbindung in C++"



  • Hi akari,

    hab den Artikel kurz überflogen, und finde ihn als Einstieg gut.

    Für den Praxisteil solltest du evtl. mal einen Blick auf SOCI werfen:
    http://soci.sourceforge.net



  • Hallo

    Danke für eure Antworten.

    michba schrieb:

    Was ich ein wenig ändern würde, ist der Titel ("Einführung in die Einbindung von Datenbanken in C++"). Denn in dem Theorieteil geht es ja nicht um C++, sondern um Datenbanken allgemein; insofern verspricht der Titel weniger als im Artikel zu finden ist.
    Mein Vorschlag (nur leicht abgewandelt): "Einführung in Datenbanken und deren Einbindung in C++"

    Ja das werde ich ändern.

    phlox81 schrieb:

    Für den Praxisteil solltest du evtl. mal einen Blick auf SOCI werfen:
    http://soci.sourceforge.net

    Ja das sieht interessant aus. PostgreSQL wollte ich als Backend nehmen, das hat zwar schon eine eigene ordentliche C++ Schnittstelle aber das werde ich auf jedenfall auch mal ausprobieren!

    bis bald
    akari



  • Habs auch mal nur ganz kurz überflogen, liest sich angenehm.
    Was mir aber auf die Schnelle aufgefallen ist, ist bei Kapitel 2.2 (Entscheidung gegen ein DBS) der Unterpunkt Sicherheit. Das halte ich zumindest für stark diskussionswürdig: SQL-Injections haben z.B. eigentlich nichts mit Sicherheitslücken einer Datenbank zu tun, sondern vielmehr mit schlampiger Programmierung (d.h. es liegt am Anwendungscode). Und auch ansonsten sehe ich da weniger Sicherheitsprobleme, da Clients in der Praxis eh nie direkt mit der Datenbank kommunizieren, sondern mit dem entsprechenden Code, der davorsteht und dann seinerseits einfach auf die Datenbank zugreift.
    Bzw. allgemein gesagt: Es gibt immer ein generelles Sicherheitsproblem wenn man Dienste nach außen ins Netz zur Verfügung stellt. Ob das nun ein DBMS oder eine selbst geschriebene Anwendung ist, spielt dabei keine Rolle. Wobei ich da dann doch noch eher dem DBMS trauen würde (bewährt, und bei kommerziellen Produkten hat der DBMS-Anbieter die Schuld).

    Ok, und wenn ich schon dabei bin 😉 Den allerletzten Punkt "Mangelnde Spezialisierungsmöglichkeiten" find ich auch etwas diskussionswürdig. Wenn man strukturierte Daten hat, dann bringt man die normalerweise schon auch in ner DB unter; natürlich kann hier der Mapping-Aufwand dann relativ groß werden, d.h. wenn dann würde ich eher das als Nachteil aufführen, dass man eben unter Umständen ein aufwändiges Mapping hat.
    Ansonsten hätte man meines Erachtens sowieso generelle Probleme solche "speziellen" Daten irgendwie zu speichern, unabhängig von Datenbanken...



  • Hallo

    nep schrieb:

    Was mir aber auf die Schnelle aufgefallen ist, ist bei Kapitel 2.2 (Entscheidung gegen ein DBS) der Unterpunkt Sicherheit. Das halte ich zumindest für stark diskussionswürdig: SQL-Injections haben z.B. eigentlich nichts mit Sicherheitslücken einer Datenbank zu tun, sondern vielmehr mit schlampiger Programmierung (d.h. es liegt am Anwendungscode). Und auch ansonsten sehe ich da weniger Sicherheitsprobleme, da Clients in der Praxis eh nie direkt mit der Datenbank kommunizieren, sondern mit dem entsprechenden Code, der davorsteht und dann seinerseits einfach auf die Datenbank zugreift.
    Bzw. allgemein gesagt: Es gibt immer ein generelles Sicherheitsproblem wenn man Dienste nach außen ins Netz zur Verfügung stellt. Ob das nun ein DBMS oder eine selbst geschriebene Anwendung ist, spielt dabei keine Rolle. Wobei ich da dann doch noch eher dem DBMS trauen würde (bewährt, und bei kommerziellen Produkten hat der DBMS-Anbieter die Schuld).

    Natürlich ist bei SQL Injection der Fehler beim Client zu suchen. Was ich aber mit dem Punkt Sicherheit klar machen wollte ist das die Möglichkeit der SQL Injection überhaupt erst deshalb zustande kommt weil das DBS SQL unterstützt. Wer sich der Konsequenzen dieser Eigenschaft nicht bewußt ist (wie sicher vieler Anfänger) wird deshalb schnell solche Sicherheitslücken im Client haben, die er mit einem eigenem, nicht SQL-fähigen DBS nicht hätte (siehe die erst vor kurzem hier im Forum gepostete Website die ganze SQL-Anweisungen in der URL hatte). Sowohl beim Konfugurieren der DBS als auch dem Programmieren des Client muß man sich also im besonderen mit der Sicherheitsproblematik auseinander setzen. Ein gut gesichertes DBS ist zweifelsohne sicherer als jedes selbst gebaute System. Ein schlecht bzw. nicht gesichertes DBS ist aber noch unsicherer als ein selbst gebautes System.

    ]Den allerletzten Punkt "Mangelnde Spezialisierungsmöglichkeiten" find ich auch etwas diskussionswürdig. Wenn man strukturierte Daten hat, dann bringt man die normalerweise schon auch in ner DB unter; natürlich kann hier der Mapping-Aufwand dann relativ groß werden, d.h. wenn dann würde ich eher das als Nachteil aufführen, dass man eben unter Umständen ein aufwändiges Mapping hat.
    Ansonsten hätte man meines Erachtens sowieso generelle Probleme solche "speziellen" Daten irgendwie zu speichern, unabhängig von Datenbanken...

    Richtig den letzten Punkt meine ich ja auch. Man darf nicht versuchen alles auf Teufel komm raus in ein DBS zu quetschen. Das führt dann zu Programmen die im laufenden Betrieb ständig Tabellen erstellen und ändern, weil die Anforderungen sich geändert haben. Oder Tabellen die aus 100 VARCHAR-Spalten bestehen, bezeichnet von "col_1" bis "col_100" damit auch ja alles in die Tabelle passt. Davor wollte ich warnen.

    bis bald
    akari


Anmelden zum Antworten