Tach!
/* Beziehung zwischen Menüs und Seiten */
CREATE TABLEcms\_menu\_pages
(id
int(11) NOT NULL AUTO_INCREMENT,
leftkey
int(11) NOT NULL,
rightkey
int(11) NOT NULL,
menu\_id
int(11) NOT NULL,
page\_id
int(11) NOT NULL,
Das ist ja die Nested-Sets-Tabelle. Und sie ist gleichzeitig die Verbindungstabelle einer m:n-Beziehung zwischen Menüs und Seiten. Für das Verständnis ist es wichtig, die Beziehungen zwischen den beiden abseits des Datenbankschemas und mehr aus fachlicher Sicht zu kennen. Ist es so, dass alle Menüpunkte in menues gelistet sind und in menu_pages die hierarchische Struktur abgebildet ist? Andererseits kann ich mir vorstellen, dass die m:n-Beziehung aussagt, welche Menüpunkte auf welcher Seite zu sehen sein soll. Wie aber spielt das mit der Hierarchie zusammen. Ein Menüpunkt kann vermutlich auf mehreren Seiten auftauchen und dann ist er mehrmals in den Nested Sets enthalten, oder nicht? Oder ist das alles ganz anders? Hier sehe ich Aufklärungsbedarf.
SELECT
cms\_menues
.name
ASmenuName
,
cms\_menu\_pages
.leftkey
,
cms\_menu\_pages
.rightkey
,
cms\_pages
.id
,
cms\_pages
.name
FROMcms\_menu\_pages
JOINcms\_pages
ONcms\_menu\_pages
.page\_id
=cms\_pages
.id
JOINcms\_menues
ONcms\_menu\_pages
.menu\_id
=cms\_menues
.id
Es joint hier zur m:n-Tabelle die m- und n-Tabelle, um deren Daten zu bekommen.
Zur WHERE-Klausel komme ich gleich noch. Aber du hast da eine Gruppierung,
GROUP BY
cms\_menu\_pages
.page\_id
mit der du viel mehr Spalten direkt und nicht aggregiert abfragst, als hier gruppiert wurden. Das lässt nur MySQL zu, anderswo wird das als Fehler geahndet. MySQL nimmt dann als Ergebnis pro Gruppe irgendeinen Wert dieser ungruppierten Spalten. Zu jeder Page-Id kommt also irgendeine beliebige Menu-ID ins Ergebnis. Das scheint mir komisch zu sein, aber vielleicht löst sich ja mit Kenntnis der Bedeutung auf. Zurück zum WHERE.
WHERE
cms\_pages
.id
Wir wollen nur Seiten,
IN(
SELECT
cms\_content
.page\_id
FROMcms\_content
JOINcms\_rights
ONcms\_content
.id
=cms\_rights
.content\_id
WHERE
cms\_rights
.group\_id
IN(
SELECTcms\_user\_groups
.group\_id
FROMcms\_user\_groups
WHEREcms\_user\_groups
.user\_id
= ?
)
für deren Content der Nutzer über die Gruppenzugehörigkeit die Berechtigung hat (Ich habs mal umsortiert.)
AND
cms\_content
.page\_id
IN(
SELECTcms\_pages
.id
FROMcms\_menu\_pages
JOINcms\_pages
ONcms\_menu\_pages
.page\_id
=cms\_pages
.id
WHEREcms\_menu\_pages
.menu\_id
= ?
(Einmal pages unnötigerweise gejoint. Die pages.id ist bereits als menu_pages.page_id verfügbar.)
und die zur übergebenen Menü-ID passen. Aber die Bedeutung dieser Bedingung erschließt sich mir nicht. Warum wird hier die Menu-ID als Parameter übergeben?
)
)
Und liege ich richtig, wenn ich vermute, dass ich die Beispiele von deinem Link einfach nur in das erste, äusserste
SELECT
schieben muss? Dann wäre es wohl doch einfacher als gedacht.
Das kann ich jetzt noch nicht sagen. Nur soviel: Nested-Sets-Abfragen verwenden oftmals Self-Joins und Gruppierung, so auch die Level-Query. Das mit der jetzigen gejointen und bereits gruppierten Query zu verheiraten wird eine ganz schöne Herausforderung werden.
Was meinst du, ist es sinnvoller mit der Datenbank-Abfrage oder mit dem Array zu spielen?
Bei der Komplexität der Query wird es wohl auf eine Array-Lösung hinauslaufen. Andererseits kann man die Komplexität mit noch mehr Komplexität augenscheinlich verringern. Die ungetestete Idee wäre, die Query in eine View zu bringen, dann wird die Anwendung des Self-Joins und der Gruppierung einfacher, als wenn man das Riesending doppelt notieren muss.
dedlfix.