Problem mit Normalisierung

Hallo allerseits,
habe ein kniffeliges Problem bei der Normalisierung folgender Tabellen:

Beschreibung:
Ein Entity ‚Prozess‘ kann entweder beliebig viele andere Prozess beinhalten oder ein ‚Gerät‘.

Folgende Lösung habe ich gefunden, aber egal wie ich die Sache drehe komme ich nicht weiter. Die Tabelle 2 ist einfach unschön, da bei jedem Eintrag dort eine der Spalten GerätID oder ProzessID frei ist.

  1. Tabelle Prozess: BesitzenderProzessID, …
  2. Tabelle ProzessListe: BesitzendenProzessID, zugeordneterProzessId, GerätID
  3. Tabelle Gerät: GerätId, …

(… stellt weitere Felder dar, die für dieses Problem nicht relevant sind.)

Ich nehme an, das sich das wohl in einer der höheren Normalformen auflöst, bin darin aber nicht sehr fit.

Vielen, vielen Dank für jede Hilfe!
Dirk

Hallo Dirk,

die erste Tabelle kannst du dir sparen. das macht man mit einer reflexiven Relation (der Foreign Key der Tabelle geht auf dieselbe Tabelle zurück) Dann gibt es:

Prozess
prozID
parentProz
geraetID

Geraet
geraetID

Prozess.parentProz referenziert auf Prozess.prozID
Prozess.geraetID referenziert auf Geraet.geraetID

Gruß

Peter

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Danke für deine Antort!

die erste Tabelle kannst du dir sparen. das macht man mit
einer reflexiven Relation (der Foreign Key der Tabelle geht
auf dieselbe Tabelle zurück) Dann gibt es:

Auf Grund dessen, was ich bisher geschrieben hatte stimm ich dir zu. Ich brauch die Tabelle aber doch noch für weitere Daten, die sich nur auf den obersten ‚Vater‘-Prozess beziehen, auf den nicht von einem anderen Prozess referenziert wird.
Ist aber unwichtig für mein Problem…

Prozess
prozID
parentProz
geraetID

Geraet
geraetID

Prozess.parentProz referenziert auf Prozess.prozID
Prozess.geraetID referenziert auf Geraet.geraetID

Hier besteht alleridngs immer noch das Problem, dass ein Prozess ja immer nur entweder die ID eines weiteren Prozesses oder die ID eines Geräts enthalten darf.
Somit ist immer noch in jeder Zeile eines der Felder Prozess.parentProz oder Prozess.geraetID leer.

Das wollte ich allerdings irgendwie umgehen. Es soll nach Möglichkeit nämlich auch nicht möglich sein, dass ein ein Prozess ein Gerät *und* gleichzeitig einen Prozess referenziert.

Dirk

Hallo Dirk,

Hier besteht alleridngs immer noch das Problem, dass ein
Prozess ja immer nur entweder die ID eines weiteren Prozesses
oder die ID eines Geräts enthalten darf.
Somit ist immer noch in jeder Zeile eines der Felder
Prozess.parentProz oder Prozess.geraetID leer.

Dein Modell klingt etwas danach, als ob hier unterschiedliche Daten in der gleichen Tabelle abgelegt werden. Das darf man tun, muss dann aber eben mit den Auswirkungen leben, wovon dein beschriebenes Problem eben eines ist. Es gäbe noch eine NICHT EMPFEHLENSWERTE Methode zu verhindern, dass du immer ein leeres Feld mitschleppst: Du definierst ein Feld Typ, dass entscheidet, ob ein Prozess oder ein Gerät referenziert wird und dann eben ein zweites Feld, in dem die Referenz sthet. Warum du das keinesfalls machen solltest: Du kannst damit keine Foreign Key Constraints mehr definieren, und das ist BÖSE (und nein, man kann referenzielle Integrität auch nicht mit Triggern abbilden).

Das wollte ich allerdings irgendwie umgehen. Es soll nach
Möglichkeit nämlich auch nicht möglich sein, dass ein ein
Prozess ein Gerät *und* gleichzeitig einen Prozess
referenziert.

Das verhinderst du ganz einfach mit einem Table-Constraint, der sicherstellt, dass eines der beiden Felder NULL ist (ggf. kannst du dort natürlich auch gleich prüfen, dass genau eines befüllt ist).

HTH,
Martin

