Verwandeln Sie das Datenbankergebnis in ein Array

7

Ich habe gerade den update / add / delete-Part für die "Closure table" -Methode zum Organisieren hierarchischer Suchdaten erstellt, die in dieser Slideshare auf Seite 70 gezeigt werden: Ссылка

Meine Datenbank sieht so aus:

Tabellenkategorien:

%Vor%

Tabelle CategoryTree:

%Vor%

Allerdings habe ich ein kleines Problem damit, den gesamten Baum als mehrdimensionales Array aus einer einzigen Abfrage zurückzubekommen.

Hier ist, was ich gerne zurückbekommen würde:

%Vor%

Aktualisierung: Habe diesen Link gefunden, aber ich habe es immer noch schwer, ihn in ein Array zu konvertieren: Ссылка

Update2: Ich konnte nun jeder Kategorie Kategorien hinzufügen, wenn das helfen kann.

    
Industrial 08.05.2010, 15:36
quelle

5 Antworten

9

Okay, ich habe PHP-Klassen geschrieben, die die Tabellen-, Zeilen- und Rowset-Klassen von Zend Framework DB erweitern. Ich entwickle das sowieso, weil ich in ein paar Wochen bei PHP Tek-X über hierarchische Datenmodelle rede.

Ich möchte meinen gesamten Code nicht in Stack Overflow posten, da sie implizit unter Creative Commons lizenziert werden, wenn ich das tue. update: Ich habe meinen Code an den Zend Framework Extras-Inkubator und meinen Code übergeben Präsentation ist Modelle für hierarchische Daten mit SQL und PHP bei slideshare.

Ich werde die Lösung im Pseudocode beschreiben. Ich verwende zoologische Taxonomie als Testdaten, heruntergeladen von ITIS.gov . Die Tabelle ist longnames :

%Vor%

Ich habe eine Abschlusstabelle für die Pfade in der Hierarchie der Taxonomie erstellt:

%Vor%

Wenn Sie den Primärschlüssel eines Knotens angeben, können Sie alle seine Nachkommen auf diese Weise erhalten:

%Vor%

Die Verknüpfung zu closure AS p schließt die Eltern-ID jedes Knotens ein.

Die Abfrage verwendet ziemlich gut Indizes:

%Vor%

Und da ich 490.032 Zeilen in longnames und 4.299.883 Zeilen in closure habe, läuft es ziemlich gut:

%Vor%

Nun verarbeite ich das Ergebnis der obigen SQL-Abfrage und sortiere die Zeilen in Teilmengen entsprechend der Hierarchie (Pseudocode):

%Vor%

Ich definiere auch Klassen für Zeilen und Zeilengruppen. Ein Rowset ist im Grunde ein Array von Zeilen. Eine Zeile enthält ein assoziatives Array mit Zeilendaten und enthält außerdem ein Rowset für die untergeordneten Elemente. Das untergeordnete Rowset für einen Blattknoten ist leer.

Zeilen und Rowsets definieren auch Methoden namens toArrayDeep() , die ihren Dateninhalt rekursiv als einfaches Array ausgeben.

Dann kann ich das ganze System wie folgt verwenden:

%Vor%

Die Ausgabe ist wie folgt:

%Vor%

Kommentieren Sie Ihren Kommentar zur Berechnung der Tiefe - oder der tatsächlichen Länge jedes Pfades.

Angenommen, Sie haben gerade einen neuen Knoten in Ihre Tabelle eingefügt, der die tatsächlichen Knoten enthält ( longnames im obigen Beispiel), die ID des neuen Knotens wird von LAST_INSERT_ID() in MySQL zurückgegeben oder Sie können sie erhalten irgendwie.

%Vor%     
Bill Karwin 09.05.2010, 20:52
quelle
9

Vorgeschlagene Lösung

Dieses folgende Beispiel gibt ein wenig mehr, als Sie verlangen, aber es ist eine wirklich nette Art, es zu tun und zeigt immer noch, woher die Informationen in jeder Phase kommen.

Es verwendet die folgende Tabellenstruktur:

%Vor%

Hier ist es:

%Vor%

Testfall

In meiner Datenbank habe ich die folgenden Zeilen:

%Vor%

Und so gibt das Skript die folgenden (langen) Informationen aus:

%Vor%

Beispiel Verwendung

Ich würde vorschlagen, eine Art rekursive Funktion zu erstellen, wenn Sie Menüs aus den Daten erstellen möchten:

%Vor%

was folgendes ausgeben würde:

%Vor%

Genießen

    
icio 08.05.2010 17:59
quelle
2

Ich mochte die Antwort von icio, aber ich bevorzuge Arrays von Arrays statt Arrays von Objekten. Hier ist sein Skript so modifiziert, dass es funktioniert, ohne Objekte zu erstellen:

%Vor%

Ich denke, es ist fair zu bemerken, dass sowohl meine Antwort als auch icios Ihre Frage nicht direkt ansprechen. Beide verwenden eine Eltern-ID-Verknüpfung in der Haupttabelle und verwenden die Verschlusstabelle nicht. Die rekursive Abfrage der Datenbank ist jedoch definitiv der Weg, aber anstatt die Eltern-ID rekursiv zu übergeben, müssen Sie die Eltern-ID UND die Ebene der Tiefe übergeben (die bei jeder Rekursion um eins zunehmen sollte), so dass die Abfragen Auf jeder Ebene kann parent + depth verwendet werden, um die direkten Elterninformationen aus der Schließtabelle zu erhalten, anstatt sie in der Haupttabelle zu haben.

HTH, -FT

    
ftrotter 02.06.2010 15:54
quelle
1

Wenn Sie die Ausgabe als ungeordnete Liste wünschen, können Sie die outputCategories-Methode wie folgt ändern (basierend auf ftrotters-Arrays in Arrays):

%Vor%     
Klaaz 26.05.2011 14:24
quelle
0

Tut mir leid, aber ich glaube nicht, dass Sie kein mehrdimensionales Array aus Ihrer (oder irgendeiner) Datenbankabfrage bekommen können.

    
Alix Axel 08.05.2010 16:07
quelle

Tags und Links