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));
Die Spalte logicalrow spielt hierbei die Rolle der Rownumber in traditionellen Datenbanksystemen und legt zusammen mit colspecref fest, welche der Datensätze in dieser Tabelle zur gleichen Zeile im virtuellen Datenmodell gehören:
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.
Multi-User-WebDAV, Docker, GitHub
17.11.2019
Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...
Weiterlesen...Android Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Go GUI Gui Hardware Java Jupyter Komponenten Links Linux Markdown Markup Music Numerik OpenSource PKI-X.509-CA Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
In eigener Sache...
Weiterlesen...Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.
Weiterlesen...Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.
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, muss 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 Codeberg-Repositories findet man hier.