Hallo,

Normalisierung hat damit eigentlich gar nichts zu tun. Eher Vererbung. Es haben dann nämlich Geräte und Prozesse bei die eine gemeinsame Wurzel. Und die musst du finden. Im ER-Diagramm gibt es eine Generalisierung, aber das eigentliche Problem wirst du damit nicht los. Die Lösung von TheBeast würde ich auch so machen, hätte aber weniger Skrupel, einen Trigger einzusetzen.

Etwas hast du noch falsch verstanden:
parentProz ist dann leer, wenn es sich um einen Prozess oberster Stufe handelt. Auf diesen Prozess können sich viele andere Prozesse beziehen. Das Attribut der Relation steht also im Unterprozess. Jeder Prozess kann noch ein Gerät haben.

Gruß

Peter

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Peter,

Die Lösung von TheBeast
würde ich auch so machen, hätte aber weniger Skrupel, einen
Trigger einzusetzen.

Aber nur, wenn du mit einem Einzelplatzsystem leben kannst. Du musst die entsprechenden Sätze in der Fremdtabelle sperren, während du einen neuen Fremdschlüssel einträgst (das ist ja noch ok), umgekehrt aber die Prozesse als Ganzes , wenn ein Eintrag in der Fremdtabelle mal gelöscht werden soll. Also ich würde das nicht machen…

Gruß
Martin

Hallo,

Normalisierung hat damit eigentlich gar nichts zu tun. Eher
Vererbung. Es haben dann nämlich Geräte und Prozesse bei die
eine gemeinsame Wurzel. Und die musst du finden. Im
ER-Diagramm gibt es eine Generalisierung, aber das eigentliche
Problem wirst du damit nicht los. Die Lösung von TheBeast
würde ich auch so machen, hätte aber weniger Skrupel, einen
Trigger einzusetzen.

Trigger geht leider nicht, da ich kein gewöhnliches DBMS habe.
Trotzdem habt ihr mir schon etwas weitergeholfen.

Etwas hast du noch falsch verstanden:
parentProz ist dann leer, wenn es sich um einen Prozess
oberster Stufe handelt. Auf diesen Prozess können sich viele
andere Prozesse beziehen. Das Attribut der Relation steht also
im Unterprozess. Jeder Prozess kann noch ein Gerät haben.

Äh, nein. Ihr habt was falsch verstanden. Eigentlich sollte jeder Prozess mehrer Sub-Prozesse haben. Aber ist ja eigentlich unwichtig…

Grüße
Dirk

Hallo,

Normalisierung hat damit eigentlich gar nichts zu tun. Eher
Vererbung. Es haben dann nämlich Geräte und Prozesse bei die
eine gemeinsame Wurzel. Und die musst du finden. Im
ER-Diagramm gibt es eine Generalisierung, aber das eigentliche
Problem wirst du damit nicht los. Die Lösung von TheBeast
würde ich auch so machen, hätte aber weniger Skrupel, einen
Trigger einzusetzen.

Trigger geht leider nicht, da ich kein gewöhnliches DBMS habe.
Trotzdem habt ihr mir schon etwas weitergeholfen.

Etwas hast du noch falsch verstanden:
parentProz ist dann leer, wenn es sich um einen Prozess
oberster Stufe handelt. Auf diesen Prozess können sich viele
andere Prozesse beziehen. Das Attribut der Relation steht also
im Unterprozess. Jeder Prozess kann noch ein Gerät haben.

Äh, nein. Ihr habt was falsch verstanden. Eigentlich sollte
jeder Prozess mehrer Sub-Prozesse haben. Aber ist ja
eigentlich unwichtig…

Kann er doch. Schau dir doch das Schema an. Beliebig viele SubProzesse können auf einen ParentProzess referenzieren. Ein SubProzess gehört zu genau einem ParentProzess.

Wegen der Trigger: dann nimm halt ein vernünftiges DBMS. Das kann mittlerweile sogar MySQL. Oder fang die Eingabe von Geräten/Prozessen wechselseitig in der Applikation ab.

Gruß

Peter

Grüße
Dirk

umgekehrt aber die Prozesse als Ganzes , wenn

ein Eintrag in der Fremdtabelle mal gelöscht werden soll.

In Oracle gilt das nur, wenn auf der referenzierenden Spalte kein Index liegt.