Im Job haben wir an einer Ausschreibung teilgenommen, die eine Java-Anwendung fordert, in der die Anwender neue Objekte definieren können sollen. Normalerweise würde das bedeuten, neue Tabellen in einer relationalen Datenbank anzulegen - leider würde das aber auch die Nutzung eines OR-Mappers, bzw. von Container Managed Persistence ausschließen.
Das erinnerte mich an eine unkonventionelles Datenmodell, das ich vor vielen Jahren mal bei einem Kunden sah: Er hatte eine Anwendung, in der eine relationale Datenbank für die Persistenz verantwortlich war. In dieser waren aber nur wenige Tabellen modelliert. In diesen Tabellen wurden die Tabellen des eigentlichen fachlichen Modells beschrieben. Damit konnte man durch simples Einfügen von Zeilen in den richtigen Tabellen Spalten zu fachlichen Tabellen hinzufügen, ohne das physische Datenmodell ändern zu müssen. Das bezeichne ich im folgenden als DBMS in Software.
Noch ein kleiner Exkurs: Wir haben natürlich darüber nachgedacht, Graph-Datenbanken in unsere Überlegungen einzubeziehen. Wir untersuchen auch einige andere Lösungsmöglichkeiten. Dieser Artikel dient wirklich lediglich dazu, meine Einsichten bei der praktischen Erprobung aufzuschreiben.
Zunächst einige Begriffsklärungen: Im folgenden werde ich mit physisches Datenmodell die tatsächlichen Tabellen im DBMS bezeichnen. Virtuelles Datenmodell umfasst die in diesen Tabellen definierten fachlichen Tabellen.
Ich probierte die nachfolgend dokumentierten Schritte in einer PostgreSQL-Datenbank der Version 9 aus. Zunächst benötigte ich eine Tabelle im physischen Datenmodell, die Informationen zu den Tabellen im virtuellen Datenmodell zu halten. Bei mir sah diese Tabelle wie folgt aus:
CREATE TABLE public.tablespec (
id serial NOT NULL,
name VARCHAR(255) , PRIMARY KEY (id));
Daran schloss sich die Erzeugung der Tabelle im physischen Datenmodell an, die die Spezifikationen der einzelnen Spalten des virtuellen Datenmodells speichern sollte:
CREATE TABLE public.columnspec (
id serial NOT NULL,
name VARCHAR(255) ,
tablespecref INTEGER REFERENCES tablespec (id) ,
PRIMARY KEY (id));
Schließlich fehlte noch die Tabelle, die die Daten aufnimmt, die in den Tabellen des virtuellen Datenmodells gespeichert werden sollten. Diese Tabelle ist wie folgt organisiert: jeder Spaltenwert in einer virtuellen Tabelle wird in einer Zeile dieser Tabelle gespeichert. Diese physische Tabelle enthält für jeden der im virtuellen Datenmodell unterstützten datentypen eine Spalte. Im Beispiel sind das zwei: Integer und String.
CREATE TABLE public.rowcontents (
id serial NOT NULL,
logicalrow INTEGER NOT NULL,
colspecref INTEGER REFERENCES columnspec (id) ,
stringval VARCHAR(255) ,
intval INTEGER , PRIMARY KEY (id));
CREATE UNIQUE INDEX tablefirstrows_idx ON rowcontents (colspecref, logicalrow);
Interessanterweise lässt sich ein UNIQUE-Constraint im virtuellen Datenmodell sehr einfach über folgendes Statement realisieren:
CREATE UNIQUE INDEX my_partial_ix ON rowcontents (intval) WHERE (colspecref = 6);
Wie kann man dieses virtuelle Datenmodell mittels traditioneller Werkzeuge nutzen? Ein Select-Statement, das den Inhalt der virtuellen Zeilen einer virtuellen Tabelle abfragt, lässt sich wie folgt realisieren:
select A.intval,B.stringval from (select
logicalrow,intval from rowcontents where colspecref=2) AS A
left join (select logicalrow,stringval from rowcontents where
colspecref=1);
Solche Abfragen können als Grundlage der Definition von normalen Datenbank-Views dienen. Damit kann man auf die Inhalte der virtuellen Tabellen mit Standard-Reporting-Werkzeugen zugreifen.
Zwei letzte Gedanke dazu: Mit etwas Aufwand ließe sich ein JDBC-Treiber zur Arbeit mit einer solchen Datenbank schreiben. Eine relativ einfache Möglichkeit, in Code auf Entities (Zeilen in den virtuellen Tabellen) zuzugreifen besteht darin, eine Facade zu erstellen, die etwa die Möglichkeiten der typsicheren Collections nutzt und Zugriffsmethoden zu nutzen wie im JDBC-Trebermodell, in dem die Spalten über Stringparameter bestimmt werden.
InfluxDB Appender für Log4J 1.x
17.03.2018
Nachdem ich vor einiger Zeit zwei Appender für Log4J 1.x vorgestellt habe, habe ich - motiviert durch meine Experimente mit Raspi und ADS-B - einen weiteren verfasst - diesmal zum Schreiben der Daten in eine Zeitreihendatenbank.
Weiterlesen...Android Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Git(lab|hub) Go GUI Gui Hardware Java Jupyter Komponenten Links Linux Markdown Markup Music Numerik PKI-X.509-CA Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
Ich habe mich ein wenig mit Attribut-Zertifikaten beschäftigt - Resultat sind einige Klassen zum leichteren Zugriff auf die enthaltenen Attribute...
Weiterlesen...Ich wollte eine Methode schaffen, neue Graphik-Primitiven, die zumindest in java.awt.Graphics2D - in Java noch fehlen, zu ergänzen.
Weiterlesen...Ich wollte eine Methode schaffen, unterschiedlichste Schraffuren in beliebigen Shapes zu erzeugen. diese Möglichkeit fehlt - zumindest in java.awt.Graphics2D - in Java noch.
Weiterlesen...Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.
Wer daran teilhaben und eventuell sogar davon profitieren möchte, muß damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.
Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...
PS: Meine öffentlichen GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.