SQL [akademisches Beispiel] Design-Entscheidung: Sammelentität oder viele Einzelne?

T

Tersus

Gast
Grüßt euch,

ich möchte mehrere Bilder (bzw. Bilderlinks) zu jeder Entität speichern. Daraus ergibt sich ein ekliges Problem. Ich habe zwei Design-Entwürfe mit angehangen.

Vorschlag 1

designVorschlag1.png

Hier wird für jeden Entitätstypen, deren Entitäten Bilder enthalten können, eine eigener Bilderentitätstyp angelegt, dessen konkrete ID sich in dem "großen" Entitätstypen Bild befinden muss.

Vorteil: Jeder Entitätstyp, wie Auto und Schiff, verwenden unabhängige IDs. Es kann sowohl ein konkretes Auto, als auch ein konkretes Schiff mit selbiger ID geben.
Nachteil: Für jeden Entitätstypen, deren Entitäten Bilder enthalten, muss ein weiterer Entitätstyp für diese Bilder geschaffen werden. Fügen wir einen neuen Enitätstypen Zug hinzu, muss zwangsweise auch der Entitätstyp Zugbild hinzugefügt werden.

Vorschlag 2

designVorschlag2.png

Hier gibt es keine speziellen Bilderentitätstypen. Dafür einen quasi Ober-Entitätstypen für alle Entitätstypen, deren Entitäten Bilder enthalten können.

Vorteil: Kommt ein neuer Entitätstyp, z .B. Zug hinzu, muss kein extra Bildentitätstyp angelegt werden.
Nachteil: Jede Enität die Bilder enthält, wie die von Auto und Schiff, muss auch im Ober-Entitätstypen Bildentität eingetragen seien. Damit darf bzw. kann es kein Auto und kein Schiff mit der selben ID geben.


Welches Design ist zu bevorzugen? Oder gibt es gar weitere Designlösungen, die ich nicht bedacht habe?
 
Zuletzt bearbeitet von einem Moderator: (Vokabelkorrektur: Entität/Entitätstyp)
Wenn "Autobild" und "Schiffsbild" keine unterschiedlichen Eigenschaften haben, sehe ich eigentlich keinen Sinn darin, diese überhaupt aufzutrennen. Du erreichst damit keine höhere Normalform.
 
JetStre4m schrieb:
Wenn "Autobild" und "Schiffsbild" keine unterschiedlichen Eigenschaften haben, sehe ich eigentlich keinen Sinn darin, diese überhaupt aufzutrennen. Du erreichst damit keine höhere Normalform.

Wenn ich sie nicht auftrenne, wie kann ich dann ableiten, zu welchem Entitätstyp ein Bild gehört? ;)

Angenommen, es gibt nur einen Entitätstyp Bild. Jedes konkrete Bild verweißt auf ein konkretes Auto oder Schiff. Wie soll das Fremdschlüsselattribut in Bild aussehen? ;) Das geht also nicht.
 
Tersus schrieb:
Wenn ich sie nicht auftrenne, wie kann ich dann ableiten, zu welchem Entitätstyp ein Bild gehört? ;)

Zum Beispiel durch eine Splate names "is_shiff" mit einem bool wert von true oder false. Ich sehe da auch kein Vorteil die zwei zu trennen außer es sind wirklich völlig andere Eigenschaften vorhanden.

Alternativ kann man auch noch eine Spalte "is_auto" einbauen ebenfalls mit true false zwar etwas überflüssig aber durchaus ok.
 
Wenn sich die "Autobilder" nicht von den "Schiffsbildern" unterscheiden, reicht es, wenn es nur eine Entität "Bild" gibt. Der Fremdschlüssel ist nicht in Bild, sondern in Auto und Schiff. Die Zugehörigkeit findest du über eine Select-Abfrage. Es verweist also nicht jedes Bild auf ein Auto/Schiff, sondern jedes Auto/Schiff auf ein Bild.
 
Zuletzt bearbeitet:
Ich verstehe das Problem ehrlich gesagt nicht so richtig..
Du hast ein Tabelle "Bild" und die enthält viele weitere Bilder (also Schiffsbilder und Autobilder?)
Wie schon in der Vorantwort erwähnt, würde ich einfach die Autobilder und Schiffsbilder in einer zweiten Tabelle speichern.

Also: Zwei Tabellen eine "Bild" und eine "Bildentität"
Der Foreign Key in der Bildentität wäre dann die ID des Elements in der Tabelle "Bild"
 
Ihr habt euch aber schon mal mit Datenbanktheorie und guten Schemata beschäftigt, oder? :p

Das ist doch ein schreckliches Design, in der Tabelle Bild dann Attribute, wie isAuto und isSchiff zu haben. Was, wenn sich das Datenbankschema erweitert und noch 3 weitere Tabellen hinzukommen. Dann muss ich weitere Attribute isDies, isDas, ... hinzufügen? An die Abfragen will ich gar nicht denken. :(

JetStre4m schrieb:
... Der Fremdschlüssel ist nicht in Bild, sondern in Auto und Schiff. ...

Dann darf jedes Auto und jedes Schiff nur ein Bild haben und das ist nicht gewollt. Es muss beliebig viele Bilder zu einem Auto oder Schiff geben dürfen. ;) Der Fremdschlüssel muss in Bild gespeichert werden.
 
