Stranger Than Usual

Der inner-platform effect

So manche Antipattern habe ich bisher nicht oder nur in sehr milder Form gesehen. Der inner-platform effect ist eins davon. Dieses Antipattern beschreibt im Prinzip, dass eine sehr flexible gestaltete Software eine schlechte Nachbildung der Technologie enthält, mit der sie gebaut wurde. Bei Datenbanken passiert das gerne, wie auch die englische Wikipedia beschreibt:

In the database world, developers are sometimes tempted to bypass the RDBMS, for example by storing everything in one big table with three columns labelled entity ID, key, and value. While this entity-attribute-value model enables the developer to break out from the structure imposed by an SQL database, it loses out on all the benefits […].

Nun geht es immer noch komplizierter. In einem Projekt, an dem ich gerade beruflich arbeite, wird ein alter IBM-Mainframe ersetzt. Mein Projekt ist nur eines von vielen Projekten in diesem Zusammenhang bei dem Kunden. Die alten Daten aus dem Mainframe (die keine bezeichnenden Feldnamen haben sondern typischerweise Bezeichner nach dem Muster ABC80878 oder DEF1075, wurden bei der Migration dann nicht in ein schönes, passendes Datenbankschema übertragen, sondern in eine wie in dem Zitat aus der Wikipedia beschriebenen ID/Schlüssel/Wert-Struktur.

Nur dass das natürlich zu einfach wäre. Deswegen gibt es zunächst eine Tabelle, die alle Schlüssel enthält, und zwar mit einem Schlüsseltyp, einer Schlüssel-ID und einem Schlüsselnamen. Man kann sich dann über Schlüsseltyp und Schlüsselnamen die Schlüssel-ID holen. Die kann man dann mit einem INNER JOIN mit der Tabelle verbinden, in der die Werte zu der Schlüssel-ID in Kombination mit einer anderen ID (sagen wir mal, eine Account-ID) zu finden sind. Der Wert ist aber nur der möglicherweise überschriebene Wert, eventuell braucht man noch einen Default-Wert. Den holt man sich dann über ein LEFT JOIN noch mit herein. Und dann kommen da noch ein paar Kleinigkeiten, so dass man auf einen SELECT-Ausdruck mit zwei INNER JOINs, einem LEFT JOIN und noch einem inneren SELECT-Statement kommt.

Und dieser SELECT-Ausdruck wird dann wieder in einem größeren Ausdruck verwendet und zwar für jedes Feld, das man Abfragen will, einer. Dazu kommen noch ein paar andere verschachtelte SELECT-Statements und ein paar JOINs und WHEREs.

Am Ende hat man eine query, die über mehrere dutzend Zeilen Code geht, anstelle eines einfachen SELECT A, B, C from X inner join Y on X.id = Y.id where Y.foo = 'bar'; Und hier kommt wieder genau das „man verliert alle Vorteile des Datenbanksystems“ aus dem Wikipedia-Zitat ins Spiel: Die Abfrage liefert gerade einmal 22.000 Ergebnisse und braucht dafür 90 Sekunden. Und man kann hier nicht mal pagen, ein limit 100 dauert trotzdem 90 s, weil man sich mit dieser so komplexen Query über alle Datenbankindizes und Query-Optimierung der Datenbank hinwegsetzt.

Ein anschaulicheres Beispiel für den inner-platform effect habe ich noch nicht erlebt.