Rekursives durchlaufen einer Datenbank

zeroize

Erfahrenes Mitglied
Hi an alle,

ich bin gerade dabei einen kleinen Aufgabenmanager umzuschreiben. Die Funktion des Aufgabenmanagers ist einfach - man kann Texte eingeben, die werden angezeigt. Auf die einzelnen Texte kann man antworten. Es ist so geschrieben, dass jeder Eintrag in die Tabelle Aufgaben geschrieben wird, auch die Antworten - bei den Antworten ist dann noch ein zusätzlicher Eintrag in der Datenbank, auf welchen Eintrag sich die Antwort bezieht.
Das Problem ist, dass ich die Einträge jetzt mit einer verschachtelten while-Schleife (erste Schleife für die Aufgabe, darin eine weitere für die Antworten) für die Ausgabe einsetze.
Das ist allerdings überhaupt nicht performant meiner Meinung nach, weil ja bei jeder Aufgabe eine SQL-Abfrage gestartet werden muss, um zu schauen, ob Antworten da sind.

Weiß jemand eine andere Möglichkeit?
 
Ok. Soweit habe ich es verstanden (denk ich mal) und auch eine Lösung dafür im Kopf entwickelt. Wenn du deinen Quelltext dazu zeigst, kann man den Optimieren.

Meine Lösung wäre einfach nur ein Query, der alle Antworten zu einem Text ausgibt.
Der Aufbau der Tabelle wäre: TextID, Left, Right, Text
Und das ganze über Nested-Sets Lösen: http://phpperformance.de/nested-sets-hierarchische-strukturen-und-baeume-in-mysql/

Den Rest macht das PHP-Script ganz schnell.
 
Zuletzt bearbeitet:
Hi,

Ich würde das eher in 2 Tabellen aufteilen und über einen JOIN lösen. Nested Sets sind empfehlenswert, wenn Die Struktur eher selten verändert wird, was hier vermutlich nicht der Fall ist.
Das Ganze ließe sich auch wohl, so wie die Struktur jetzt ist, über einen SELF JOIN machen. 2 Tabellen finde ich aber sauberer.

LG
 
Vielen Dank für die Antworten, hier der Ausschnitt aus dem Quelltext,
ich hoffe ihr könnt damit was anfangen (bitte keine Kommentare darüber, dass das ganze in Tabellen geschrieben wird, ich muss das ganze auch noch in divs bauen, damit ich das mit ajax verändern kann, aber vorerst hab ich mich für Tabellen entschieden :) ).
PHP:
$res = mysql_query("SELECT *
					FROM Tasks
					INNER JOIN Mitarbeiter ON Tasks.Mit = Mitarbeiter.ID
					WHERE An='' AND Archiv='".$showarch."' ORDER BY Date DESC, Time DESC")or die(mysql_error());

while($row = mysql_fetch_assoc($res))
{
    echo "<table class=thread cellspacing=0>\n";
	echo "<tr class=thread><td class=thread width=10px>\n";
	echo "&nbsp;</td><td class=thread width=85px>".$row[Date]."<br>".$row[Time]."</td><td>">".$row[Name].";
	echo "<td class=thread width=600px><span style=color:".$row[Color].">".nl2br($row[Besch]);
	echo "<td class=thread>\n";
	    
    $res2 = mysql_query("SELECT *
                        FROM Tasks 
                        INNER JOIN Mitarbeiter ON Tasks.Mit = Mitarbeiter.ID 
                        WHERE An=".$row[Id]." AND Archiv='".$showarch."' ORDER BY Date, Time")or die(mysql_error());
    
    while($an = mysql_fetch_assoc($res2))
    {
	    echo "<tr><td width=10px>\n";
	    echo "</td><td width=85px><div>".$an[Date]."-".$an[Time]."</td><td>".$an[Name]."<td>".nl2br($an[Besch])."</td><td>\n";
		echo "<img src=../img/http.png id=\"ch".$an[Id]." onclick=\"chshow(this,'".$an[Id]."')\"></td></tr>";
		
	}	
	echo "</table><table><td>&nbsp;</td><td>&nbsp;&nbsp;\n";
	echo "<img src=../img/antwort.gif id=\"ant".$row[Id]."\" onclick=\"anshow(this,'".$row[Id]."')\">\n";
	echo "</td></table>\n";
}
Ich persönliche finde, dass eine zweite Tabelle für die Antworten weniger "schön" ist, weil die Tabellenstruktur für die Antworten = der Tabelle der Aufgaben + 1 Feld für die ID der Aufgabe ist. Außerdem muss dann tatsächlich immer ein Join gemacht werden, was auch nicht soo eine performante Lösung ist, oder?
Ich bin ja nicht Beratungsresistent - was meint ihr dazu?
 
Hi,

Ich persönliche finde, dass eine zweite Tabelle für die Antworten weniger "schön" ist, weil die Tabellenstruktur für die Antworten = der Tabelle der Aufgaben + 1 Feld für die ID der Aufgabe ist.

Da sehe ich kein Argument drin.

Außerdem muss dann tatsächlich immer ein Join gemacht werden, was auch nicht soo eine performante Lösung ist, oder?

Das ist garantiert performanter, als in der Schleife nochmal für jede Aufgabe einzeln eine Abfrage auf die Antworten abzusetzen.

LG
 
Naja, was macht es für einen Sinn, eine zweite Tabelle für die Antworten zu erstellen, wenn bereits eine andere Tabelle besteht, die die gleichen Daten speichern kann? Ist das nicht zwei mal das gleiche? Ich bin nicht besonders gut im Bereich Datenbanken aber mein Prof würde sagen - 3. Normalform, dann ist Schluss ;-).
Mein großes Problem das ich damit habe, ist eigentlich meine momentanen Implementierungsvorstellungen: denn am Ende sollen einzelne Antworten und Aufgaben gelöscht werden können und somit könnte eine Antwort, dann wieder eine neue Aufgabe sein - und wäre damit in der falschen Tabelle.
Oder wie würdest du dieses Problem lösen?
 
Hi,

Naja, was macht es für einen Sinn, eine zweite Tabelle für die Antworten zu erstellen, wenn bereits eine andere Tabelle besteht, die die gleichen Daten speichern kann?

Na ja, das ist ja nu auch kein Argument. Dann könnte man ja immer grundsätzlich alles in einer Tabelle speichern. Das kann man ja einrichten, dass die alles speichern kann.

denn am Ende sollen einzelne Antworten und Aufgaben gelöscht werden können und somit könnte eine Antwort, dann wieder eine neue Aufgabe sein - und wäre damit in der falschen Tabelle.
Oder wie würdest du dieses Problem lösen?

So etwas würde ich gar nicht implementieren. Entweder etwas ist eine Aufgabe oder eine Antwort/Kommentar/whatever... Klingt irgendwie seltsam. Warum soll das denn so sein, bzw. was soll das werden?

LG
 
Naja, es wird halt ein Collaboration-Tool für eine kleine Arbeitsgruppe. Jeder kann dort Nachrichten (Tasks) eintragen, z.B. Telefonanrufe von Kunden, ToDos, Termine, etc.
Wenn man es erweitern möchte, oder etwas zu dem Thema beizutragen hat, oder eben die Aufgabe erledigt hat, kann man darauf antworten.
Natürlich kann so ein Thread lang werden und bei einer längeren Diskussion können natürlich Folgeauträge entstehen, die also quasi wieder Aufgaben sind, die jemand erledigen soll.
Ich hoffe ich hab das halbwegs verständlich erklärt :).