Zuletzt bearbeitet von einem Moderator:
Boolsche Spalten zur Entitätsdiskriminierung wie die von Cool Master vorgeschlagenen is_schiff oder is_auto fallen für mich in die Kategorie „ganz übel”, da sie zunächst einen programmatischen Ansatz mit ER-Design vermischen. Bitte nicht!

Entitäten sollten Mengen durch ihre beschreibenden Attribute voneinander abgrenzen und dies nicht durch künstliche Attribute „simulieren”, denn dann sind die Grenzen schlichtweg falsch gesetzt.

Von der eingangs beschriebenen Ausgangslage betrachtet haben wir hier:
  • zwei Arten von Fahrzeugen
  • eine Art von Bild
    (weil sich ein Autobild nach Deiner Beschreibung in seinen Attributen erstmal nicht von einem Schiffsbild unterscheidet, lediglich der Inhalt ist anders)
Diese stehen in einer ternären Beziehung zueinander - wie man die „akademisch korrekt“ abbildet, gibt die vierte Normalform vor - die insbesondere bei den Boolschen Spalten schnell verletzt wird.

Erfahrungsgemäß würde ich weiterhin auf Vererbungsbeziehungen verzichten, wo immer es möglich ist. Das hat vor allem pragmatische Gründe, weil es einerseits bei Implementierungen oft technische Hürden gibt und andererseits, weil spätestens ab der vierten Ebene wiederum einerseits die mentale Übersicht flöten geht und andererseits das Datenmodell derart abstrakt wird, dass man quasi gleich auf Quarks-Ebene arbeitet. ;)
 
Zuletzt bearbeitet:
Vielleicht verstehe ich die Frage falsch, aber ich würde einfach eine Tabelle mit dem Fahrzeugtyp führen.

Und diese auf der jeweiligen Fahrzeugentität referenzieren. Dann ist es erweiterbar und in Normalform.
 
thecain schrieb:
Vielleicht verstehe ich die Frage falsch, aber ich würde einfach eine Tabelle mit dem Fahrzeugtyp führen.

Und diese auf der jeweiligen Fahrzeugentität referenzieren. Dann ist es erweiterbar und in Normalform.

Genau. Das entspricht ungefähr meinem Vorschlag 2 vom Eingangsbeitrag. Jedes Bild könnte somit ein Fahrzeug referenzieren. Problem ist nur, wenn Entitätstypen hinzukommen, die keine Fahrzeuge sind, aber dennoch visuell durch Bilder abgebildet werden können. Diese würden dann nicht berücksichtigt.

Shagrath schrieb:
...
Von der eingangs beschriebenen Ausgangslage betrachtet haben wir hier:
  • zwei Arten von Fahrzeugen
  • eine Art von Bild
    (weil sich ein Autobild nach Deiner Beschreibung in seinen Attributen erstmal nicht von einem Schiffsbild unterscheidet, lediglich der Inhalt ist anders)
Diese stehen in einer ternären Beziehung zueinander - wie man die „akademisch korrekt“ abbildet, gibt die vierte Normalform vor - die insbesondere bei den Boolschen Spalten schnell verletzt wird.
Die ternäre Beziehung sehe ich nicht heraus, was die 4. Normalform als Lösung nichtig macht.

Shagrath schrieb:
Erfahrungsgemäß würde ich weiterhin auf Vererbungsbeziehungen verzichten, wo immer es möglich ist. Das hat vor allem pragmatische Gründe, weil es einerseits bei Implementierungen oft technische Hürden gibt und andererseits, weil spätestens ab der vierten Ebene wiederum einerseits die mentale Übersicht flöten geht und andererseits das Datenmodell derart abstrakt wird, dass man quasi gleich auf Quarks-Ebene arbeitet. ;)

Dem stimme ich so zu, denke jedoch, dass ich hier nicht dran vorbei komme.
 
Stimmt, ternär war Quatsch; hab gepennt.

Würde auch im Sinne von OCP zunächst eine „abstrakte“ Entität dazwischen hängen, wie auch immer die nun benannt wird.
 
Zuletzt bearbeitet:
Tersus schrieb:
Wenn ich sie nicht auftrenne, wie kann ich dann ableiten, zu welchem Entitätstyp ein Bild gehört? ;)

Angenommen, es gibt nur einen Entitätstyp Bild. Jedes konkrete Bild verweißt auf ein konkretes Auto oder Schiff. Wie soll das Fremdschlüsselattribut in Bild aussehen? ;) Das geht also nicht.

Wenn es sich um einen Primärschlüssel Attribut handelt welches nur einmalig vergeben werden kann, kann man dies über einen SELECT bestimmen (Wenn ich das Diagramm korrekt gelesen habe, kenne leider nur den UML Standard).

