Dave: Tabellen Verknüpfen oder anderer DB aufbau ?

Servus.

Hab eine DB gebaut und zweifle nun an meinen eigenen Gedanken.

also. hab 6 Tabellen: dozenten, jahr, projekt, semester, student, TAG
diese haben jeweils ID und VALUE

dazu hab ich 5 tabellen: projekt_dozent, projekt_jahr, projekt_semester, projekt_student, projekt_TAG
jeweils IDs drin.

hab ich das zu kompliziert aufgebaut ?

wenn ich z.B. alle Projekte bei denen der student herbert(ID=1) gearbeitet hat ausgeben will ... was muss ich dann selectieren bzw. Joinen ?

und was selectiere und joine ich wenn ich alle projekte eines studenten mit allen anderen verknüpften angaben wie jahr, TAGs, semester usw. haben will.

das datenbankthema liegt nun schon 5 jahre zurück und ich muss mich neu einarbeiten. wäre nett wenn mir einer nen tip gibt.

ach so... was das wird, vielleicht ganz hilfreich.
ich will aus flash eine datenbank abrfrage über PHP machen.
aber dazu muss ich erst mal sicher sein das die datenbank ok is und
die abragen möglich.

Vielen Dank!

  1. Hallo,

    dein Datenbankaufbau ist falsch oder einfach nur schlecht, wenn du die Anforderungen damit nicht oder nur mit viel Umweg erfüllen kannst. Deine Anforderungen sind in Einzelfall solche Abfragen, wie:

    wenn ich z.B. alle Projekte bei denen der student herbert(ID=1) gearbeitet hat ausgeben will ...
    und was selectiere und joine ich wenn ich alle projekte eines studenten mit allen anderen verknüpften angaben wie jahr, TAGs, semester usw. haben will.

    Wie du erwähnt hast, hast du bereits Tabellen, welche die einzelnen Entitäten miteinander in Beziehung setzen:

    dazu hab ich 5 tabellen: projekt_dozent, projekt_jahr, projekt_semester, projekt_student, projekt_TAG

    wenn ich z.B. alle Projekte bei denen der student herbert(ID=1) gearbeitet hat ausgeben will ...

    Dafür würde schon grundsätzlich mal einfach die Abfrage
    SELECT projekt, student FROM projekt_student WHERE student = 1 ausreichen.

    Da du aber vielleicht den Projektnamen und den Studentennamen mit dazunehmen willst, solltest du auch auf die beiden Entitätstabellen projekt und student joinen:

      
    SELECT projekt, student, p.Value AS ProjektName, s.Value as StudentName  
      FROM projekt_student ps  
      INNER JOIN projekt p  
        ON p.Id = ps.projekt  
      INNER JOIN student s  
        ON s.Id = ps.student  
      WHERE s.Id = 1  
    
    

    Nach dem selben Schema, einfach INNER JOINs oder LEFT JOINs, verfährst du für die weiteren Tabellen. Für die Verknüpfungstabellen würde ich dir LEFT JOINs empfehlen, da dort vielleicht keine Einträge vorhanden sind. Für die Entitäten solltest du vorrangig (meine Empfehlung) mit INNER JOINs arbeiten, da Ids in den Verknüpfungstabellen eigentlich auch in den Entitätstabellen enthalten sein sollten. Es ist vielleicht auch ganz nützlich, die Abfrage immer bei einer Verknüpfungstabelle zu beginnen und dann _sternförmig_ zu den anderen Tabellen zu gehen. ;)

    Auf den ersten Blick halte ich dein Modell nicht für zu kompliziert. Allerdings solltest du statt VALUE vielleicht sinntrefferendere Spaltennamen vergeben. Evt möchtest du ja mehrere Infos zu einem Dozenten speichern als nur einen VALUE. ;)

    HTH, Ciao, Frank

    1. Hab mir gestern nach vielen Versuchen noch sowas aus den Haaren gezogen.
      Gibt es ein besser oder schlechter bzw. was is genau der Unterschied zu deinem ?

      Was macht dieses AS ?

      SELECT dozent.dozentNAME, projekt.projektNAME
      FROM projekt_dozent
      INNER JOIN dozent
      ON (projekt_dozent.dozentID = dozent.dozentID)
      INNER JOIN projekt
      ON (projekt_dozent.projektID = projekt.projektID)
      WHERE projekt_dozent.dozentID=X";

      1. Hi,

        das AS benutzt man (auch wenn es wohl nicht notwendig ist) für die Vergabe von Alias-Namen für Tabellen und Spalten.

        SELECT t1.* FROM TabelleMitSehrSehrLangemNamen AS t1
        SELECT t1.* FROM TabelleMitSehrSehrLangemNamen t1

        Das macht sich z.b. bei Joins recht gut, da man dann nicht immer den vollen Namen wieder verwenden muss.

        Bei berechneten Spalten wie ua. COUNT(*) oder MAX(tabelle.feld) solltest du dahinter (mit oder ohne AS dazwischen) immer einen Feldnamen angeben.

        Besser/Schlechter ... Wenn du von konsistenten Daten ausgehen kannst, dann sind INNER JOINs immer besser als LEFT JOINS. Ansonsten, wenn du falsche Reihenfolge in den Joins drin hast, wird sich die Datenbank über unbekannte Felder ärgern und dir ne Fehlermeldung geben. Die Reihenfolge der Joins ist nicht unbedingt wichtig (kann aber muss nicht), da die Datenbank die Abfrage selbst optimiert.

        Grundsätzlich kann man auch sagen: Schneller = Besser. Wenn du mehr liest als schreibst dann empfehlen sich eigentlich per se Indices auf den Verknüpfungstabellen zur Geschwindigkeitssteigerung.

        Unterschiede zum meinen Beispielen? Meine Beispiele waren nur Beispiele ;)

        Ciao, Frank

        1. Yea, danke. Hilft auf jeden fall !

          1. ach so. ist es möglich wenn z.B. 3 Profs mit einem Projekt verknüpft sind diese 3 Profs in eine Zeile zu bringen also

            Projekt, Prof1, prof2, prof3 ? geht das per join ?

            1. Dein Vorhaben mit den 3 Profs ist nicht so trivial in der Datenbank selbst zu lösen. Was du machen möchtest, nennt sich gemeinhin "Pivotieren".

              Aber mal ne Gegenfrage (oder auch ein paar mehr):

              • Wozu musst die Infos unbedingt in einer Zeile haben?
              • Und meinst du genau mit "einer Zeile"? Die Ausgabe im Browser?

              Ich würde dir empfehlen, das Professorenproblem separat mit einer Abfrage, die dir 3 Zeilen (1e pro Pforessor) zurückgibt, zu lösen und die Daten dann mittels PHP in der Ausgabe einfach zusammenzufügen.

              Ciao, Frank

              1. Also die sache is das ich z.B. 3 Professoren pro projekt hab.
                jedes Projekt hat wie gesagt eine ID

                ich such nun irgendwie nach projekten z.B. nach Tags und bekomme ProjektIDs die darauf zutreffen.
                sagen wir mal 3 projekte.

                wie mach ich die abfrage so das ich pro ID 3 professorennamen bekomm ?
                bzw. wie gebe ich diese aus.

                ausgabe könnt ich so machen :

                echo " Dozent: ",mysql_result($ergebnis,0,0).'<br/>';
                echo " Dozent: ",mysql_result($ergebnis,1,0).'<br/>';
                echo " Dozent: ",mysql_result($ergebnis,2,0).'<br/>';

                dann hab ich alle 3 dozenten untereinander.

                1. Hallo nochmal,

                  Also die sache is das ich z.B. 3 Professoren pro projekt hab.
                  jedes Projekt hat wie gesagt eine ID

                  Gemäss den von dir im Ausgangsposting genannten Tabellen hast du eine Tabelle "projekt_dozent", in welcher dozentId und projektId drin sind. Die ProjektIds bekommst du ja über die andere Abfrage nach den Tags. Da brauchst du doch einfach nur noch an deine bestehende "Tags"-Abfrage einen weiteren Join auf "projekt_dozent" mit der ProjektId dranhängen und einen von "projekt_dozent" auf "dozent" mittels der DozentId.

                  Ich möchte dir nicht alles haarklein vorkauen, dann hast du ja überhaupt keinen Lerneffekt, mal ein bisschen Pseudo-SQL

                  SELECT dozent.name
                  FROM projekt_dozent
                  JOIN dozent on dozentId ...
                  JOIN projekt_tags on projektId
                  JOIN tags on tagId
                  WEHRE tags.tagName = deinsuchtag

                  Oder du teilst deine Logik in

                  gibMirAlleProjekte   -> 1 SQL Abfrage
                  foreach(projekt in gibMirAlleProjekte)
                    gib mir dozenten von projekt   -> jeweils eine SQL Abfrage

                  ausgabe könnt ich so machen :

                  echo " Dozent: ",mysql_result($ergebnis,0,0).'<br/>';
                  echo " Dozent: ",mysql_result($ergebnis,1,0).'<br/>';
                  echo " Dozent: ",mysql_result($ergebnis,2,0).'<br/>';

                  dann hab ich alle 3 dozenten untereinander.

                  Mit etwas Layout anstelle von nur <br/> kannst du daraus auch eine horizontale Ausgabe machen ... deucht mich.

                  Oder anders gefragt: Was hast du bereits versucht (als Abfragen) und woran ist das dann gescheitert?

                  Ciao, Frank

                  1. habs durch rumprobieren hinbekommen.
                    hab deinen Rat befolgt und verschiedene Abfragen gemacht.

                    ich mach das jetzt so:

                    1. abfrage gibt die ProjektIDs raus die in Frage kommen.

                    dann gibts mehrere abfragen ( der Übersicht halber für mich )
                    die mir die ergebnisse liefern.

                    $loesung = array("3", "5", "10","500","2000","156",);
                    $lanzahl = count($loesung);

                    foreach($loesung as $loesung2){

                    //Anfang Selects

                    $dozent_projekt =  "SELECT dozent.dozentNAME, projekt.projektNAME, projekt_dozent.dozentID
                         FROM projekt_dozent
                         INNER JOIN dozent ON (projekt_dozent.dozentID = dozent.dozentID)
                         INNER JOIN projekt ON (projekt_dozent.projektID = projekt.projektID)
                         WHERE dozent.dozentNAME IS NOT NULL AND projekt_dozent.projektID=".$loesung2;

                    $student =  "SELECT student.studentNAME, projekt_student.studentID
                       FROM projekt_student
                       INNER JOIN student ON (projekt_student.studentID = student.studentID)
                       WHERE student.studentNAME IS NOT NULL AND projekt_student.projektID=".$loesung2;

                    $sem = "SELECT semester.semesterNAME
                      FROM projekt_semester
                      INNER JOIN semester ON (projekt_semester.semesterID = semester.semesterID)
                      WHERE semester.semesterNAME IS NOT NULL AND projekt_semester.projektID=".$loesung2;

                    $tag =  "SELECT tag.tagVALUE
                      FROM projekt_tag
                      INNER JOIN tag ON (projekt_tag.tagID = tag.tagID)
                      WHERE tag.tagVALUE IS NOT NULL AND projekt_tag.projektID=".$loesung2;

                    //Variablen speichern aus selects für jedes arrayfeld

                    $ergebnis = mysql_query($dozent_projekt);
                    $zeilen = mysql_num_rows($ergebnis);

                    $ergebnis2 = mysql_query($student);
                    $zeilen2 = mysql_num_rows($ergebnis2);

                    $ergebnis3 = mysql_query($sem);
                    $zeilen3 = mysql_num_rows($ergebnis3);

                    $ergebnis4 = mysql_query($tag);
                    $zeilen4 = mysql_num_rows($ergebnis4);

                    //Ausgabe Projektname, Semester, Jahr
                     echo "Projekt: ",mysql_result($ergebnis,0,1).'<br/>';
                     echo "Semester: ",mysql_result($ergebnis3,0,0).'<br/>';
                    //Ausgabe Dozenten
                     for($i = 0; $i < $zeilen; $i++){
                     echo "ID: ",mysql_result($ergebnis,$i,2),"    Dozent: ",mysql_result($ergebnis,$i,0).'<br/>';
                     }
                    //Ausgabe Studenten
                     for($i = 0; $i < $zeilen2; $i++){
                     echo "ID: ",mysql_result($ergebnis2,$i,1),"    Student: ",mysql_result($ergebnis2,$i,0).'<br/>';
                     }
                    //Ausgabe TAGs
                     for($i = 0; $i < $zeilen4; $i++){
                     echo "TAG: ",mysql_result($ergebnis4,$i,0).'<br/>';
                     }
                     echo '<br/>',"---------------------------------------------------------",'<br/><br/>';
                    }

                    hab ich vorhin noch gebastelt.

                    Danke für deine Hilfe. War super !