Formal sei s ( U , Q ) = { V | V ∈ U und V ⊆ Q }, wobei U , Q und V alle Mengen darstellen und U , genauer gesagt, eine Menge von Mengen darstellt. Zum Beispiel könnte U ein Satz der (Sätze von) Zutaten sein, die für verschiedene Rezepte in einem Kochbuch erforderlich sind, wobei Q den Satz von Zutaten darstellt, die ich habe. V steht für ein Rezept, das ich mit diesen Zutaten machen könnte. Die Abfrage s ( U , Q.) entspricht der Frage "Was kann ich alles mit diesen Zutaten machen?"
Was ich suche ist eine Darstellung der Daten , dass Indizes U derart , dass es eine effiziente Abfrage unterstützt s ( U , Q ) , wobei Q und alle Mitglieder von U verglichen werden im allgemeinen klein , um die Vereinigung aller Mitglieder von U . Außerdem möchte ich, dass es U effizient aktualisieren kann (z. B. ein Rezept hinzufügen oder entfernen).
Ich kann nicht anders, als zu denken, dass dieses Problem gut verstanden werden muss, aber ich konnte keinen Namen oder eine Referenz dafür finden. Kennt jemand eine Strategie, um dies effizient zu lösen, oder einen Ort, an dem ich mehr darüber lesen kann?
Wenn ich über eine Lösung nachdachte, dachte ich, ich sollte einen Entscheidungsbaum für die Menge U erstellen . An jedem Knoten im Baum wird die Frage "Enthält Ihre Zutatenliste x ?" würde mit x ausgewählt werden, um die Anzahl der Mitglieder von U zu maximieren, die durch die Antwort eliminiert werden. Wenn U aktualisiert wird, muss dieser Entscheidungsbaum neu ausgeglichen werden, um die Anzahl der Fragen zu minimieren, die erforderlich sind, um das richtige Ergebnis zu finden. Ein anderer Gedanke ist, U mit so etwas wie einem n- dimensionalen booleschen 'Octree' darzustellen (wobei n die Anzahl der eindeutigen Bestandteile ist).
Ich glaube, dass "Welche Rezepte können mit diesen Zutaten gemacht werden?" kann beantwortet werden, indem man das kartesische Produkt der (für die) Zutaten erforderlichen Sätze im Kochbuch mit dem Potenzsatz der Zutaten nimmt und die resultierenden geordneten Paare nach Paaren filtert, in denen beide Elemente gleich sind, aber dies ist kein effiziente Lösung, und ich frage, wie diese Art von Betrieb optimiert werden kann; Wie würde man dies in SQL so zusammenstellen, dass es effizient wäre, und was macht SQL, damit dies effizient ist?
Obwohl ich die Abbildung eines Kochbuchs mit Rezepten und einer Reihe von Zutaten verwende, gehe ich davon aus, dass die Anzahl der „Rezepte“ und die Anzahl der „Zutaten“ sehr groß sein wird (jeweils bis zu Hunderttausende), obwohl die Anzahl der Zutaten In einem bestimmten Rezept ist die Anzahl der Zutaten in einem bestimmten Zutaten-Set relativ gering (wahrscheinlich etwa 10-50 für ein typisches "Rezept" und etwa 100 für ein typisches "Zutaten-Set"). Darüber hinaus ist die häufigste Operation die Abfrage s ( U , Q ), daher sollte sie am optimalsten sein. Dies bedeutet auch, dass ein Brute-Force-Algorithmus, bei dem jedes Rezept überprüft oder jede Zutat bearbeitet werden muss, für sich genommen unerwünscht langsam ist. Mit cleverem Caching
Antworten:
Für die Zahlen, die Sie gegeben haben, erzwingen Sie es einfach brutal.
Hier ist ein JavaScript-Programm, das es für 10 Zutaten in der DB, 10 Rezepte in der DB, jedes Rezept benötigt 2 Zutaten und ich habe 5 Zutaten zur Verfügung:
Es läuft in 0 Millisekunden. Ich habe diese kleinen Zahlen ausgewählt, damit Sie sie ein paar Mal selbst ausführen und sich davon überzeugen können, dass sie das tun, was Sie wollen, und relativ frei von Fehlern sind.
Ändern Sie es jetzt so, dass wir 1'000'000 Zutaten in der DB, 1'000'000 Rezepte in der DB, 50 Zutaten pro Rezept und 100 Zutaten zur Verfügung haben. Dh Werte, die alle gleich oder größer sind als der größte Anwendungsfall, den Sie angegeben haben.
Es läuft in 125 Millisekunden unter nodejs, und dies ist mit der dümmsten Implementierung ohne jeglichen Optimierungsaufwand.
quelle