Unabhängig davon:

Muss man dies in der Praxis denn überhaupt wissen (Ob Schiffsbild oder nicht)?

Wie so häufig im Leben (und auch in der Informatik), die eierlegende Wollmilchsau gibt es nicht.

Ungeeignete Lösungen werden häufig nach gegebenen Anforderungen aussortiert, gibt es keine Anforderungen (Willkommen in der Uni) wirst du dir selbst welche ausdenken müssen (Wann sollte man sich für einen, wann für den anderen Lösungsansatz entscheiden [ist ja bereits schon geschehen]).

Der Dozent/Professor wird dann natürlich noch seinen persönlichen Senf dazugeben.

Ein sehr häufiges Argument ist in der Praxis zum einen die Performanz, zum anderen gibt es in der Softwareentwicklung noch Wartbarkeit (und noch viele mehr ...).

Wenn einem die Performanz sehr wichtig ist und man JOINs vermeiden kann sollte man dies in Betracht ziehen jedoch unter vollem Bewusstsein welche Nachteile man sich hierdurch ins Boot holt (Normalform x hin oder her).

An der Universität bekommt man im Bachlor gelehrt wie unglaublich wichtig die Normalformen 1-n sind.
Im Master lernt man dann, dass durch die Anwendung der Normalformen die Leseperformanz verschlechtert wird zugunsten Eintragegeschwindigkeit (no duplicates 'n' stuff) und der Update Perfromanz. Außerdem kann hierdurch auch die Wartbarkeit verbessert werden.
Irgendwann (später) kommen dann die praxisrelevanten Fragen.
Wie oft wird eine Tabelle am Tag selektiert?
Wie viele Einträge gibt es am Tag?
Wie viel mehr verhunze ich mir durch eine performanzsteigernde Änderung mein Datenbank Design :D?

Naja ich denke je nach Universität solltest du (mehr oder weniger) darauf achten die Normalform einzuhalten (nicht weil das zwangsläufig sinnvoll ist sondern weil es sonst Abzüge in der Klausur gibt). Wie man es dann richtig macht lernt man dann im Master und wenn nicht da dann wenn man damit arbeitet ;).
 
Zuletzt bearbeitet: (UPDATE Performanz)
Sensenmännchen hat es auf den Punkt gebracht :) Genau deswegen gab es auch den Vorschlag von mir mit is_schiff etc.. Die 0,1% weniger Performance spielt heute keine Rolle mehr außer wir reden über Millionen von Einträgen. Des Weitern macht man Abfragen idR einmal alle 12-24 Stunden, speichert sie im Cache und aktuallisiert per Cron z.B. nachts um 0 Uhr damit die Inhalte wieder Up2Date sind.

Die Theorie ist immer schön und nett in der Praxis sieht es aber immer anders aus ;)
 
Cool Master schrieb:
Sensenmännchen hat es auf den Punkt gebracht :) Genau deswegen gab es auch den Vorschlag von mir mit is_schiff etc.. Die 0,1% weniger Performance spielt heute keine Rolle mehr außer wir reden über Millionen von Einträgen. Des Weitern macht man Abfragen idR einmal alle 12-24 Stunden, speichert sie im Cache und aktuallisiert per Cron z.B. nachts um 0 Uhr damit die Inhalte wieder Up2Date sind.

Die Theorie ist immer schön und nett in der Praxis sieht es aber immer anders aus ;)

Die Rede ist hier nicht von 0,1%, JOINs können extrem teuer sein und das einsparen Dieser kann (total Fallabhängig) bis zu 50% (oder mehr) der Zeit einsparen (statt 10 nur noch 5 Sekunden). 1.000.000 Datensätze sind in der Praxis in vielen mittelständigen Firma nix ungewöhnliches.
Ich habe in meiner Bachelorarbeit ein Beispiel wo durch eine Denormalisierung nur noch 100ms anstatt mehreren Sekunden für einen SELECT benötigt wurden (es ist sehr Fallabhängig).
Jedoch leidet die INSERT und die UPDATE Performanz darunter.

Imho kann man sich gerade mit deinem Beispiel den JOIN sparen und somit etwas Performanz gewinnen.
 
Auf was war das ganze aufgebaut HDD Raid oder schon SSD (Raid)? Ach ja bzgl. der Zeit wie gesagt Cache nutzen! Drupal ist da ein sehr gutes Beispiel das ist sau lahm mit guten Cache aber (z.B. APC) läuft das sau schnell :)
 
Zuletzt bearbeitet:
So richtig verstehe ich das Problem wohl auch nicht. Das Ganze kann man doch so sehr schön normalisiert abbilden und die Generalisierung ist durch neue Einträge für den Typ problemlos möglich.

Was Joins angeht, da optimieren die verschiedenen DBMS bei so simple Fällen meist sehr gut und im Zweifelsfall kann man durch gezieltes Optimieren da eingreifen.
 

Anhänge

  • ERM.png
    ERM.png
    4,7 KB · Aufrufe: 189
Zurück
Oben