Ich würde deine Lösung mit den zwei Tabellen sofort übernehmen, wenn ich nicht wüsste, das sobald in einer Antwort eine weitere Aufgabe drin stehen würde, sofort die Daten in der falschen Tabelle wären. mmhhh, schwieriger als ich es mir vorgestellt hab...
 
Hi,

Natürlich kann so ein Thread lang werden und bei einer längeren Diskussion können natürlich Folgeauträge entstehen, die also quasi wieder Aufgaben sind, die jemand erledigen soll.

Dann muss das auch als neue Aufgabe eingetragen werden. Dafür könnte man z.B. einen Button vorsehen, der das Anlegen eines neuen Tasks mit den Daten der "Antwort" auslöst.

Ich würde deine Lösung mit den zwei Tabellen sofort übernehmen, wenn ich nicht wüsste, das sobald in einer Antwort eine weitere Aufgabe drin stehen würde, sofort die Daten in der falschen Tabelle wären. mmhhh, schwieriger als ich es mir vorgestellt hab...

Na, irgendwie feststellen musst Du diese Tatsache doch. Was hindert Dich denn daran, statt dann dieses Flag in der Tabelle zu verändern, einen neuen Datensatz in der richtigen Tabelle anzulegen? Löschen und rumschieben würde ich so etwas gar nicht. Dann ist das alles später auch noch nachvollziehbar.

Vielleicht willst Du das Ganze ja auch mal so erweitern, dass man z.B. Beziehungen zwischen Tasks angeben kann (z.B. wenn sich aus einem Task ein neuer ergeben hat...;) ). Wie willst Du das in einer einzigen Tabelle (vernünftig) verwalten?

LG
 
Ich finde kuddels Lösungsvorschlag gut und würde es auch so ähnlich angehen. Würde auch strikt zwischen einer Aufgabe und einer Antwort unterscheiden. Ich kenne deine Anwendung nicht aber es klingt für mich so als wäre eine Aufgabe logisch betrachtet etwas völlig anderes als eine Antwort. Und wenn in einer Antwort eine neue Aufgabe versteckt ist, wie erkennst du das in deinem System? Parst du den Nachrichtentext? Da würde sich wahrscheinlich wirklich ein Button Folgeaufgabe neben dem Antwortbutton anbieten.

Nur weil es zunächst so aussieht, als würde die Tabellenstruktur von Aufgabe und Antwort übereinstimmen ist kein Argument sie in die gleiche Tabelle zu speichern. Grundsätzlich ist es so, dass das Speichern logisch verschiedener Objekte in der gleichen Tabelle zwangsläufig zur Verletzung der Grundregeln für gutes DB-Design führen, auch der 3.NF. Daraus erwachsen eine große Menge an Problemen wenn man die Datenbank später vielleicht erweitern möchte.
 

Neue Beiträge

Zurück