dedlfix: MySQL - Sehr sehr schwerer Query, ich schaffs nicht alleine

Beitrag lesen

echo $begrüßung;

Nun geht es Darum einen Thread darzustellen.
Dafür müssen sämtliche Informationen aus der Datenbank geholt werden.
Wenn möglich mit einem Query.

Möglich ist das - irgendwie - aber nicht sinnvoll. Denn dazu müsstest du mehrere Abfragen mit UNION verbinden, was nur bei gleichen oder vergleichbaren Feldern sinnvoll ist. Die Anzahl muss auch übereinstimmen. Und beim Auswerten musst du unterscheiden, welcher Datensatz für welche Informationsart (Thread, Posting, Pic) steht. Andererseits kannst du joinen, wobei aber ohne Join-Bedingung x Datensätze aus der einen Tabelle und y Datensätze aus der anderen Tabelle x × y Datensätze in der Ergebnismenge ergeben (jeder mit jedem - kartesisches Produkt). Mit einer Join-Bedingung kann man die Menge reduzieren, aber es entstehen dann immer noch für beispielsweise 5 Postings gejoint mit einem Thread insgesamt 5 Postings mit 5 mal den Thread-Daten dazu, obwohl du die Thread-Daten vielleicht nur einmal für den Seitenkopf brauchst. Noch schlimmer wird es, wenn Pics in wechselnder Anzahl und unregelmäßig in die Postings eingestreut sind. Dann hast du entweder zu viele sich wiederholende Postingdaten oder zu viele Bilder im Ergebnis oder beides. Joine also nur da, wo es für das Ergebnis sinnvoll ist und mach dir das Programm nicht an anderer Stelle unnötigerweise komplexer, nur weil du hier etwas sparen willst. Optimieren geht meist ganz anders.

Ich würde mit einer Abfrage die Daten zu Thread 1 aus board_thread holen. Eine zweite Abfrage holt die Postings zu diesem Thread. Eine dritte die Pics. Gejoint werden müssen nur die Userdaten mit den Postings, denn nur die stehen in einem direkten 1:1-Zusammenhang.

Besonders schwer tue ich mich bei den Categories diese sind ja so aufgebaut das solange der subcategoryid-Wert != 0 ist, eine weiter Category darunter liegt.
Also ich will in diesem Fall später ausgeben können: Sport -> Handball -> Vereine

Auch die Abfrage der Kategorienhierarchie bekommt eine eigene Abfrage, wenn nicht sogar eine komplette Umgestaltung. Die Kategorie mit dem niedrigsten Level bekommst du aus der Thread-Abfrage über die dortige categoryid.

board_category
##############
categoryid subcategoryid categoryname
1          0             Sport
2          1             Handball
3          2             Vereine
4          0             Ernährung

Die Herausforderung ist jetzt aber, an die jeweils übergeordneten Levels zu kommen, ohne ständig die subcategoryid aus dem Ergebnis auswerten und eine neue Abfrage absenden zu müssen. Das Problem dabei ist, dass du nicht in einer Bedingungsformulierung alle übergeordneten Kategorien und nur diese ansprechen kannst. Jedenfalls nicht dann, wenn die Tiefe unterschiedlich ist, also einmal 3, ein anderes Mal 2 und manchmal 4 Level bis oben abzufragen sind. Bei feststehender Tiefe kann man da mit Selfjoins was hinbekommen, was bei n Levels n-1 Joins bedeutet. Für dieses Dilemma gibt es (besser: kenne ich) zwei Lösungswege.

Wenn die Anzahl der Kategorien überschaubar klein ist, kann man einfach alle Datensätze abfragen und die passenden Kategorienamen rekursiv im Programm heraussuchen. Der Aufwand das in Code zu fassen ist nicht besonders hoch. Allerdings erhöht sich mit steigender Kategorienanzahl die für jedes Level benötigte Zeit beim Durchlaufen der Datenmenge.

Bei umfangreichem Kategorie-Baum ist es deshalb sinnvoller, nur die benötigten Daten aus dem DBMS zu holen. Dafür hat man Nested Sets erfunden. Jedoch erkauft man sich die Vorteile von Nested Sets mit einer erhöhten Komplexität bei der Datenpflege. Einfügen und Löschen sind aufwendig, weil stets mehr oder weniger große Teile der Datensätze zu ändern sind. Nested Sets spielen ihre Vorteile aus, wenn viel gelesen und wenig geändert wird. Zu Nested Sets gibt es einiges Material im Netz, einfach mal danach googeln oder bingen.

Mein Bauchgefühl rät mir zur Alles-und-dann-selbst-suchen-Variante statt Nested Sets. Die Kategorienanzahl wird sich im niedrigen zweistelligen Bereich bewegen, da ist das vertretbar, wenn man sich auf der anderen Seite den Nested-Sets-Aufwand dazu anschaut.

JOIN board_thread_post ON board_thread_post.threadid = '1'
JOIN board_thread_media ON board_thread_media.threadid = '1'
JOIN users ON users.uid = board_thread_post.uid
JOIN board_category ON board_category.categoryid = board_thread.categoryid
WHERE board_thread.threadid = '1'[/code]

In der ON-Klausel eines Joins sollten nur die Verknüpfungsbedingungen stehen. Die Datenmenge einschränkende Bedingungen gehören ins WHERE. Lediglich die für die Verknüpfung relevanten/notwendigen einschränkenden Bedingungen kommen noch mit ins ON. Doch auf den Fall trifft man(/ich) eher selten.

echo "$verabschiedung $name";