1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Hilfe bei Datenbankstruktur

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von michael97, 26 Januar 2017.

  1. michael97

    michael97 Benutzer

    Hallo,
    ich habe ein Problem, für das ich einfach keine Lösung finde.
    Ich habe folgene Ausgangslage:
    Ich habe einen Chef, dem mindestens eine Firmen unterstellt ist. Diese Firmen haben jeweils mindestens eine Filiale. Nun habe ich Arbeiter, die für den Chef, die Firma und/oder für eine Filiale arbeiten. Sie führen für die besagten Objekte/den Chef Tätigkeiten aus, die sich von Objekt zu Objekt unterscheiden können. Ich habe das mal in einer Grafik dargestellt.
    Frage_DB.png
    Das besondere ist, dass wenn ein Arbeiter dem Chef mit einer bestimmten Tätigkeit zugewiesen ist, er auch implizit in allen Firmen und Filialen die besagte Tätigkeit ausübt. Falls er mit einer bestimmten Tätigkeit einer Firma zugewiesen ist, er die Tätigkeit ebenfalls in allen Filialen der Firma ausübt. Im Falle von Arbeiter 1 bedeutet dies, dass er in allen Filialen (Filiale 1 - 6) die Tätigkeit 3 (die Tätigkeiten stehen im Kreis) ausübt, in allen Filialen der Firma 3 (Filiale 4 - 6) die Tätigkeit 1 ausübt, in Filiale 1 die Tätigkeit 1 ausübt und in Filiale 3 die Tätigkeit 2 ausübt.

    Es interessieren nur die Filialen. Die Firmen und der Chef sind als abstrakte Objekte anzusehen, in denen man nicht arbeiten kann.

    Als Resultat hätte ich gerne (arbeiterpezifisch) etwas wie:
    Für Arbeiter 1
    Filiale Tätigkeit
    1 1
    1 3
    2 3
    3 2
    3 3
    4 1
    4 3
    5 1
    5 3
    6 1
    6 3


    Mein Problem ist, wie ich das vernünftig in der Datenbank abbilden kann ohne allzu komplizierte Abfragen zu erhalten. Mein bisheriger Ansatz war von der Form:

    Code:
    chef_hat_arbeiter_mit_taetigkeit
    chef_id | arbeiter_id | taetigkeit_id
    
    firma_hat_arbeiter_mit_taetigkeit
    firma_id | arbeiter_id | taetigkeit_id
    
    filiale_hat_arbeiter_mit_taetigkeit
    filiale_id | arbeiter_id | taetigkeit_id
    
    Der Chef, die Firmen und die Filialen hängen wie folgt zusammen
    Code:
    chef
    id | name
    
    firma
    id | chef_id | name
    
    filiale
    id | firma_id | name
    
    Ich bin jetzt die ..._hat_arbeiter_in_taetigkeit-Tabellen von oben nach unten durchgegangen und habe nach dem arbeiter gesucht. Anschließend die nächste ge-JOINt und geprüft, ob der Eintrag NULL war, so konnte ich davon ausgehen, dass er nur in der 'höheren' Tabelle vorkommt. Als letztes habe ich mir dann sämtliche Filialen geholt. Mit dieser Herangehensweise benötige ich nur sehr viele JOINs und UNIONs und krieg eine sehr unübersichtliche Query, die ich nichit einmal auf Richtigkeit prüfen kann.

    Hat jemand eine Idee, wie ich das Umsetzen kann? Ich möchte eine möglichst einfache und übersichtliche Struktur und Abfrage erhalten, also das komplette Gegenteil vom bisherigen Stand.

    Viele Grüße
    Michael
     
  2. drdimitri

    drdimitri Datenbank-Guru

    Ganz so einfach wird das nicht werden.
    Noch eine Frage zu dem Chef und Firma. Wieso können die ignoriert werden? Ein Arbeiter kann diesen doch zugewiesen werden?
    Ich vermute, du kommst aus der OO Welt und versuchst eine Klassenhierarchie abzubilden? Das läßt sich in einer Relationalen DB nur bedingt. Entweder es gibt die Entität Firma oder es gibt sie nicht.
    Gibt es nur einen Chef oder kann es mehrere Chefs geben, die dann disjukte Fimen/Arbeiter haben?
     
  3. michael97

    michael97 Benutzer

    Hallo drdimitri,
    vielen Dank für Deine Antwort.
    Es gibt nur einen Chef. Der Chef und die Firma sind egal, da nur der Ort interessiert, an dem die Arbeiter arbeiten und das sind in diesem Fall die Filialen. Ich wollte mit dem Ansatz, dass ich dem Chef und einer Firma Arbeiter mit ihren Rechten zuweise, die Möglichkeit schaffen, nach dem Erstellen einer neuen Filiale, nicht einem Arbeiter erst diese zuweisen zu müssen, sondern er gleich in dieser arbeitet, wenn er in der Firma für diese Tätigkeit vorgesehen ist.
    Ich könnte natürlich Tabellen erstellen, in denen ich speicher, welche Arbeiter dem Chef oder einer Firma zugewiesen sind und bei jedem Erstellen einer neuen Filiale diese Tabellen durchsuchen und den eingetragenen Arbeitern automatisch der neu angelegten Filiale zuordnen. Aber so etwas wollte ich gerne umgehen.
    Nutzern Chef oder einer Firma mit einer speziellen Tätigkeit zuordnen
    Code:
    nutzer_hat_taetigkeit_bei_chef
    nutzer_id | taetigkeit_id | 
    
    nutzer_hat_taetigkeit_in_firma
    nutzer_id | firma_id | taetigkeit_id
    
    die entsprechenden Nutzer dann Eintragen in

    Code:
    nutzer_hat_taetigkeit_in_filiale
    nutzer_id | filiale_id | taetigkeit_id
    
    Mehrere Chefs kann es geben, aber diese hätten dann komplett andere Arbeiter. Also sind diese zu vernachlässigen.

    Viele Grüße
    Michael
     
  4. ukulele

    ukulele Datenbank-Guru

    Ich finde dBeziehungen
    chef_hat_arbeiter_mit_taetigkeit
    chef_id | arbeiter_id | taetigkeit_id

    firma_hat_arbeiter_mit_taetigkeit
    firma_id | arbeiter_id | taetigkeit_id

    filiale_hat_arbeiter_mit_taetigkeit
    filiale_id | arbeiter_id | taetigkeit_id
    überflüssig. Ich sehe hier weder eine relationale noch eine logische Notwendigkeit.

    Ein Arbeiter ist immer bei einem Unternehmen angestellt und hat mit dem Unternehmen einen Vertrag. Eine Beziehung firma_hat_arbeiter würde genau das abbilden. Eine weitere Beziehung bildet dann arbeiter_hat_tätigkeit_in_standort ab. Das kann ja vieleicht auch zeitlich befristet sein und es kann in mehreren Filialen, theoretisch auch in denen die anderen Firmen gehören, gleichtzeitig der Fall sein. Wenn er in einer Filiale eines anderen Unternehmens arbeitet dann wird vermutlich seine Tätigkeit zwischen den Unternehmen verrechnet / Finanziell ausgeglichen.

    Die Datenbank kann vom Chef des Unternehmes über das Unternehmen und seine Filiale auf die dort beschäftigten Arbeiter schließen, oder auf die angestellten Arbeiter eines Unternehmens.

    Es gibt in so einem Modell nur selten die Wahl zwischen leichten und komplizierten Abfragen, meist gibt es richtig und falsch. Nur selten sollte man sich zu Vereinfachungen durch strukturelle Schlampigkeiten hinreißen lassen um ein paar Zeilen Code in Abgfragen zu sparen, releationale Datenbanken leben von Releationen.
     
  5. michael97

    michael97 Benutzer

    Hallo ukulele,
    ich habe es erst auch mit den beiden von dir erwähnten Tabellen umgesetzt. Allerdings bin ich auf das Problem gestoßen, wie ich einem Arbeiter eine Tätigkeit in allen Filialen einer Firma zuweisen kann. Ich könnte theretisch für jede Filiale einen Eintrag in die Tabelle arbeiter_hat_tätigkeit_in_standort vornehmen. Wenn jetzt eine neue Filiale hinzukommt, müsste der entsprechende Eintrag erst vorgenommen werden. Das soll nicht sein. Wenn ein Arbeiter jeder Filiale einer Firma zugewiesen ist, sollten theoretisch beliebig viele Filialen einer Firma hinzukommen und der Arbeiter soll diesen Firmen automatisch zugewiesen sein. Auch hätte ich gerne eine Übersicht, welcher Arbeiter mit welcher Tätigkeit einer Firma und nicht nur einer Filiale zugewiesen ist.

    Viele Grüße
    Michael
     
  6. ukulele

    ukulele Datenbank-Guru

    Das ist zugegeben eine Art Problem das sich mit den üblichen Normalformen nicht gut abbilden läßt. Ich würde so vorgehen:

    Es gibt eine Dummy-Filiale "Alle Filialen" der ein Arbeiter explizit zugewiesen wird. Das kannst du entweder in deinen Selects berücksichtigen (hart eincoden) oder du machst eine Sicht die aus diesem Eintrag "Alle Filialen eine Übersetzung macht CROSS JOIN Mitarbeiter zu Filiale und mit UNION ALL mit den vorhandenen Datensätzen verschmilzt.

    Beispiel:
    Code:
    --Testtabelle (funktioniert nicht in MySQL)
    WITH  arbeiter_hat_taetigkeit_in_standort(arbeiter,taetigkeit,standort) AS (
       SELECT 1,1,'Filiale #1' UNION ALL
       SELECT 2,2,'Filiale #2' UNION ALL
       SELECT 3,1,'Alle Filialen'
       )
    --Ende Testtabelle
    SELECT   arbeiter,taetigkeit,standort
    FROM   arbeiter_hat_taetigkeit_in_standort
    WHERE   standort != 'Alle Filialen'
    UNION ALL
    SELECT   t1.arbeiter,t1.taetigkeit,t2.standort
    FROM   arbeiter_hat_taetigkeit_in_standort t1
    CROSS JOIN ( SELECT DISTINCT standort FROM arbeiter_hat_taetigkeit_in_standort WHERE standort != 'Alle Filialen' ) t2
    WHERE   t1.standort = 'Alle Filialen'
    Das hat den vorteil das du die Zuordnung einer Person zu allen Filialen nachvollziehbar hast und auch wieder rückgängig machen kannst.

    Du musst noch abgrenzen, was ist wenn ein weiterer Chef mit ganz anderen Firmen und Filialen daher kommt, dann darf der CROSS JOIN eventuell nur auf Chef-Ebene oder auf Firmen-Ebene arbeiten, es müssen also weitere Tabellen gejoint werden.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden