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.
Certstream, InfluxDB, Grafana und Netflix
16.04.2019
Nachdem ich vor kurzem über mein erstes Spielen mit dem certstream berichtete, habe ich weitere Experimente gemacht und die Daten zur besseren Auswertung in eine InfluxDB gepackt, um sie mit Grafana untersuchen zu können.
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...
Die sQLshell hat eine weitere Integration erfahren - obwohl ich eigentlich selber nicht viel dazu tun musste: Es existiert ein Projekt/Produkt namens steampipe, dessen Slogan ist select * from cloud; - Im Prinzip eine Wrapperschicht um diverse (laut Eigenwerbung mehr als 140) (cloud) data sources.
Weiterlesen...Nach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2024 folgt hier gleich die nächste:
Weiterlesen...Da ich seit nunmehr einem Jahr bei meinem neeun Arbeitgeber beschäftigt und damit seit ungefähr derselben Zeit für Geld mit Python arbeite, haben sich gewisse Antipathien gegenüber Python vertieft (ich kann mit typlosen Sprachen einfach nicht umgehen) - aber auch einige meiner Gründe, Python zu lieben sind ebenso stärker geworden. Einer davon ist der Fakt, dass eine Methode in Python mehr als einen Wert zurückgeben kann.
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.