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

Datenbank für AnforderungsManagement

Dieses Thema im Forum "Datenmodellierung, Datenbank-Design" wurde erstellt von RedFerret, 3 Januar 2013.

  1. RedFerret

    RedFerret Benutzer

    Hallo,

    ich bin neu hier im Forum und brauche ein paar Tipps. Grundlegende Kenntnisse zu Datenbanken habe ich und ich arbeite mit MySQLworkbench.

    Ich möchte eine Datenbank erstellen mit der ich für verschiedene Produkte Anforderungen erfassen kann, die sich in Haupt- und Unteranforderungen unterteilen lassen. Ich überlege nun, ob es sinnvoll ist für jedes Produkt eine eigene HauptanforderungsTabelle zu erstellen. Jede dieser Hauptanforderungen müsste sich dann wieder in Unteranforderungen aufspalten. Dann hätte ich eine unübersichtlich große Anzahl an Tabellen, aber Redundanzen vermieden. Die Alternative wäre eine große Tabelle für alle Hauptanforderungen und eine große Tabelle für alle Unteranforderungen, dadurch dann halt Redundanz. Oder hat jemand noch eine ganz andere Idee?

    Wenn mir jemand ein paar Tipps geben könnte wäre ich sehr dankbar. Ich möchte nicht dass jemand die Aufgabe für mich löst, nur etwas Beratung. Habe noch nicht viele Datenbanken erstellt.

    Bis hier hin schonmal Danke fürs lesen :)
     
  2. akretschmer

    akretschmer Datenbank-Guru

    aber Dein Geschäft könnte nicht mehr wachsen, denn mit jedem neuen Produkt müßtest Du neue Tabellen anlegen und auch die Programmierung der Anwendung anpassen.

    Wo siehst Du Redundanz?

    Nochmal: wo siehst Du Redundanz?


    Andreas
     
    RedFerret gefällt das.
  3. RedFerret

    RedFerret Benutzer

    Danke für die schnelle Antwort :)

    Meine Idee war, beim Anlegen eines neuen Produktes durch einen Trigger eine neue dazu gehörige Anforderungstabelle erstellen zu lassen. Was du mit "Programmierung der Anwendung anpassen" meinst ist mir nicht ganz klar.

    Ich denke Redundanz würde auftauchen, wenn ich eine Tabelle für sämtliche Anforderungen hätte, dann müsste nämlich jede Anforderung das Attribut "Produkt" haben, damit man weiß wozu die Anforderung gehört.
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Du hast also eine Tabelle mit den Produkten. Wenn da ein Neues auftaucht, willst Du eine neue Tabelle speziell für dieses Produkt erstellen, ja?

    Nun wirst Du ja nicht die ganze Arbeit alles händisch mit SQL machen wollen, sondern Du hast z.B. eine Website mit PHP, mit der Du das bedienst. Diese wirst Du dann vermutlich ändern müssen, damit diese die neuen Tabellen kennt (okay, man kann den Namen sicher auch dynamisch herleiten).

    Über wieviele Produkte und über alle Produkte wie viele Anforderungen reden wir?

    Das, was Dir wohl vorschwebt, ist Tabellen-Partitionierung. Aber das lohnt erst richtig wenn Du *richtig* viele Daten hast. Nenn also mal 'ne Hausnummer.

    Ja, dazu wäre dann natürlich ein Fremdschlüssel auf die Produkttabelle nötig. Daher kommt auch das 'relational' von 'Relationalen Datenbanken' ;-)



    Andreas
     
    RedFerret gefällt das.
  5. RedFerret

    RedFerret Benutzer

    Die Anzahl der Datensätze wird bei mir nicht über 10 Produkte hinausgehen, denn es soll nur ein Modell werden und es wird niemals den Weg zur praxistauglichen Anwendung finden. Allerdings soll man nachher nicht sagen können: "Das funktioniert ja nur wenn es nicht viele Datensätze gibt!"

    Aber ich denke Du hast mich überzeugt doch besser jeweils eine "große" Tabelle für alle Haupt- und Unteranforderungen zu machen. Kann man dann von einem normalisierten Tabellenmodell sprechen?
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Ja.


    Andreas
     
  7. RedFerret

    RedFerret Benutzer

    Kurz und knapp ;)

    Vielen Dank für die Hilfe
     
  8. ukulele

    ukulele Datenbank-Guru

    Auch an dieser Stelle möchte ich mal noch auf einen meiner Beiträge verweisen: http://www.datenbankforum.com/threads/guid-über-mehere-tabellen.796/ (2ter Beitrag)

    Hier (in diesem Thread) scheint mir die selbe Problematik zu Grunde zu liegen. Ich habe eine beliebilge Anzahl nicht gleichartiger Objekte (Produkte) zu verwalten und nicht alle Objekte und deren Eigenschaften sind mir von Anfang an bekannt.

    Vieleicht schreibe ich dazu nochmal einen kleinen extra Beitrag wenn ich die Zeit habe um das Anhand von Beispielen besser zu erleutern. Ich habe mit dieser Vorgehensweise das erste mal über unser DMS zu tun gehabt und finde diesen Ansatz logisch und nützlich. Natürlich gibt es Alternativen wie z.B. das Anlegen neuer Tabellen.
     
    RedFerret gefällt das.
  9. RedFerret

    RedFerret Benutzer

    Danke für den Hinweis, werde mir Deinen Beitrag mal ansehen.
     
  10. RedFerret

    RedFerret Benutzer

    Stehe vor einem neuen Problemchen.

    In meinem Modell hat jede Anforderung ein gewissen Zeitbedarf.
    Eine HauptAnforderung besteht aus Unteranforderungen und
    der Zeitbedarf der HauptAnforderung soll die Summe der Zeitbedarfe ihrer UnterAnforderungen sein.

    Da ich sowas noch nie gemacht habe, frage ich mich, wie ich einem Wert "sage", dass er sich aus anderen Werten zusammensetzen soll.

    EDIT:

    Denke ich habe eine korrekte Lösung gefunden und poste sie mal, falls jemand ein ähnliches Problem haben sollte:

    UPDATE HauptAnforderungen
    SET ZeitBedarf_Tage = (

    SELECT
    sum(unteranforderungen.zeitbedarf_tage)
    from unteranforderungen
    where hauptanforderungen.anforderungsid = unteranforderungen.hauptanforderungsid
    )
     
  11. akretschmer

    akretschmer Datenbank-Guru

    Ähm, ja.

    So wie Du das formulierst ist da eher eine Forderung, die einzuhalten ist. Also, Du sagst, die Anforderung hat Zeitbedarf X, die Summe der Zeitbedarfe der Unterforderungen darf das nicht überschreiten. Das wäre natürlich auch abbildbar, aber Deine Lösung ist ja viel trivialer. Und so, wie Du es löst, eigentlich auch wieder falsch, weil nun hast Du Redundanz in Deiner Datenbank. Du kannst also den Zeitbedarf einer Anforderung komplett weglassen und die Summe beim SELECT bilden.


    Andreas
     
    RedFerret gefällt das.
  12. RedFerret

    RedFerret Benutzer

    Die Redundanz hatte ich vergessen... hast mal wieder Recht. Das mit dem Zeitbedarf der nicht überschritten werden wäre wirklich eine bessere Alternative. Allerdings hat jedes Produkt an sich schon einen Abgabetermin. Jetzt könnte man vielleicht der HauptAnforderung einen Vorstellungstermin geben, an dem es dem Kunden vorgeführt werden soll.
     
  13. RedFerret

    RedFerret Benutzer

    Bin dabei einen Trigger zu schreiben aber es gelingt mir leider nicht so ganz.

    Meine Anforderungen haben das boolean Attribunt "erledigt". Wenn jetzt jede UnterAnforderung den Wert "erledigt 1" hat, soll die dazugehörige HauptAnforderung auch den Wert 1 bei "erledigt" bekommen. Mit jeweils einer View(Select lässt sich ja im Trigger nicht benutzen) für

    HauptAnforderungsID, Anzahl_UnterAnforderungen und
    HauptAnforderungsID, Sum_ErledigteUnterAnforderungen

    schaffe ich mir zwei Vergleichswerte. Wenn diese übereinstimmen soll das Attribut "erledigt" von der jeweiligen HauptAnforderung auf 1 gesetzt werden.

    Ich hab mich jetzt einfach mal an einem Trigger versucht der so aussieht:

    DELIMITER //
    CREATE TRIGGER erledigung
    AFTER UPDATE ON unteranforderungen.erledigt
    FOR EACH ROW
    BEGIN
    IF sum_erledigt.anzahl_erledigt = uanf_pro_hanf.anzahl_uanf ***
    THEN SET hauptanforderungen.erledigt = 1;
    END IF;
    END//
    DELIMITER ;

    *** sum_erledigt.anzahl_erledigt enthält die summe der erledigt booleans
    und uanf_pro_hanf.anzahl enthält die Anzahl der UnterAnforderungen pro HauptAnforderung


    Das ist vermutlich totaler Käse, bekomme auch die Fehlermeldung "Error Code: 1193. Unknown system variable 'erledigt'0.000 sec"
    aber ich komm einfach ohne Hilfe nicht weiter...
     
  14. akretschmer

    akretschmer Datenbank-Guru


    Was für eine DB ist bei Dir am Start?

    Hier mal 'ne Fingerübung in PostgreSQL:

    Code:
    test=# create table aufgaben (id serial primary key, erledigt bool default false);
    NOTICE:  CREATE TABLE will create implicit sequence "aufgaben_id_seq" for serial column "aufgaben.id"
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "aufgaben_pkey" for table "aufgaben"  
    CREATE TABLE                                                                                         
    Time: 5,352 ms                                                                                       
    test=*# create table unteraufgaben (id serial primary key, aufgabe int references aufgaben, erledigt bool default false);
    NOTICE:  CREATE TABLE will create implicit sequence "unteraufgaben_id_seq" for serial column "unteraufgaben.id"          
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "unteraufgaben_pkey" for table "unteraufgaben"            
    CREATE TABLE                                                                                                             
    Time: 33,343 ms                                                                                                          
    test=*# create or replace function trg_aufgabe() returns trigger as $$ begin if (select count(1) from unteraufgaben where aufgabe=new.aufgabe and not erledigt) = 0 then update aufgaben set erledigt = true where id = new.aufgabe; end if; return new; end;$$language plpgsql;                                                        
    CREATE FUNCTION                                                                                                                                                     
    Time: 17,596 ms                                                                                                                                                     
    test=*# create trigger trg1 after update on unteraufgaben for each row execute procedure trg_aufgabe();
    CREATE TRIGGER                                                                                         
    Time: 0,263 ms                                                                                         
    test=*# insert into aufgaben (id) values (1);
    INSERT 0 1                                   
    Time: 0,427 ms
    test=*# insert into aufgaben (id) values (2);
    INSERT 0 1
    Time: 0,156 ms
    test=*# insert into unteraufgaben (id, aufgabe) values (1,1);
    INSERT 0 1
    Time: 0,700 ms
    test=*# insert into unteraufgaben (id, aufgabe) values (2,1);
    INSERT 0 1
    Time: 0,327 ms
    test=*# select * from aufgaben;
     id | erledigt
    ----+----------
      1 | f
      2 | f
    (2 rows)
    
    Time: 0,175 ms
    test=*# update unteraufgaben set erledigt = true where id = 1;
    UPDATE 1
    Time: 0,703 ms
    test=*# select * from aufgaben;
     id | erledigt
    ----+----------
      1 | f
      2 | f
    (2 rows)
    
    Time: 0,150 ms
    test=*# update unteraufgaben set erledigt = true where id = 2;
    UPDATE 1
    Time: 0,644 ms
    test=*# select * from aufgaben;
     id | erledigt
    ----+----------
      2 | f
      1 | t
    (2 rows)
    
    Time: 0,151 ms
    

    So könnte es also gehen, wenn Ich Dich richtig verstanden habe.


    Andreas
     
    RedFerret gefällt das.
  15. RedFerret

    RedFerret Benutzer


    ja genau so hab ich das gemeint, allerdings benutze ich SQL. Mein Trigger müsste also so funktionieren wie bei dir die function trg_aufgabe(). Das müsste ja dann ungefähr so aussehen:

    Code:
     
    DELIMITER //
    CREATE TRIGGER erledigung
    AFTER UPDATE ON unteranforderungen
    BEGIN 
    IF (SELECT count(1) FROM unteranforderungen
    WHERE hauptanforderungen = new.hauptanforderungen and NOT erledigt
    ) = 0 
    THEN 
    UPDATE hauptanforderungen SET erledigt = true 
    WHERE id = new.hauptanforderungen; 
    END IF;  
    END//
    DELIMITER ;
     
    
    Aber ich verstehe nicht was mit count(1) gemeint ist und wie das mit new funktioniert :(
     
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