Regina: Tabellenstruktur "einfaches" Logikproblem

Hi brauche mal wieder eure Hilfe bezüglich Logik hinter Tabellenstruktur/aufbau. Möchte eine Linkliste in einer Datenbank speichern. Habe also eine Tabelle Link, mit ID, URL, NAME, BESCHREIBUNG.

Diesen Links sollen Kategorien zugeordnet werden. Also zweite Tabelle Kategorie mit ID und Name Soweit kein Problem.

Allerdings möchte ich die Möglichkeit haben beliebig viele Unterkategorien zuzuordnen (also das Prinzip einer Verzeichnisstruktur: kann Link in Oberverzeichnis ablegen oder ein Verzeichnis drunter und so weiter beliebig viele Verzeichnisebenen). Vermute mal, dass es eine max Tiefe von 5-6 Ebenen sein wird.

Frage ist wie mache ich das vom Tabellenaufbau am besten? Alle Kategorien - egal in welcher Ebene sie sich befinden in eine Liste und ZWischentabelle die auf sich selbst verweist, oder Zwischentabellen für die unterscheidlichen Ebenen (dann müsste ich allerdings die Möglichkeit einführen eine neue Tabelle zu kreieren wenn doch eine weitere Ebene dazukommen sollte), oder die Kategoriebezeichnungen für die verschiedenen Ebenen in einzelne Tabellen... oder in der Tabelle Kategorie ein Feld einfügen welcher Ebene die Kategorie zugeordnet ist, oder eine eigene Tabelle für Ebenentiefe also ID und Tiefe

  • nur wie verbinde ich die dann sinnvoll? Also z.B.

Link1 | kat1ebene: Reise | kat2ebene: Deutschland | kat3ebene:Berlin | kat4ebene: Ausflug | kat5ebene: Boot

Für Hinweise und Ideen wäre ich dankbar

Grüße Regina

  1. Wenn du mehrere Tabellen für die gleichen Daten anlegst ist das i.d.R. schon falsch, genau wie Spalten durchnummerieren. Für hierarchische Daten hast du aber unterschiedliche Möglichkeiten die in einer Tabelle abzulegen - mit vielen Vor- und Nachteilen. Als Parent, als Nested Set oder als Pfad, mal so als Beispiele. Kommt aber auch auf deine Datenbank an, für Parent ist eine DB gut die RECURSIVE unterstützt, wie PostgreSQL.

  2. Hallo Regina,

    die Tabelle mit den Links:

    |link_id|link_url|kat_id|

    Die Tabelle mit den Kategorien:

    |kat_id|kategoriename|elternelement_id|

    Wenn elternelement_id 0 ist, hat die Kategorie kein Elternelement, sonst ist elternelement_id die kat_id des Elternelements. Die kat_id kannst du dann in die Tabelle mit den Links packen – Stichwort Fremdschlüssel.

    Durch die Abstraktion über kat_id müsstest du nur an einer Stelle – nämlich in der betreffenden Spalte in der Tabelle mit den Kategorien – etwas ändern, beispielsweise falls Chemnitz irgendwann wieder Karl-Marx-Stadt heißen sollte 😉

    Ein threaded-Forum ist ein ähnliches „Problem“: Threadbasiertes Forum mit PHP und MySQL

    Gruß
    Julius

    --
    „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
    Andrew S. Tanenbaum (Quelle)
    1. Vorsicht. Wenn Du den Kategorienbaum komplett im Speicher hältst, dann kannst Du eine Abstrakte Klasse "Knoten" mit den Subklassen "Kategorie" und "Link" erzeugen, und an den Kategorien führst Du eine Liste von Kindknoten (was sich im SQL als Fremdschlüssel kat_id bzw. elternelement_id darstellt).

      Diese Struktur 1:1 auf SQL abzubilden führt zu Performance-Tiefschlägen, weil Du im RAM sehr schnell von einem Knoten zum nächsten springen kannst, in der SQL DB aber nicht. Folgende Operationen werden durch dieses Datenmodell sehr langsam, bzw. erfordern einen SQL Server, der rekursive Queries beherrscht (ein Feature von SQL-99, das aber selbst MySQL 5.7 noch nicht kennt; es soll mit MySQL 8 kommen)

      • Ermitteln des Pfades von einem Knoten zur Wurzel
      • Aufspannen eines Kategoriebaumes
      • Finden eines Eintrags innerhalb eines bestimmten Teilbaumes

      Deswegen hatte Chorn ja auch die Alternativen Nested Set und Path angesprochen - alle mit ihren eigenen Vor- und Nachteilen.

      Rolf