Struktur für Objekte mit unterschiedlichen Eigenschaften

Jan2016

Neuer Benutzer
Beiträge
4
Guten Morgen,
ich entwickle eine Anwendung unter VB .NET. Meine Daten speichere ich einer SQLite DB.
Jetzt stehe ich vor einer Anforderung, für die ich Hilfe benötige.
Ich habe eine Menge an Objekten/Assets, die unterschiedliche Eigenschaften haben. Die Eigenschaften sind nicht bekannt.
Ich stelle mir vereinfacht folgende Tabellen vor:


Table "Assets"

ID | Name
-------------
1 | Asset1
2 | Asset2
3 | Asset3


Table "Properties"

ID | AssetID | Property | Value
-----------------------------------
1 | 1 | Prop1 | Val1
2 | 1 | Prop2 | Val2
3 | 1 | Prop3 | Val3
4 | 2 | Prop1 | Val1
5 | 2 | Prop2 | Val2
6 | 3 | Prop2 | Val2
7 | 3 | Prop3 | Val3
8 | 3 | Prop4 | Val4


Im Ergebnis würde ich mir Folgendes vorstellen:


View "AssetProperties"

Asset | Property1 | Property2 | Property3 | Property4
--------------------------------------------------------
Asset1 | Val1 | Val2 | Val3 | ----
Asset2 | Val1 | Val2 | ---- | ----
Asset3 | ---- | Val2 | Val3 | Val4


Die View "AseetProperties" muss nicht dynamisch sein, d.h. ich werde wissen, welche Properties angezeigt werden sollen. Soweit meine Überlegungen. Falls eine andere Struktur mehr Sinn macht, bin ich flexibel.
Ich freue mich auf Eure Vorschläge.

Gruß
Andreas
 
Werbung:
Danke für den Eav Hinweis. Das war mir nicht bekannt und ich werde mich bei Zeiten mal darüber informieren.
Postgre ist keine Option, da ich die DB nicht wechseln werde.
Ich könnte mir natürlich die View problemlos über. NET zusammen bauen, das möchte ich aber eigentlich vermeiden.
Gibt es denn einen EAV Ansatz für SQLite? Alternative Vorschläge sind gerne willkommen.
Gruß Andreas
 
Ich könnte mir natürlich die View problemlos über. NET zusammen bauen,

Das klingt nach FAIL. Dann nutzt Du die DB nur als dumme Datenhalde, dann kann die DB nix für Dich optimieren etc. Da kannst auch gleich eine Textdatei nehmen.

Mal jetzt ganz simpel, einfach mit numerischer objekt_id :

Code:
test=*# select * from jan2016 ;
 objekt_id | eigenschaft |  wert  
-----------+-------------+--------
  1 | farbe  | rot
  1 | gewicht  | 12kg
  1 | laenge  | 1m
  2 | farbe  | blau
  2 | laenge  | 2m
  2 | alter  | 4jahre
(6 Zeilen)

test=*# select   
  objekt_id,
  string_agg(wert,'') filter (where eigenschaft = 'farbe') as farbe,
  string_agg(wert,'') filter (where eigenschaft = 'gewicht') as gewicht,
  string_agg(wert,'') filter (where eigenschaft = 'laenge') as laenge,
  string_agg(wert,'') filter (where eigenschaft = 'alter') as alter
from
  jan2016
group by
  objekt_id;
 objekt_id | farbe | gewicht | laenge | alter  
-----------+-------+---------+--------+--------
  1 | rot  | 12kg  | 1m  |
  2 | blau  |  | 2m  | 4jahre
(2 Zeilen)

test=*#
 
Das klingt nach FAIL. ... Da kannst auch gleich eine Textdatei nehmen.
Das sehe ich nicht so! Für mich ist die DB tatsächlich nur ein Datenspeicher.
Allerdings nutze ich LINQ To SQL um die Daten mit meinem Objektmodell zu binden. Da ist mir kein Weg über eine Textdatei bekannt.
Für mich passt das so.
Ich bedanke mich für das übermittelte Beispiel, allerdings stehen die verwendeten Funktionen nicht in SQLite zur Verfügung.
Wie schon erwähnt, war der Hinweis auf das EAV Modell für mich sehr hilfreich und der Schlüssel zur Lösung.
Ich konnte hier (SQL Pivot in allen Datenbanken: MySQL, MariaDB, SQLite, PostgreSQL, Oracle, …) die passende und SQLite-kompatible Lösung finden.

Hier noch meine komplette Lösung:

CREATE TABLE [Assets] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Name] VARCHAR);

CREATE TABLE [Properties] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[AssetID] Integer NOT NULL CONSTRAINT [fk_Properties_Assets] REFERENCES [Assets]([ID]),
[Property] VarchAR,
[Value] VARCHAR);

CREATE VIEW [AssetProperties] AS
SELECT Assets.Name AS Asset
, MAX(CASE WHEN Property='Prop1' THEN Value Else '---' END) AS Property1
, MAX(CASE WHEN Property='Prop2' THEN Value Else '---' END) AS Property2
, MAX(CASE WHEN Property='Prop3' THEN Value Else '---' END) AS Property3
, MAX(CASE WHEN Property='Prop4' THEN Value Else '---' END) AS Property4
FROM Assets INNER JOIN Properties ON Assets.ID = Properties.AssetID
GROUP BY Assets.Name;

Gruß und schönen 3. Advent
Andreas
 
Das sehe ich nicht so! Für mich ist die DB tatsächlich nur ein Datenspeicher.

Der Punkt ist: das skaliert schlecht. Wenn Du mit Datenbanken im Bereich von einigen hundert GB oder gar im Bereich einiger TB arbeitest, dann wird es nicht funktionieren, für z.B. Aggregationen die Daten immer aus der DB in eine wie auch immer aufgebaute Applikation zu tragen und das dann dort zu machen. Also: je größer die DB, desto mehr wirst Du gezwungen sein, die DB nicht nur als Datenhalde zu nutzen.

Du hast ja inzwischen einen Weg gefunden - da in SQLite die Filter - Konstruktion nicht verfügbar ist ist das der beste Weg.
 
Werbung:
Wenn Du mit Datenbanken im Bereich von einigen hundert GB oder gar im Bereich einiger TB arbeitest, dann wird es nicht funktionieren
Das kann ich nachvollziehen, meine DB wird aber eher im Bereich von 10-100 MB haben und das auch nur, weil ich BLOBS für Thumbnails mit speichere.
Ich würde bei der Struktur und View jetzt bleiben. Eine kleine Unterstützung könnte ich aber noch gebrauchen.
Das aktuelle Ergebnis würde ich gerne in einer alternativen View nach einer Spalte (z.B. Property3) zusammenfassen.
Das Ergebnis sollte dann so aussehen:

Count | Property1 | Property2 | Property3 | Property4
--------------------------------------------------------
2 | different | Val2 | Val3 | different
1 | Val1 | Val2 | ---- | ----
 
Zurück
Oben