Suche im Kategoriebaum

Hallo,

ich muss eine Suche realisieren, die sich über mehrere Felder/Tabellen
erstreckt. Auf den ersten Blick eigentlich kein großes Problem. Meine
Suche sieht momentan etwa so aus:
Sei der Suchbegriff "a b"

SELECT * FROM datensaetze WHERE
CONCAT_WS(name, beschreibung, hersteller, kategorie) LIKE '%a%' AND
CONCAT_WS(name, beschreibung, hersteller, kategorie) LIKE '%b%' ...

Ich verwende folgende Tabellenstruktur und hole mir Hersteller- und
Kategorienamen über LEFT JOINs:

datensaetze:
id, name, beschreibung, hersteller, kategorie, ...

kategorien:
id, name, parent

Die Kategorietabelle sieht in etwa so aus:
id name parent
1 | Sport | 0
2 | Spiel | 0
3 | Basketball | 1

Wenn ich nun nach "Sport" suche, werden natürlich keine Datensätze
gefunden, die in der Untergruppe Basketball sind. Kann mir jemand einen
Hinweis geben, wie ich das Problem lösen kann?

Manuel
skanto [ Mi, 13 Juli 2005 13:54 ] [ ID #878091 ]

Re: Suche im Kategoriebaum

Manuel Wohlers wrote:

> ich muss eine Suche realisieren, die sich über mehrere Felder/Tabellen
> erstreckt. [..] Suchbegriff "a b"
>
> SELECT * FROM datensaetze WHERE

16.14. Warum soll ich nicht SELECT * schreiben?
http://www.php-faq.de/q/q-sql-select.html

> CONCAT_WS(name, beschreibung, hersteller, kategorie) LIKE '%a%' AND
> CONCAT_WS(name, beschreibung, hersteller, kategorie) LIKE '%b%' ...

Sieht aus, als würde es funktionieren. Aber Deine Datenbank kann keinen
Index verwenden, bei einer grossen Datenmenge würde das spürbar langsam
werden.

> Ich verwende folgende Tabellenstruktur und hole mir Hersteller- und
> Kategorienamen über LEFT JOINs:
>
> datensaetze:
> id, name, beschreibung, hersteller, kategorie, ...
>
> kategorien:
> id, name, parent

Fein. Nur die Tabellennamen solltest Du nochmal überdenken. Mein
Vorschlag wäre 'produkt' und 'kategorie', falls es sich um einen Shop
handelt.

Das Feld datensaetze.kategorie enthält eine ID, nehme ich an?

> Die Kategorietabelle sieht in etwa so aus:
> id name parent
> 1 | Sport | 0
> 2 | Spiel | 0
> 3 | Basketball | 1
>
> Wenn ich nun nach "Sport" suche, werden natürlich keine Datensätze
> gefunden, die in der Untergruppe Basketball sind. Kann mir jemand einen
> Hinweis geben, wie ich das Problem lösen kann?

Du müsstest weitere LEFT OUTER JOINs anfügen, ganausoviele wie Dein
Kategorienbaum Ebenen ebenen hat.

...
LEFT OUTER JOIN kategorien AS k1
ON k1.id = datensaetze.kategorie

LEFT OUTER JOIN kategorien AS k2
ON k2.id = k1.parent

LEFT OUTER JOIN kategorien AS k3
ON k3.id = k2.parent

usw.

k1.name, k2.name, usw kommen dann in Dein CONCAT_WS().

Das sollte funktionieren. Für eine sauberere, schnellere Lösung solltest
Du Dir überlegen, einen Keyword-Tabelle anzulegen, oder Dir die
MySQL-proprietäre Volltextsuche mit MATCH AGAINST [1] ansehen.
Um Bäume in SQL abzubilden gibt es auch z.T. geschicktere Möglichkeiten
als über eine 'parent'-Spalte [2].

cheers,

-Uli.

[1] http://dev.mysql.com/doc/mysql/en/fulltext-search.html
[2] http://google.com/search?q=b%C3%A4ume+sql
Uli Honal [ Sa, 16 Juli 2005 14:18 ] [ ID #882324 ]

Re: Suche im Kategoriebaum

Uli Honal <uli [at] netzgeist.de> wrote:

> 16.14. Warum soll ich nicht SELECT * schreiben?
> http://www.php-faq.de/q/q-sql-select.html

Tausendmal durchgekaut und hier auch nur für eine bessere Lesbarkeit
verwendet.

> Nur die Tabellennamen solltest Du nochmal überdenken.

Nö, denn das waren ja auch nur Beispielnamen - was drinsteht spielt hier
doch keine Rolle.

> Du müsstest weitere LEFT OUTER JOINs anfügen, ganausoviele wie Dein
> Kategorienbaum Ebenen ebenen hat.

Ja, habe ich so auch getestet, aber leider ist das ziemlich langsam...
Ich habe mir jetzt folgendermaßen geholfen:

Ein zusätzliches Feld in in der Kategoriendatenbank, in dem sämtliche
Namen der übergeordneten Kategorien eingetragen sind. Beim umbenennen
oder "verschieben" der Kategorie oder einer übergeordneten Kategorie
wird gleichzeitig auch der Inhalt des Feldes erneuert.
Klappt gut so :-)

> [1] http://dev.mysql.com/doc/mysql/en/fulltext-search.html
Die Volltextsuche sucht nur nach ganzen Wörtern, oder?

Vielen Dank für die Ratschläge!

Grüße,
Manuel
skanto [ So, 17 Juli 2005 09:58 ] [ ID #883091 ]
PHP » de.comp.lang.php.datenbanken » Suche im Kategoriebaum

Vorheriges Thema: MySQL: Zeit fürAbfrage abschätzen
Nächstes Thema: Komme nicht weiter: Sonderzeichen aus Formular in MYSQL-Tabelle eintr.