Grundsätzliches zu Datenbanken

Datenbank-Operationen ...

Die weitaus meisten Einsatzgebiete von Computern sind Datenbank-Applikationen. Dabei passieren eigentlich immer nur vier Dinge: Datensätze werden eingefügt, gelesen, geändert oder gelöscht.

Was datenbank-intern dabei passiert interessiert den Anwender i.d.R. nicht, wohl aber, wie sich die Aktionen für ihn auf seinem grafischen Frontend darstellen, insbesondere ob z.B. die Bedienung intuitiv ist. Genau hier liegt die Herausforderung für den Programmierer. Betrachten wir mal die genannten vier Aktionen im einzelnen im Hinblick auf die daraus resultierenden Anforderungen an ein "gutes" Programm.


... im Detail

Datensatz einfügen

Hierbei geht es stets um genau einen Datensatz. Für das GUI (= "Grafische User-Interface") heißt das: Es muß eine Bildschirm-Maske vorhanden sein, die für jedes Feld des Datensatzes ein Texteingabefeld besitzt, in das der Anwender die gewünschten Inhalte eingeben kann, sowie ein „Einfügen“-Button, der den (datenbankinternen) Insert-Befehl letztlich auslöst.

Ein "gutes" Programm zeichnet sich hier durch "gute" Plausibilitätsprüfungen aus. Natürlich könnte das Programm, nachdem der Anwender den "Einfügen"-Button betätigt hat, das ganze Zeug, welches der Anwender in der Maske eingegeben hat, stumpf an den Datenbank-Server senden und sagen: "Verbuch dat mal ...". bei ist es sinnvoll, verschiedene Plausis einzusetzen, die ggf. vor Ausführung des Inserts prüfen, ob die vom Anwender eingegebenen Feldinhalte plausibel sind, d.h. ob etwa der Inhalt eines Datumsfeldes von der Struktur her ein plausibles Datum darstellt. Solche Prüfungen können naturgemäß immer nur systaktische Prüfungen sein, nie (oder allenfalls höchst selten) semantische. Will sagen, daß eine solche Prüfung zwar feststellen kann, daß „33.14.2012“ kein plausibles Datum ist und daraufhin eine entsprechende Fehlerbehandlung auslösen kann, niemals aber, daß – wenn der Anwender z.B. „24.12.2012“ eingegeben hat – er in Wirklichkeit aber den „25.12.2012“ meinte. Des weiteren kann es Felder geben, die – im Gegensatz zu anderen Feldern - zwingend einen Inhalt haben müssen. Auch das kann geprüft und mit einer Fehlerbehandlung versehen werden.

Es gibt eine weitere mögliche Komplikation, die erst in dem Moment zum Tragen kommt, wenn der Insert-Befehl tatsächlich ausgeführt wird: Datensätze, bei denen ein Feld (oder mehrere Felder zusammen) einen eindeutigen Schlüssel („unique Key“) darstellt, kann es sein, daß der vom Anwender eingegebene Datensatz über einen unique Key verfügt, der in der betreffenden Tabelle der Datenbank bereits vorhanden ist. Das Ausführen des Insert-Befehls würde hier unweigerlich zu einem Datenbankfehler („Duplicate Key Error“) führen. Es empfiehlt sich daher, einen Insert-Befehl immer innerhalb eines „try: … error: ...“-Konstrukts auszuführen und im „error“-Zweig eine entsprechende Fehlerbehandlung auszuführen.

Datensätze lesen

Jeder Select-Befehl liefert ein Resultat in Form einer (im mathematischen Sinne) Menge von Ergebnis-Datensätzen. Diese können alle Felder des Datensatzes umfassen („select * from ...“) oder auch nur einen Teil der vorhandenen Felder („select , feld<2>, … from ...“), je nach Formulierung der Projektion. Interessanter aber ist die Anzahl der selektierten Datensätze. Je nach Formulierung der where-Klausel kann die Resultat-Menge keinen, genau einen, oder mehrere (viele) Datensätze enthalten. Es ist wichtig, sich dessen bewußt zu sein, denn die Weiterverarbeitung der Resultat-Menge, insbesondere deren Visualisierung in dem GUI, hängt empfindlich (und durchaus nichttrivial) von der Anzahl der selektierten Datensätze ab. Denn i.d.R. will man ja die selektierten Einträge irgendwie anzeigen.

Datensätze löschen

