Wählen Sie Produkte aus, bei denen die Kategorie zu einer Kategorie in der Hierarchie gehört

8

Ich habe eine Produkttabelle, die eine FK für eine Kategorie enthält. Die Tabelle Kategorien wurde so erstellt, dass jede Kategorie eine übergeordnete Kategorie haben kann, zum Beispiel:

%Vor%

Ich muss eine Select-Abfrage machen, dass, wenn die ausgewählte Kategorie Prozessoren ist, es Produkte zurückgibt, die in Intel, Pentium, Core 2 Duo, Amd usw. enthalten sind.

Ich habe überlegt, eine Art "Cache" zu erstellen, der alle Kategorien in der Hierarchie für jede Kategorie in der Datenbank speichert und das "IN" in die where-Klausel aufnimmt. Ist das die beste Lösung?

    
Bruno 13.10.2008, 12:10
quelle

9 Antworten

6

Die beste Lösung hierfür ist die Datenbankentwicklung. Ihre Kategorietabelle muss ein geschachtelter Satz sein. Der Artikel Hierarchische Daten in MySQL verwalten ist nicht so MySQL-spezifisch (trotz des Titels), und gibt einen guten Überblick über die verschiedenen Methoden zum Speichern einer Hierarchie in einer Datenbanktabelle.

Zusammenfassung:

Verschachtelte Mengen

  • Auswahlmöglichkeiten sind für jede Tiefe einfach
  • Einfügungen und Löschungen sind schwer

Standard parent_id-basierte Hierarchie

  • Selektionen basieren auf inneren Joins (also werden Sie schnell behaart)
  • Einfügen und Löschen sind einfach

Wenn Ihre Hierarchietabelle also ein geschachtelter Satz wäre, würde Ihre Abfrage also in etwa so aussehen:

%Vor%

Die 2 und 11 sind jeweils links und rechts von Processors record.

    
MDCore 13.10.2008, 13:35
quelle
3

Sieht wie ein Job für einen gemeinsamen Tabellenausdruck aus ... etwas in der Art von:

%Vor%

Das sollte die Kategorie auswählen, deren Name "Prozessoren" und deren Nachfolger ist, sollte in der Lage sein, das in einer IN-Klausel zu verwenden, um die Produkte zurückzuziehen.

    
Steven Robbins 13.10.2008 13:35
quelle
0

Ich habe in der Vergangenheit ähnliche Dinge gemacht, zuerst nach den Kategorie-IDs gesucht und dann nach den Produkten "IN" dieser Kategorien gesucht. Es ist schwer, die Kategorien zu bekommen, und Sie haben einige Optionen:

  • Wenn die Verschachtelungsebene von Kategorien bekannt ist oder Sie eine Obergrenze finden können: Erstellen Sie ein schrecklich aussehendes SELECT mit vielen JOINs. Dies ist schnell, aber hässlich und Sie müssen ein Limit für die Ebenen der Hierarchie festlegen.
  • Wenn Sie eine relativ kleine Anzahl von Gesamtkategorien haben, fragen Sie sie alle ab (nur IDs, Eltern), sammeln Sie die IDs von denen, die Ihnen wichtig sind, und machen Sie ein SELECT .... IN für die Produkte. Das war die passende Option für mich.
  • Abfrage der Hierarchie mithilfe einer Reihe von SELECTs. Einfach, aber relativ langsam.
  • Ich glaube, dass neuere Versionen von SQLServer rekursive Abfragen unterstützen, aber nicht selbst verwendet haben.

Gespeicherte Prozeduren können helfen, wenn Sie diese App-Seite nicht machen möchten.

    
Draemon 13.10.2008 12:20
quelle
0

Was Sie finden wollen, ist die transitive Schließung der Kategorie "Eltern" -Beziehung. Ich nehme an, dass es keine Beschränkung für die Kategorie-Hierarchie-Tiefe gibt, so dass Sie keine einzige SQL-Abfrage formulieren können, die alle Kategorien findet. Was ich tun würde (in Pseudocode) ist das:

%Vor%

Such einfach weiter nach Kindern, bis keine mehr gefunden werden. Dies verhält sich in Bezug auf die Geschwindigkeit gut, es sei denn, Sie haben eine degenerierte Hierarchie (z. B. 1000 Kategorien, die jeweils ein Kind eines anderen sind) oder eine große Anzahl von Gesamtkategorien. Im zweiten Fall könnten Sie immer mit temporären Tabellen arbeiten, um den Datentransfer zwischen Ihrer App und der Datenbank klein zu halten.

    
Simon 13.10.2008 12:24
quelle
0

Vielleicht etwas wie:

%Vor%

[EDIT] Wenn die Kategorietiefe größer als eins ist, würde dies Ihre innerste Abfrage bilden. Ich vermute, dass Sie eine gespeicherte Prozedur entwerfen könnten, die in der Tabelle einen Drilldown ausführen würde, bis die von der inneren Abfrage zurückgegebenen IDs keine untergeordneten Elemente hatten - wahrscheinlich ein Attribut, das eine Kategorie als Endknoten in der Hierarchie kennzeichnet Führen Sie die äußere Abfrage für diese IDs aus.

    
tvanfosson 13.10.2008 12:28
quelle
0
%Vor%

Der letzte Teil des Beispiels funktioniert nicht wirklich, wenn Sie es gerade so ausführen. Entfernen Sie einfach die Auswahl aus den Produkten und ersetzen Sie sie mit einem einfachen SELECT * FROM r

    
Jonas Lincoln 13.10.2008 12:56
quelle
0

Dies sollte alle "Kinder" -Kategorien ab einer bestimmten Kategorie wiederholen.

%Vor%     
Should_be_working 13.10.2008 13:40
quelle
0

Ich verwende gerne eine Stack-Temp-Tabelle für hierarchische Daten. Hier ist ein grobes Beispiel -

%Vor%

Es gibt hier eine gute Erklärung link text

    
cheeves 15.10.2008 21:56
quelle
0

Meine Antwort auf eine andere Frage von vor ein paar Tagen gilt hier ... Rekursion in SQL

Es gibt einige Methoden in dem Buch, die ich verlinkt habe, die Ihre Situation gut abdecken sollten.

    
Tom H 15.10.2008 22:08
quelle

Tags und Links