Vier Fragen an alle, die an Unternehmensanwendungen arbeiten:

  1. Würde irgend jemand auf die Idee kommen, ein zentrales Verzeichnis anzulegen, in der die aktuelle Version des Quellcodes für ein Projekt liegt, und das von allen Entwicklern gleichzeitig genutzt und bearbeitet wird? Natürlich nicht, denn es wäre praktisch unmöglich etwas konsistent zu kompilieren, ständig wäre die eine oder andere Datei in Bearbeitung und daher unbenutzbar.
  2. Würde irgend jemand auf die Idee kommen, ein Programm auszuliefern, dass nicht einmal vollständig compiliert? Natürlich nicht, denn es würde bedeuten, das etwas nicht funktioniert, und das würde zumindest aus der Auslieferung entfernt werden.
  3. Würde irgend jemand es akzeptieren, wenn die ausgelieferten Jars/Exe, oder was immer man ausliefert, nicht identisch sind bei Kunden, die die selbe Version erhalten haben (Wenn man mal von Konfigurationsdateien absieht)? Wohl kaum.
  4. Würde irgend jemand ein Programm ausliefern, das nicht wenigstens einmal als ganzes getestet wurde? Wohl nur sehr wenige sehr 'wagemutige'.


Aber dennoch kann man dies in vielen Projekten beobachten, wenn eine Datenbank involviert ist. Mehr als einmal habe ich folgendes Vorgehen in Sachen Datenbank Entwicklung gesehen:Es gibt für das gesamte Team + N Kunden 2+N oder 2+2N Datenbanken: Entwicklung und Test vor Ort und für jeden Kunden entweder nur eine Produktionsdatenbank, oder eine Integrations- und eine Produktionsdatenbank. Das heißt alle entwickeln auf der selben Datenbank (vgl. 1.). Zu einem bestimmten Zeitpunkt wird der aktuelle Stand auf die Testdatenbank gebracht. Die dafür verwendeten Skripte sind meist ungetestet und daher fehlerhaft. Wenn solche Fehler entdeckt werden, werden sie nach bestem Wissen und ohne Gewissen behoben, ohne sie erneut zu testen. Diese Skripte werden in einem späteren Schritt verwendet um das System beim Kunden zu aktualisieren (vgl. 4.). Da hierbei immer wieder Fehler entdeckt werden, werden die Skripte nachgebessert. So dass bei jedem Kunden eine geringfügig andere Version installiert ist (vgl. 3.).

Da es keinen konsistenten reproduzierbaren Stand gibt, laufen Schemata immer weiter auseinander und können nur durch den heroischen Aufwand einzelner halbwegs identisch gehalten werden. Nicht selten finden sich dabei Bestandteile im Schema, die nicht kompilieren, die in anderen Varianten des selben Schemas aber gar nicht vorhanden sind. Aber da man nie weiß, ob das nicht noch jemand benötigt, werden die Leichen nicht oder nur bei unregelmäßigen Aufräumaktionen beseitigt.

Es gibt zwei Gründe für diese Missstände:

  1. Datenbanken sind doof. Bei einer Anwendung in Form einer EXE / eines Jars wird bei einem Update die alte Version weggeschmissen, und eine neue installiert. Bei Datenbanken geht das so nicht. Die alten Daten müssen aufwendig migriert werden.
  2. 80% der Datenbankentwickler haben von Softwareentwicklung keine Ahnung. Ich vermute dies liegt darin, dass die meisten Datenbankentwickler nur Datenbankentwicklung betreiben, und dies oft auch nur für eine Datenbank. Wogegen die meisten Softwareentwickler im Laufe ihrer Laufbahn eine ganze Reihe von Sprachen und Entwicklungsumgebungen kennen gelernt haben. Dieser Mangel an Ausweichmöglichkeiten ermöglicht es den Toolherstellern absolut essentielle Features (Refactoring, Codecompletion, Anbindung an Versionskontrolle, Integration von Difftools ...) nicht, nur bruchstückhaft oder nur gegen Aufpreis zur Verfügung zu stellen. Um Missverständnissen vorzubeugen: programmieren können die Datenbankentwickler, Analyse und Design mag auch zu ihrem Handwerkszeug gehören, es fehlen ihnen nur einige Kenntnisse in fundamentalem Softwareentwicklungsknowhow: Versionsverwaltung und Change- und Releasemanagement.