Das Löschen von Datensätzen ist, jedenfalls hinsichtlich der Programmierung, ein trivialer Vorgang. Zwar ist auch hier ein Selektionsvorgang involviert („delete from where “) , die so selektierte Ergebnismenge soll aber nicht programmatisch weiterverarbeitet (visualisiert o.ä.), sondern lediglich stumpf gelöscht werden. Sowohl die Selektion als auch das sofort anschließende Löschen der Ergebnismenge passiert als datenbankinterner Vorgang – die Ergebnismenge tritt „nach außen“ gar nicht in Erscheinung. Dem Anwender – und auch dem Programmierer – kann es daher egal sein, ob die Ergebnismenge keinen, einen oder mehrere Sätze umfaßt.

Datensätze ändern

Das Ändern von Datensätzen erfordert – ebenso wie das Löschen – zunächst einen Selektionsvorgang. In der so erhaltenen Ergebnis-Menge werden dann in bestimmten Feldern die vorhandenen Inhalte durch neue Inhalte ersetzt, entsprechend der „set = “-Klauseln des update-Befehls. Beides, die Selektion wie auch das Ersetzen der Feldinhalte, sind wiederum datenbankinterne Vorgänge, die nach außen nicht in Erscheinung treten. Mögliche Komplikation hierbei ist, daß Feldinhalte geändert werden sollen, die unique Keys (oder Bestandteile davon) sind. Unique Keys aber können grundsätzlich nicht geändert werden- ein solcher update-Befehl muß unweigerlich fehlschlagen! Für den Programmierer heißt das, daß er (in Kenntnis der Datenbank-Struktur) hier eine Fallunterscheidung einbauen muß. Änderungen, die ausschließlich non-Key-Felder betreffen, werden einfach über den update-Befehl gehandelt. Sind aber Key-Felder von Änderungen betroffen, so gibt es nur die Möglichkeit, den Update eines Satzes zu ersetzen durch ein Delete des Satzes und anschließendes Insert des geänderten Satzes.

Man könnte nun sagen, „na gut, dann eben so“. Aber die Konsequenzen für die Programmierung sind u.U. weitreichender als auf dem ersten Blick ersichtlich. Angenommen, ich habe ein Feld namens „Discounter“, welches kein Schlüsselfeld ist, und ich will in allen Datensätzen, in denen dort „Aldi“ steht, dieses durch „Lidl“ ersetzen, so genügt ein Update-Befehl:

    update {tabelle}
    set    discounter=“Lidl“
    where  discounter=“Aldi“;
  

Dabei kann es mir egal sein, ob es zwei oder 10000 Sätze sind, die die where-Klausel erfüllen.

Ganz anders sieht es aus, wenn „Discounter“ ein Key wäre. Dann wäre ich gezwungen, durch eine entsprechende programmatische Schleife jeden einzelnen Satz zu lesen (select), ihn zu löschen (delete - als Einzelsatz!), und ihn mit geändertem Inhalt des Feldes „Discounter“ wieder zu speichern (insert).

Ohne jetzt ins Detail zu gehen (erfolgt an anderer Stelle): Das ist aber 'ne ganz andere Nummer!


Gefährlichkeit der Datenbank-Operationen

Bei der Betrachtung der „Gefährlichkeit“ von Datenbank-Operationen ergibt sich folgende Reihenfolge:

Datensätze lesen

Völlig ungefährlich! Egal welchen Mist ich bei der Formulierung des select-Statements auch mache, es wird jedenfalls nur gelesen. Vielleicht nicht das, was ich in Wirklichkeit lesen will, aber ich kann jedenfalls in der Datenbank nichts „kaputt machen“.

Datensätze einfügen

Hier könnte ich irgendwelchen Müll einfügen – also schon mal nicht ganz so ungefährlich wie ein reiner select. Merke ich den Fehler aber sofort, so kann ich den fehlerhaften Datensatz – ggf. über das CLI der Datenbank (z.B. „mysql“) unverzüglich wieder löschen, und der Fehler wäre behoben. Aufwendig und lästig – aber machbar.

Datensätze updaten oder löschen

Gefährlich! Hierbei wird Information vernichtet, die ohne anderweitige Vorkehrungen nicht rekonstruiert werden kann.

Dringende Empfehlung:

Datenbanken sind immer zu sichern! mysql bietet z.B. hier die Möglichkeit, über einen Datenbank-Dump eine Textdatei herzustellen, in der sowohl die Befehle zum Löschen und neu Erstellen der Datenbank als auch zum Befüllen mit dem zum Dump-Zeitpunkt aktuellen Datenstand enthalten sind. Meine Empfehlung: Beim Beenden des Datenbank-Programms immer einen Dump ziehen, wobei der Dateiname automatisch mit Datum und Uhrzeit des Dumps versehen werden muß. So kann man auf beliebige ältere Versionen des Datenstandes zurückgreifen, und die Dump-Dateien sind – als reine ASCII-Dateien – von keinem proprietären Programm abhängig.

zurück nach oben zurück zur Startseite