David301 Geschrieben 13. Juli 2005 Teilen Geschrieben 13. Juli 2005 Ich habe folgende kleine abfrage: SELECT DISTINCT P.threadid, P.userid, P.timestamp, T.headline FROM forum_threads T, forum_posts P WHERE T.forenid =1 AND T.threadid = P.threadid ; Diese Abfrage wird auf einem MySQL-Server ausgeführt. Mein Problem ist, dass das DISTINCT nicht mehr funktioniert, sobald ich die Spalte P.timestamp dazu nehme. Dann bekomme ich auch doppelte threadids ausgegeben. Kann es daran liegen, dass timestamp nicht NOT NULL ist? Das kann ich aber auch nicht ändern. Oder liegt es am Format? Habe das Format Timestamp gewählt. Hab vorher immer mit Oracle gearbeitet und da habe ich für Datum/Zeit-Angaben immer DATE benutzt. Aber DATE scheint ja unter MySQL keine Zeit zu enthalten. Das Ziel ist jedenfalls, die forum_posts auf die forum_threads zu joinen aber nur den ersten Treffer aus forum_posts zu erhalten. Wenn jemand eine Idee hat, wie man das anders umsetzt, ist das auch ok. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Monty82 Geschrieben 13. Juli 2005 Teilen Geschrieben 13. Juli 2005 Ungetestet: SELECT DISTINCT P.threadid, P.userid, P.timestamp, T.headline FROM forum_threads T, forum_posts P WHERE T.forenid =1 AND T.threadid = P.threadid GROUP BY P.threadid, P.userid Darf man Fragen, welche Darstellung Dein Ziel ist? Weil Threads ohne Einträge werden ja dann gar nicht angezeigt... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David301 Geschrieben 13. Juli 2005 Autor Teilen Geschrieben 13. Juli 2005 Wunderbar, das funktioniert. Danke Ziel ist die Auflistung aller threads in einem Forum. Threads ohne Inhalt sind sowieso nicht vorgesehen. Um den Erstellungszeitpunkt und den Author zum Thread zu haben, wird einfach der erste Post verwendet. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_JesterDay Geschrieben 14. Juli 2005 Teilen Geschrieben 14. Juli 2005 Diese Abfrage wird auf einem MySQL-Server ausgeführt. Mein Problem ist, dass das DISTINCT nicht mehr funktioniert, sobald ich die Spalte P.timestamp dazu nehme. Dann bekomme ich auch doppelte threadids ausgegeben. Das liegt daran, dass der Timestamp die Zeit bis zu einer Genauigkeit von 1 tausendstel Sekunde enthält. Wenn du jetzt 1 eintrag in jede Tabelle direkt hintereinander machst, stimmt zumindest dieser Bruchteil einer Sekunde ziemlich sicher nicht überein. Mit Distinct filterst du nur die Ergebnisse, die in alle gewählten Spalten gleich sind. Der Aufbau deiner DB ist mir nicht ganz klar. Du hast eine eigene Tabelle, in der du Threads speicherst, aber die eigentliche Information zu einem Thread kommt ja doch aus dem Beitrag... irgendeinem Beitrag(?). Wieso gibst du deinem Thread nicht noch die Felder Überschrift, erstellt (timestamp) und userid? Dann hätte jeder Thread genau 1 Überschrift, 1 Ersteller und 1 Zeitpunkt, wann er erstellt wurde. Ausserdem würde die Abfrage "SELECT * FROM forum_threads" genügen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
kills Geschrieben 14. Juli 2005 Teilen Geschrieben 14. Juli 2005 Ich kann Jesterday nur zustimmen. Diese Felder gehören eigentlich in die Tabelle Threads mit rein... Gruß, Markus Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Jaraz Geschrieben 14. Juli 2005 Teilen Geschrieben 14. Juli 2005 Hi, Kann es daran liegen, dass timestamp nicht NOT NULL ist? Das kann ich aber auch nicht ändern. Oder liegt es am Format? Habe das Format Timestamp gewählt. Hab vorher immer mit Oracle gearbeitet und da habe ich für Datum/Zeit-Angaben immer DATE benutzt. Aber DATE scheint ja unter MySQL keine Zeit zu enthalten. timestamp ist dafür nicht geeignet, da er sich bei jeder Änderung des Datensatzes aktualisiert. Nimm anstatt DATE einfach DATETIME, dann haste auch die Zeit mit drin. Gruß Jaraz Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
beetFreeQ Geschrieben 14. Juli 2005 Teilen Geschrieben 14. Juli 2005 Wunderbar, das funktioniert. Danke Ziel ist die Auflistung aller threads in einem Forum. Threads ohne Inhalt sind sowieso nicht vorgesehen. Um den Erstellungszeitpunkt und den Author zum Thread zu haben, wird einfach der erste Post verwendet. Hast du das auch schonmal mit einem Thread probiert, in dem zwei verschiedene User einen Post geschrieben haben? Diese sollten dann nämlich trotzdem beide erscheinen. Daher geht das IMO auch nicht ganz... Ich kann Jesterday nur zustimmen. Diese Felder gehören eigentlich in die Tabelle Threads mit rein... Gruß, Markus Das würde ich nicht sagen - da ja jeder einzelne Post einen Ersteller und ein Datum hat, machen die Felder in der Tabelle Post schon Sinn. In Threads wären sie redundant. Und wie er sagt, gibt es ja auch keine Threads ohne Posts - also ist der erste Post automatisch der Text des Threads. So wird es AFAIK in fast jedem Forensystem gemacht. Die Überschrift des Threads ist ja schon in der Tabelle Threads vorhanden, wenn es allerdings so wie hier im Forum wäre, wo jeder Post eine eigene Überschrift haben kann, wäre de Spalte ebenfalls in Posts besser aufgehoben! Ich würde zur Ermittlung des ersten Posts und auch der Reihenfolge der Posts vielleicht noch ne feste Nummer in die Tabelle Posts einfügen, die bei jedem ersten Post mit 1 beginnt und hochgezählt wird - dann könnte man ganz einfach über PostNr = 1 nur die jeweils ersten Posts pro Thread anzeigen lassen... Also meine Lösung wäre dann folgende (Hoffe, die Syntax passt zu MySQL) SELECT P.threadid, P.userid, P.timestamp, T.headline FROM forum_threads T JOIN forum_posts P ON (T.threadid = P.threadid and P.PostNr = 1) WHERE T.forenid = 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David301 Geschrieben 14. Juli 2005 Autor Teilen Geschrieben 14. Juli 2005 Oh, sind ja noch einige Antworten gekommen. @Jesterday: timestamp wird ja auch nicht mit DISTINCT aussortiert sondern die Threadid. Es werden also zu erstmal alle Posts eines Threads ausgelesen (Where threadid = x) und durch das DISTINCT soll nur der erste Treffer mit der threadid stehen bleiben. (DISTINCT threadid) Das funktioniert auch solange man nicht auch noch timestamp selected. Finde ich komisch. Der Aufbau mit den 2Tabellen gefällt mir eigentlich ganz gut und ich hatte eigentlich nicht vor jedem User die Möglichkeit einer Überschrift zu geben, da es eigentlich nicht nötig ist. Fände es nicht so praktisch die Threadlist komplett aus der Poststabelle auszulesen. @beetFreeQ: Die Idee mit dem Extrafeld für den Threaderstelle ist gar nicht schlecht. Wäre dann wahrscheinlich auch performanter. Allerdings ist es wegen des ORDER BY timestamp unnötig das Teil hochzuzählen. Habe mir gerade überlegt, eine "Bool"-Variable dafür anzulegen(Threadersteller true oder false ). Welcher Datentyp sollte ich da verwenden. Gibt es einen BOOL in SQL? INT mit 0 und 1 würde ja auch gehen. Ob deine Syntax so auf MySQL funzt kann ich nocht nicht sagen. Habe ich auf Oracle aber auch so gelernt. Allerdings haben mich die Leute während meines Praktikums blöd angeguckt als ich denen sowas abgeliefert habe. Hatten dei anscheinend noch nicht gesehen. Seitdem schreibe ich das immer mit WHERE und AND. Obwohl es eigentlich etwas unübersichtlicher ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_JesterDay Geschrieben 14. Juli 2005 Teilen Geschrieben 14. Juli 2005 @Jesterday: timestamp wird ja auch nicht mit DISTINCT aussortiert sondern die Threadid. Es werden also zu erstmal alle Posts eines Threads ausgelesen (Where threadid = x) und durch das DISTINCT soll nur der erste Treffer mit der threadid stehen bleiben. (DISTINCT threadid) Das funktioniert auch solange man nicht auch noch timestamp selected. Finde ich komisch. DISTINCT bezieht sich auf die Ergebnismenge, nicht das Feld dahinter. SELECT DISTINCT Feld1, Feld2 FROM Tabelle liefert dir ein Ergebniss, in dem alle Datensätze drin sind, die unterschiedlichen Werte für Feld1 und Feld2 (in Kombination) haben. SELECT DISTINCT Feld1, DISTINCT Feld 2 FROM Tabelle liefert dir höchstwahrscheinlich nur einen Fehler Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David301 Geschrieben 14. Juli 2005 Autor Teilen Geschrieben 14. Juli 2005 Was? *imoraclebuchnachschlag* Ich war mir ziemlich sicher dass DISTINCT sich nur auf die folgende Spalte bezieht. Ist das bei MySQL nicht so? Das muss ich jetzt dirrekt mal austesten. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David301 Geschrieben 14. Juli 2005 Autor Teilen Geschrieben 14. Juli 2005 Gabs hier nicht gerade noch nen EDIT-Knopf? Irgendwie ist der weg, obwohl ich eingelogt bin. Sorry für den Doppelpost aber irgendwie kann ich meine Beiträge nicht bearbeiten. @Jesterday: Du hast Recht. Das DISTINCT bezieht sich wirklich auf alle Spalten aus der gleichen Tabelle. Das ist ja blöd. Bei Oracle ist das aber nicht so. Aber ist ja nicht so schlimm. Die GROUP BY Lösung funktioniert ja. Jetzt fehlen mir nur noch Kommentare zu der Lösung mit der "BOOL"-Spalte. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
~Hawkeye~ Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 Zu den Posts einen Primary Key erfassen mit fortlaufender Nummer - am besten gleich Autoincrement - und dann mit einem SELECT MIN() den kleinsten Post für den jeweiligen Thread auslesen. Der kleinste Wert im Primary Key, des jeweiligen Topics ist auch der erste. Damit wäre die zusätzliche Spalte überflüssig. Übrigens sind Threads und Posts 2 verschiedene Objekte im DBMS. Ergo 2 verschiedene Tabellen und nicht beides in eine oder gemischt. Die gehören zudem obligatorisch 1:n verknüpft. 1 Thread muss 1 oder mehr Posts haben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_JesterDay Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 Das würde ich nicht sagen - da ja jeder einzelne Post einen Ersteller und ein Datum hat, machen die Felder in der Tabelle Post schon Sinn. In Threads wären sie redundant. Und wie er sagt, gibt es ja auch keine Threads ohne Posts - also ist der erste Post automatisch der Text des Threads. So wird es AFAIK in fast jedem Forensystem gemacht. Weiss ich jetzt gar nicht, ob das in jedem forensystem so gemacht wird, kann ich mir daheim bei phpBB aber mal ansehen (wenn ich es nicht vergessen). Kann mir das aber ehrlichgesagt nicht vorstellen. Stell dir mal vor, aus irgendeinem Grund muss der erste Beitrag gelöscht werden (oder wird es), dann hast du auf einmal einen neuen Thread mit neuem Thema und neuem Ersteller, neuem Erstellungszeitpunkt... aber alten Beiträgen. Für den ersten Beitrag mag das vielleicht dann redundant sein, aber die theoretische Lösung (x. Normalform) ist in der Praxis nicht unbedingt immer die beste. EDIT: IMHO sollten die Threads vollkommen unabhängig von den Beiträgen darin sein. Und ich bin auch der Meinung, dass das in fast jedem Forensystem so gemacht wird Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
beetFreeQ Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 Weiss ich jetzt gar nicht, ob das in jedem forensystem so gemacht wird, kann ich mir daheim bei phpBB aber mal ansehen (wenn ich es nicht vergessen). Kann mir das aber ehrlichgesagt nicht vorstellen. Stell dir mal vor, aus irgendeinem Grund muss der erste Beitrag gelöscht werden (oder wird es), dann hast du auf einmal einen neuen Thread mit neuem Thema und neuem Ersteller, neuem Erstellungszeitpunkt... aber alten Beiträgen. Für den ersten Beitrag mag das vielleicht dann redundant sein, aber die theoretische Lösung (x. Normalform) ist in der Praxis nicht unbedingt immer die beste. EDIT: IMHO sollten die Threads vollkommen unabhängig von den Beiträgen darin sein. Und ich bin auch der Meinung, dass das in fast jedem Forensystem so gemacht wird Hmm, war mir auch nicht 100% sicher - hab's nur so gelernt und auch für sinnvoll gehalten. Aber klar, wenn der erste Post gelöscht werden muss, passen die Daten nicht mehr zusammen, aber ist es denn besser, einen Thread von Benutzer X zu haben, der dank Löschens des ersten Posts mit einer Antwort von Benutzer Y anfängt? - Ist so oder so etwas unglücklich, einfach so einen ersten Post zu löschen... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_JesterDay Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 aber ist es denn besser, einen Thread von Benutzer X zu haben, der dank Löschens des ersten Posts mit einer Antwort von Benutzer Y anfängt? - hm... ich denke da an einen Thread, in dem Benutzer Links zu ihren Lieblingswebseiten, oder Bildern o.ä. posten. Threadüberschrift "Lieblingslinks". Ok, natürlich ist das etwas aus der Luft gegriffen, aber ich wollte nur auf die vermeidbare Abhängigkeit von Thread und Beitrag hinweisen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
~Hawkeye~ Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 Also der weitere Posts hängen vom ersten Post und der vom Topic ab? Wenn ich das richtig verstehe, dann lösch ich also den ersten Post und dann wird nicht einer der anderen Posts zum ersten sondern die anderen Post liegen ohne Beziehung, weil der jeweilige Foreign Key nicht mehr gleich dem jeweiligen Primary Key ist. Damit sehe ich gar keine Posts mehr zu dem Thema. Es ist nur sinnvoll die Beiträge, auch wenn es der erste sein mag, in einer anderen Tabellen zu speichern als das Topic. Allein schon, wenn ein Topic sich ändert, dann muss der Name des Topics in mehreren Datensätzen geändert werden. Und das Ganze auch noch fehlerfrei und ohne Transaktionen oder Stored Procedures in MySQl. Zudem um herraus zu finden wer ein Topic erstellt hat, kann man auch einfach den Primary Key des jeweiligen Users mit in die Topic- Tabelle übernehmen. Man sollte nur nicht vergessen auch hier User nur im Vordergrund zu löschen, weil ansonsten das SELECT fehlschlägt. Aber dafür kann man ja mit nem Bool (User gelöscht? Ja, Nein)in der Usertabelle arbeiten. Im phpbb sind die übrigens getrennt und mit fällt kein Forensystem ein , wo es so ist, wie Du beschreibst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
beetFreeQ Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 Im phpbb sind die übrigens getrennt und mit fällt kein Forensystem ein , wo es so ist, wie Du beschreibst. Wen meinste jetzt? Und was meinste mit getrennt? Alle Daten zu jedem Post in der Posts-Tabelle und nur eine Thread-ID in der Threads-Tabelle? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
~Hawkeye~ Geschrieben 15. Juli 2005 Teilen Geschrieben 15. Juli 2005 Jedes Topic hat eine ID, jeder Post zu einem Topic hat die Topic ID als Foreign Key. Hier ist nochmal die Datenbankbeschreibung vom phpbb. http://www.phpbb.de/doku/doku2.php Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David301 Geschrieben 16. Juli 2005 Autor Teilen Geschrieben 16. Juli 2005 Es ist meiner Meinung optimal so wie es ist. - Eine Tabelle für Threads/Topics mit ID, Überschrift - Eine Tabelle mit Posts mit UserID, Text, Zeitpunkt... - Werden alle Threads eines Forums angezeigt, wird der erste Post (identifiziert durch frühestes Datum) verwendet für Erstellungsdatum und Author - Würde der erste Post gelöscht, würde der zweite Post zum Ersteller, was aber eigentlich egal ist, da ich es sehr viel wahrscheinlicher finde, dass der Thread gesperrt wird anstatt dass der erste Post gelöscht wird -Beim Aufruf des Threads werden alle Posts mit der Threadid, geordnet nach dem Zeitpunkt, angezeigt Finde ich so schonmal gut. Hab mir gerade mal kurz die Doku angesehen. Ist es nicht totaler Schwachsin in die Poststabelle die forenid mit reinzunehmen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
~Hawkeye~ Geschrieben 16. Juli 2005 Teilen Geschrieben 16. Juli 2005 Naja es ist im Prinzip wieder denormalisiert da eine transitive Abhängigkeit zwischen dem Post und dem Forum besteht und diese sollte eigentlich in der 3. Normalform weiter augeschlüsselt werden. Der Grund für die direkte Verknüpfung sollte Performance sein um den letzten Post in einem Forum anzeigen zu können ohne den Weg über das Topic zu gehen. Um die Performance zu steigern wird oft nach dem Normalisieren wieder denormalisiert. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.