Kind Elemente in einer Hierarchie/Baumstruktur
Andreas N.
- datenbank
Hallo,
es geht um die Abbildung einer Hierarchie/Baumstruktur in einer mysql Datenbank.
Tabelle object:
-------------
| id |
| name |
| parent_id |
-------------
Nun möchte ich zu einer id auch alle Kind Einträge ermitteln, um mir alle zugehörigen objekt Namen zu einer id ausgeben zu lassen.
Zum Beispiel:
SELECT
object.name
FROM
object
WHERE
object.id IN (Liste-mit-allen-kind-objekten-zu-einer-id)
Um nun alle Kind-Objekte zu einer Objekt-id (im SQL: "Liste-mit-allen-kind-objekten-zu-einer-id") zu erhalten müsste ich diese ids ermitteln. Das ist ja weiter kein Problem. Jedoch enthält die object Tabelle ca. 280.000 Einträge, was das SQL-Statement -für den Fall, dass ein Objekt aus einer der obersten Ebene ausgewählt wird- sehr lang und wahrscheinlich auch nicht gerade performant macht.
Meine Idee ist es nun eine weitere Tabelle anzulegen, in der zu einem object (object_id) alle Kindelemente (object_child_id) aufgelistet werden:
child2object
--------------------
| object_id |
| object_child_id |
--------------------
object_id und object_child_id wären dann der Primär-Schlüssel.
Das Statement würde dann so aussehen:
SELECT
object.name
FROM
object
INNER JOIN
child2object
ON
(object.id = child2object.object_child_id)
WHERE child2object.object_id = 'irgendeine-id'
Bei 280.000 Einträgen in der objekt Tabelle wird die child2object Tabelle natürlich auch nicht gerade klein.
Ist das eine gute Lösung oder gibt es bessere Ansätze?
Vielen Dank für Hilfe & viele Grüße
Andreas
Sup!
Tabelle object:
| id |
| name |
parent_id
Warum schreibst Du eigentlich nicht
SELECT object.name
FROM object
WHERE parent_id = id;
?!?
Irgendwelche Daten zu duplizieren halte ich auf jeden Fall für eine ziemlich dumme Idee...
Gruesse,
Bio
Hallo Bio,
Tabelle object:
| id |
| name |
parent_id Warum schreibst Du eigentlich nicht
SELECT object.name
FROM object
WHERE parent_id = id;
ich verstehe nicht so ganz was Du meinst. Denn mit dem SQL Statement erhalte ich nicht die gewünschte Ausgabe (genau genommen gar keine Datensätze ;-) oder ich habe etwas übersehen?
Vielleicht habe ich mich in meinem ersten Posting etwas ungenau ausgedrückt. Ich möchte alle Kind Elemente erhalten, also auch die Kindes Kinder und wiederum deren Kinder usw.
In der Tabelle object ist die 'id' der Primärschlüssel, 'name' ein beliebiger Name und 'parent_id' zeigt wieder auf die 'id'.
Beispiel Daten für die object Tabelle:
| id | name | parent_id |
-------------------------
| 1 | a | 0 |
| 2 | b | 0 |
| 3 | aa | 1 |
| 4 | aaa | 3 |
| 5 | aaaa | 4 |
| 6 | bb | 2 |
| 7 | bbb | 6 |
Für die id=1 wären es die Datensätze:
| id | name | parent_id |
-------------------------
| 3 | aa | 1 |
| 4 | aaa | 3 |
| 5 | aaaa | 4 |
Also die ids 3, 4 und 5. So würde das Statement um die Namen aller Kinder (und Kindes Kinder) zu ermitteln wie folgt aussehen:
SELECT
object.name
FROM
object
WHERE
object.id IN (3,4,5)
Dies liefert mir die gewünschten Namen "aa","aaa" und "aaaa".
Diese Liste mit allen Kindern kann ich natürlich serverseitig ermitteln, doch bei relativ vielen Datensätzen (ca. 280.000) wie in meinem Fall würde im Statement der 'IN (x,y,z)'-Teil sehr groß werden.
Die Idee ist dies mit Hilfe einer zweiten Tabelle und dem entsprechendem JOIN zu verhindern.
Viele Grüße
Andreas
Hallo,
object.id IN (Liste-mit-allen-kind-objekten-zu-einer-id)
Um nun alle Kind-Objekte zu einer Objekt-id (im SQL: "Liste-mit-allen-kind-objekten-zu-einer-id") zu erhalten müsste ich diese ids ermitteln.
Ich habe eine weitere Lösung gefunden, die mir sinnvoller erscheint und die Lösung des Problems erleichtert. Anstatt des Zeigermodells (über die 'parent_id') ist die Verwendung des Mengenmodells eine bessere Alternative. Streng genommen gibt es hier wegen der zusätzlichen left und right Spalten auch wieder Redundanz, doch die Lösung gefällt mir besser als eine weiteren Tabelle anzulegen.
Eine gute Einführung hierzu gibt es unter http://kris.koehntopp.de/artikel/sql-self-references/.
Grüße
Andreas
Sup!
Wohl dem, der eine Codasyl-Datenbank irgendwo ausgraben kann... da war dieser Mechanismus Standard.
Gruesse,
Bio