Datenbankdesign für Maschinenvergleich

Ich bräuchte dringend Beratung beim Entwurf eines Datenbankdesigns.

Ich muss eine Datenbank entwerfen, welche sämtliche Daten zu verschiedenen CNC-Maschinen speichert und auch gegeneinander vergleichen kann. Das Hauptproblem ist allerdings, dass die verschiedenen Entitäten einer Maschine einmal aus Strings, einmal aus Integers oder Floats oder gleich Feldern aus Integers bestehen können. Als noch etwas unbedarfter Datenbankdesigner stehe ich nun vor einem Problem - ich kann ja wohl schlecht alle Entitäten in eine fette Tabelle “machines” stopfen, oder? Meine Überlegung war, für jede Entität die eine Maschine haben kann, eine eigene Tabelle in der Datenbank anzulegen - das wären dann etwa so um die 60 Tabellen. Der Vorteil davon wäre, dass ich so auch ganz gut die deutsche Bezeichnung der Entität (zB Umlaufdurchmesser oder Drehmoment) und die Maßeinheit dazu speichern kann. Allerdings bedeutet das auch einen großen Aufwand - erstens zum Erstellen der vielen Tabellen und zweitens beim Joinen.

Meine Frage wäre nun: ist mein Ansatz ein guter bzw. ist er vlt. sogar der einzig saubere oder bin ich total auf dem Holzweg?

Sorry für den Doublepost, konnte leider keine Edit-Funktion finden.

Mein Datenbankkonzept sieht soweit so aus:

Doppelpost ist doch ok, weil so merkt man das du was neues geschrieben hast :wink:

wenn ich mir deinen Text oben durchelese und dein Model unten ansehe gefällt mir das ganz gut bis auf 2 Sachen
wenn ich das richtig lese würde ich das so interpretieren dass deine … bedeuten du hast mehrere von den generic ids? Was auch erklären würde warum zwischen den Generic IDs und den Maschinen eine 1:1 Beziehung ist
Wenn das so stimmt mag ich das nicht :wink:

Ändere die Beziehung so ab, lösche die Punkte und den generic_fk raus. Dafür wird aus der Beziehung zwischen machines und generic_attribute eine 1:m beziehung. Daher einfach bei generic_attribute eine Machine_id einfügen. So kannst du jedes Attribut einer Maschine zuordnen

Aber auf jeden Fall musst du die maschine_id aus den Metadaten löschen, weil sonst sagst du Metadaten Typ A gibt es nur in Maschine 1 in Maschine 2 gibt es kein A

Alles klar, werd’s dann morgen gleich versuchen. Nur hab ich irgendwie Sorge, dass sich das mit den Joins irgendwie nicht mehr ganz ausgeht bzw. die dann richtig ar***kompliziert werden :smiley:

hängt bisschen davon ab was du abfragen willst aber so komplex werden die nicht, und es bietet sich auch an zb die generic attribute und metadata Tabellen in einer view zusammen zufassen. Das spart dir einen Join

Daran hätte ich auch schon gedacht. Ich hab allerdings noch nie direkt mit View gearbeitet, kann ich mir das dann so als Tabelle mit Tabellen vorstellen? (logisch betrachtet natürlich)

Jep, das kann je nach Datenbank und Art des Views auch eine echte Tabelle werden, bei der musst du dich dann aber nicht über die Befüllung kümmern sondern das macht das DBMS

So hier mal mein überarbeitetes ER-Diagramm:

diese Datenbank funktioniert nicht, bzw. nur mit extrem viel Aufwand :wink:
Du musst bei einer Attribut Tabelle bleiben, weil warum willst du mehrere draus machen? Was für eine Art von Attribut es ist bekommst du doch über die Metadaten raus.

Du musst bei einer Attribut Tabelle bleiben, weil warum willst du mehrere draus machen? Was für eine Art von Attribut es ist bekommst du doch über die Metadaten raus.

Weil jedes Attribut einen anderen Datentyp benötigt. Eines braucht einen String, das andere einen Integer, das nächste gleich ein ganzes Array an Integers.

dann mach das anders, lege sie alle als VARCHAR ab und anhand des Typs/Metadaten weißt du ob es ein String oder eine Zahl ist.
Bei nem Array solltest du überlegen ob es sich vielleicht lohnt daraus mehrere Einträge zu machen, dazu müsstest du wahrscheinlich in den Metadaten irgendwie die Reihenfolge markieren. Sonst einfach mit Semikolon oder so getrennt im String ablegen und dann zum Vergleichen holst du sie halt am Stück raus und teilst sie auf.