Aber genug des Lamentierens, wie geht es denn richtig?

  1. Eine Datenbank(schema) für jeden Entwickler (und Tester, Dokumentator oder wer sonst noch die Anwendung für seine Arbeit benötigt). Die großen Datenbankhersteller bieten für Entwickler kostenlose Versionen an, die lokal installiert werden können. Alternativ kann auf einem zentralen Server eine Datenbank mit mehreren Schemata eingerichtet werden.
  2. Alles was zum Schema gehört, kommt unter Versionskontrolle. Alle DBA's und Datenbankentwickler bitte nachsprechen: ALLES. Tabellen, Indizes, Views, Trigger, Stored Procedures, Migrationsskripte.
  3. Es muss einen einfachen Weg geben, um den aktuellen Stand der Datenbank in dem persönlichem Schema eines Entwicklers herzustellen. Für OLTP Anwendungen bevorzuge und empfehle ich die Schemagenerierung von Hibernate und ähnlichen Tools. Dies hat den Vorteil, dass die Definition des Schemas automatisch auch immer in der Versionsverwaltung mitgeführt wird, und man sich darum nicht mehr explizit kümmern muss.
  4. Es werden wenigstens zwei Arten von Skripten benötigt, die reproduzierbar Testdaten erzeugen: Einerseits Spieldaten, d.h. eine geringe Zahl von Datensätzen, die von den Entwicklern für Entwicklertests genutzt werden können. Andererseits Massendaten die in der Anzahl und der Komplexität vergleichbar sind mit den real produktiv zu erwartenden Daten. Diese werden benötigt um die Performance der Anwendung unter annähernd realistischen Bedingungen zu testen.
  5. Ein Schema für automatische Tests.


Mit diesen 5 Punkten ist sichergestellt, dass das Schema zu jeder beliebigen Version zeitnah wiederhergestellt werden kann. Bleibt noch ein Problem: Die oben angesprochene Migration. Spätestens ab der ersten Version, die beim Kunden ausgeliefert wird, kann man nicht mehr einfach das Schema neu erstellen, sondern es muss migriert werden. Die Skripte, die dies bewerkstelligen haben eine unangenehme Eigenschaft: Sie können bzw. dürfen im allgemeinen nur einmal auf einem Schema laufen. Ein Skript, dass zum Beispiel eine Spalte in einer Tabelle ergänzt würde beim zweiten Lauf einen Fehler verursachen. Also kommen bei jedem Release ein paar Aufgaben auf den Releasemanager zu:

  1. Die bisherige Version die beim Kunden installiert ist, wird in ein leeres Datenbankschema installiert.
  2. Das Schema wird mit Testdaten gefüllt. Idealerweise mit einem Abzug der Produktionsdatenbank. Dies stellt sicher, dass wenigstens unakzeptables Performance Verhalten und harte Datenfehler, zum Beispiel auf Grund von nicht befriedigten Constraints sofort auffallen.
  3. Das adäquate Changeskript wird identifiziert und ausgeführt.
  4. Die neue Version des Datenbankschemas wird aus der Versionsverwaltung geholt und in ein weiteres Schema installiert.
  5. Die beiden Schemata werden miteinander verglichen. Werden Abweichungen identifiziert, so werden die Changescripte korrigiert und das gesamte Verfahren wiederholt.


Es bleibt noch eine Frage: Woher kommen die Changescripte? Einige Tools (z.B. Toad) generieren solche Skripte, aber diese Tools haben zwei Probleme. Erstens haben sie erschreckend häufig Bugs. Toad z.B. versuchte zumindest noch in der letzten Version die ich genutzt habe, Unique Constraints und die dazu gehörigen Indizes beide einzelnd anzulegen, was zu unzähligen Fehlermeldungen bei der Skriptausführung führte, aber ich gehe mal davon aus, dass sich mit einiger Suche ein funktionierendes Tool finden lässt. Zweitens können dieses Tools naturgemäß nur DDL. Jeglich DML Statements entziehen sich ihrer Kontrolle. D.h. den Teil der Skripte, die die Daten aktualisieren müssen auf jeden Fall von Hand geschrieben werden. Mühselig, aber es geht kein Weg daran vorbei.

Wenn Releases in kurzen Abständen aufeinander folgen können die Delta Skripte jeweils für ein Release erstellt werden. Liegen mehr als wenige Wochen zwischen zwei Releases, so sollten die Changescripte direkt zusammen mit der jeweiligen Änderung erstellte werden und sollten dann auch in einem automatischen Test geprüft werden, der die oben beschriebenen 5 Punkte automatisch ausführt. Deutlich detailliertere Gedanken über die Erstellung und Verwaltung von Change Scripten hat sich K. Scott Allen gemacht.

Das alles ist viel Aufwand? Stimmt, gerade beim ersten mal steckt man eine Menge Arbeit in die geeignete Infrastruktur. Aber wer zahlende Kunden hat, schuldet ihnen Qualität, und wenn es sich um ein ernst zu nehmendes Projekt handelt, lohnt es sich ganz sicher in diese Fragestellungen ein wenig Gehirnschmalz zu stecken. Wie sicher jeder bestätigen kann, der einmal genötigt war ein halbes Dutzend Schemata synchron zu halten.

Talks

Wan't to meet me in person to tell me how stupid I am? You can find me at the following events: