mySQL Datenbank Design für verschachtelte, dynamische Navigation

Dieses Thema im Forum "Web-Programmierung" wurde erstellt von sevY, 18.03.2004.

  1. sevY

    sevY Thread Starter Gast

    Hi, ich komme nicht weiter…

    Ich versuche gerade ein CMS als Frontend an dein DB Modell zu setzen und frage mich, wie ich die Queries machen soll…


    Hier ist ein DB Modell, das ein Freund mir erstellte, mit dem er hoffte, das es gehen wird:

    PHP:
    #MySQL

    CREATE TABLE `multiple` (
      `
    idint(11NOT NULL auto_increment,
      `
    parent_idint(11NOT NULL default '0',
      `
    dateint(11NOT NULL default '0',
      `
    textvarchar(60) default NULL,
      `
    imagevarchar(60) default NULL,
      `
    linkvarchar(60) default NULL,
      
    PRIMARY KEY  (`id`)
    TYPE=MyISAM AUTO_INCREMENT=;




    Als Oberpunkte habe ich:

    A B C D E F G

    Jeder der Punkte hat Unterpunkte wie folgt:

    a b c d e


    Diese o.g. genannten Punkte sind alle fest und werden nicht erweitert.


    Diese Punkte enthalten Unterpunkte, die dynamisch erweiterbar sein sollen

    a b c d e


    Also:

    a1 a2 a3 a4 … ax

    b1 b2 b3 b4 … bx

    … … … … … …

    Diese Unterpunkte enthalten wiederum Unterpunkte:

    a1-1 a1-2 a1-3 a1-4 … a1x
    a2-1 a2-2 a2-3 a2-4 … a2x

    b1-1 b1-2 b1-3 b1-4 … b1x
    b2-1 b2-2 b2-3 b2-4 … b2x

    … … … … … …
    … … … … … …


    Und diese haben dann nocheinmal Unterpunkte.


    a1-1-1 a1-1-2 a1-1-3 … a1-1-x
    a1-2-1 a1-2-2 a1-2-3 … a1-2-x
    … … … … …

    a2-1-1 a2-1-2 a2-1-3 … a2-1-x
    a2-2-1 a2-2-2 a2-2-3 … a2-2-x
    … … … … …

    b1-1-1 b1-1-2 b1-1-3 … b1-1-x
    b1-2-1 b1-2-2 b1-2-3 … b1-2-x
    … … … … …

    b2-1-1 b2-1-2 b2-1-3 … b2-1-x
    b2-2-1 b2-2-2 b2-2-3 … b2-2-x
    … … … … …

    … … … … …
    … … … … …
    … … … … …



    Wie würde die Inhalte aussehen? Wie sieht zb die Query aus für 'b2-2-3' oder für 'b2-3' als Insert, Read, Update?


    Fragen Fragen Fragen nichts als Fragen…


    Liebe Grüße

    Yves
     
  2. balufreak

    balufreak MacUser Mitglied

    Beiträge:
    1.560
    Zustimmungen:
    28
    MacUser seit:
    12.10.2003
    Hallo Yves!

    Also ich würde das Problem mit mindestens zwei Tabellen lösen. Ich hab jetzt nicht wirklich gross darüber nachgedacht. Aber ich versuche hier mal ein Beispiel zu geben

    PHP:
    CREATE TABLE `parent` (
      `
    parent_idint(11NOT NULL auto_increment,
      `
    parent_nameint(11NOT NULL default '0',
      
    PRIMARY KEY  (`parent_id`)
    TYPE=MyISAM AUTO_INCREMENT=;  

    /*und für die eigentlichen Navi*/

    CREATE TABLE `navi` (
      `
    idint(11NOT NULL auto_increment,
      `
    parent_idint(11NOT NULL default '0',
      `
    dateint(11NOT NULL default '0',
      `
    textvarchar(60) default NULL,
      `
    imagevarchar(60) default NULL,
      `
    linkvarchar(60) default NULL,
      
    PRIMARY KEY  (`child_id`)
    TYPE=MyISAM AUTO_INCREMENT=;  
    Die Abfrage kannst du dann wie folgt machen.

    PHP:
    $sql="
    SELECT C.text, C.image, C.link, P.parent_name
    FROM navi AS C
    LEFT JOIN parent AS P ON C.parent_id = P.parent_id
    "
    ;
    Somit solltest du eine Tabelle in diesem Stil zurückbekommen:

    Code:
    | text | image | link | parent_name |
    |------|--------|------|----------------|
    | Seite 1 | bild.jpg | http://... | Seiten |
    
    Verstehst du in etwa wie ich das meine?

    Wenn du jetzt ein Parent setzen willst, musst du diesen in der parent Tabelle anlegen. Für die childs kannst du dann einfach die parent_id, welche erstellt wurde einfügen. Sollte so eigentlich klappen...

    Nachtrag: Mit dem obigen Query werden alle Parents angezeigt, auch diese, welche keine childs haben. Willst du dass nur die Parents angezeigt werden, welche childs haben, musst du anstelle von LEFT JOIN einfach INNER JOIN verwenden.

    Ich hoffe dir geholfen zu haben

    Greets balu
     
  3. Jakob

    Jakob MacUser Mitglied

    Beiträge:
    1.067
    Zustimmungen:
    21
    MacUser seit:
    05.01.2004
    Ist vielleicht ganz blöd: Kannst Du nicht einfach in der Tabelle noch drei Spalten anlegen?

    Code:
    Hauptpunkt  |  Unterpunkt1  |  Unterpunkt 2
    ------------|---------------|-----------------
           a    |       1       |                               <- Menüpunkt a-1
    ------------|---------------|-----------------
           c    |        2      |          3                   <- Menüpunkt c-2-3
    
    Und dann machst Du Queries wie "SELECT […] WHERE Hauptpunkt=a AND Unterpunkt1=1 AND Unterpunkt2=''". Damit bekommst Du dann alle Punkte der ersten Unterebene von a.

    Oder Du fragst gleich alles ab mit SELECT * und unterscheidest dann mit ner PHP-Funktion, welche Punkte wo Unterpunkte haben und angezeigt werden sollen.
     
    Zuletzt bearbeitet: 08.10.2005
  4. dms

    dms Thread Starter Gast

    Eine zweite Tabelle ist eigentlich nicht nötig. Einfach ein Feld "parentOf" oder sowas in die bestehende Tabelle einfügen. Darin wird ggf. die ID des übergeordneten Punkten gespeichert. Dann kann man leicht ermitteln ob es sich um einen Unter- oder Hauptpunkt handelt und zu welchem Hauptpunkt ein Unterpunkt gehört. Ich habe vor Ewigkeiten mal sowas gemacht. Der Code existiert leider nicht mehr.
     
  5. Yankee

    Yankee MacUser Mitglied

    Beiträge:
    155
    Zustimmungen:
    0
    MacUser seit:
    27.02.2004
    Sehe ich genauso, ein Feld "parent" oder ähnlich in die ursprüngliche Tabelle einzufügen sollte reichen. Allerdings nicht, wenn ein Menüpunkt mehrere Väter haben kann. Das Problem an solchen Strukturen in MySQL ist, dass es keine rekursiven Abfragen erlaubt, im Gegensatz zu mächtigeren Datenbanken.

    Wirkliche Probleme erhälst Du nicht beim Einfügen in den Baum, sondern beim Lesen und Aufbauen desselben in Bezug auf die Anzahl der Queries. Dafür gibt es meiner Ansicht nach 3 Möglichkeiten:
    1. Einen Query pro Menüpunkt, um die Kinder herauszufinden. Das ist recht dreckig, da viel zu viele Queries.
    2. Wenn der Baum auf- und zuklappbar sein soll, könntest Du bei Bedarf neue Queries absetzen, um die Unterpunkte zu einem Menüpunkt zu erhalten.
    3. Das ganze Menü als Result Set holen und mit Hilfe von PHP (ich nehme an, das ist die Hostsprache) den Baum aufbauen. Mit einer klugen Vorsortierung durch die DB und einem vernünftigen Algorithmus könnte das Deine Lösung sein.

    Ansonsten: Steig auf Oracle oder sowas um ;)))

    @Jakob: Deine Lösung ist absolut nicht geeignet, da auf eine gewisse Anzahl an Untermenüpunkten beschränkt.
     
    Zuletzt bearbeitet: 08.10.2005
  6. tobias.beuth

    tobias.beuth MacUser Mitglied

    Beiträge:
    142
    Zustimmungen:
    0
    MacUser seit:
    06.09.2004
    Dein Ansatz ist schon richtig und auch am flexibelsten.
    Das einzige Problem ist dabei das auslesen des Baums, was ein wenig komplizierter wird, dafür kannst du aber sehr leicht Zweige verschieben.
    Und Beim Löschen musst du dir Gedanken machen was du mit den Kindern des Knoten machst.

    Bleibt dir nichts anderes als Rekursion fürs Auslesen übrig. Ob man das in von der Datenbank oder, wie Yankee sagt, aus dem Memory macht bleibt dir überlassen.

    Ansonsten sehen die Querys ganz normal aus:
    Du hast ja immer eine ID auf die du dich beziehen kannst.
     
  7. dms

    dms Thread Starter Gast

    Bin gerade per Zufall drüber gestolpert. Ein schöner Artikel zu genau Deinem Thema: http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
     
    Zuletzt von einem Moderator bearbeitet: 19.02.2016
  8. Yankee

    Yankee MacUser Mitglied

    Beiträge:
    155
    Zustimmungen:
    0
    MacUser seit:
    27.02.2004
    Hier könnte diese Lösung wirklich elegant sein.
     
  9. Yankee

    Yankee MacUser Mitglied

    Beiträge:
    155
    Zustimmungen:
    0
    MacUser seit:
    27.02.2004

Diese Seite empfehlen