Ist das dann denn noch wirklich sauber? Das nächste Problem ist nämlich, dass ich diese Daten dann auch noch vergleichen muss (welche Maschine ist am besten, welches am schlechtesten.

Wo willst du das vergleichen? In ner App oder in der DB?
In ner App, dann ist es egal. In ner DB dann geht das immer noch problemlos. Einzige Ausnahme sind die Arrays, aber mit denen wirst du so oder so einige Probleme bekommen :wink:

Dein Hauptproblem ist aber wenn du jetzt 20 verschiedene Attribut Tabellen machst ist, wie machst du dafür eine richtige Abfrage?

Eine andere Sache die ich mich gerade frage, eins ist klar int, double, float ist kein Problem abzuspeichern. Aber warum können Strings kommen? Was beinhalten sie?
Der andere Punkt über den du vieleeicht schon nachgedacht hast, oder noch nachdenken solltest. Wenn du einen Array bekommst 1,2,3,4 und eine andere Maschine hat 4,3,2,1 welche ist besser? Weil wenn du darauf irgendwie eine Formel anwendest die am Ende einen Wert ausspuckt, dann kannst du die ja gleich vor dem Einfügen ausführen und hast so keinen Array

Dein Hauptproblem ist aber wenn du jetzt 20 verschiedene Attribut Tabellen machst ist, wie machst du dafür eine richtige Abfrage?

Ich fürchte es sind sogar eher 60 ^^’

Aber warum können Strings kommen? Was beinhalten sie?

Meist technische Bezeichnungen (zB „MK 6“ für das Attribut „Zentrierspitze“). Die können/müssen allerdings nicht verglichen werden, weil die keinen echten Informationsgehalt über die Güte liefern.

Der andere Punkt über den du vieleeicht schon nachgedacht hast, oder noch nachdenken solltest. Wenn du einen Array bekommst 1,2,3,4 und eine andere Maschine hat 4,3,2,1 welche ist besser? Weil wenn du darauf irgendwie eine Formel anwendest die am Ende einen Wert ausspuckt, dann kannst du die ja gleich vor dem Einfügen ausführen und hast so keinen Array

Ich denke, dass in solchen Fällen meist entweder die jeweils höchsten bzw. niedrigsten Werte miteinander verglichen werden. Die anderen Werte müssen dennoch abgespeichert werden, da die ja dann später in der Gegenüberstellung angezeigt werden müssen. Ich hoffe darauf, dass es einen SQL-Befehl in dieser Richtung gibt: GET_MAX(INT_ARRAY). Im Moment weiß ich aber noch nichtmal ob man in SQLite überhaupt solche Datenfelder speichern kann.

Edit: Mir ist gerade noch etwas eingefallen. Um beliebig lange Zahlenketten zu speichern, könnte ich doch eine zusätzliche Tabelle [integer_values] einführen, welche eine Referenz auf [attribute_metadata] enthält. Dazu müsste ich dann bei [attribute_metadata] noch ein eigenes Feld für den jeweilig verwendeten Datentyp einführen (1 = einfache Zahl, 2 = Zahlenfeld, 3 = String, etc.). Dafür würden dann natürlich die vielen Attribut-Tabellen wegfallen.

Ok, hier mein Vorschlag:
Speichere alles als VARCHAR, in der Tabelle Metadata hast du ja den des Attributs festgelegt daher weißt du ja ob es ein INT/STRING… ist (Weil du weißt ja ID 1 ist A und A hat als Wert einen int oder du fügst noch eine Spalte ein die das genau sagt was sauberer ist)
Speichere Arrays als VARCHAR, weil SQLite kann keine Arrays soweit ich weiß, vergleichen musst du die dann halt mit deinem Programm, bzw wenn SQLLite StoredProcedures anbietet könntest du eine Funktion schreiben um Arrays zu vergleichen.

Wenn du deine Daten loggen willst solltest du in jedem Datensatz aber auch ein Datum einfügen um zu wissen welches wozu gehört.

Ich weiß nicht so recht, irgendwie missfällt es mir extrem sämtliche Werte als Strings abzuspeichern. Immerhin verstößt das total gegen das was wir in der Datenbankübung gelernt haben.

Ich hab es jetzt mal mit diesem Ansatz versucht, weiß aber noch nicht ob die Beziehungen alle richtig gesetzt sind:

wieso verstößt das? Nur die Arrays verstoßen dagegen.
Wenn du ein richtiges DBMS benutzen würdest könntest du sagen die Spalte ist ein Object und du schmeißt VARCHARs, INTs oder Arrays rein

Du kannst das so machen wie du es da gemalt hast, aber glaub mir das gibt grauenvolle komplexe Abfragen. Ich würde auch darauf tippen dass du früher oder später Probleme bekommen wirst. Auch wenn mir gerade kein Beispiel einfällt.

Ich werd mal ein bisschen herumspielen und ein paar Testabfragen machen um zu sehen wie komplex das ganze tatsächlich wird. Auf jeden Fall mal herzliches Dankeschön, dein Input hat mir schon wesentlich weitergeholfen! :slight_smile: