Ich möchte eine sortierte Liste in einer Datenbank speichern. Ich möchte die folgenden Vorgänge effizient ausführen.
- Einfügen (x) - Fügen Sie den Datensatz x in die Tabelle ein
- Löschen (x) - Löscht den Datensatz x aus der Tabelle
- Vorher (x, n) - Die 'n' Datensätze vor dem Datensatz x in der sortierten Liste zurückgeben.
- Nach (x, n) - Die 'n' Datensätze zurückgeben, die dem Datensatz x in der sortierten Liste folgen.
- First (n) - Gibt die ersten n Datensätze aus der sortierten Liste zurück.
- Last (n) - Gibt die letzten n Datensätze aus der sortierten Liste zurück.
- Compare (x, y) - Wenn zwei Datensätze x und y aus der Tabelle gegeben sind, finde, ob x> y ist.
Die einfache Methode, die ich mir vorstellen könnte, besteht darin, eine Art "Rang" -Attribut in der Tabelle zu speichern und durch Sortieren nach diesem Attribut abzufragen. Bei dieser Methode wird das Einfügen / Ändern eines Datensatzes mit Rang jedoch zu einer kostspieligen Operation. Gibt es eine bessere Methode?
Insbesondere möchte ich die Tabelle mit Amazon SimpleDB implementieren. Eine allgemeine Antwort für eine relationale Datenbank sollte jedoch ebenfalls hilfreich sein.
Update beim Ladeprofil:
Da ich dies für eine Webanwendung plane, hängt es von der Anzahl der Benutzer ab, die die App verwenden.
Wenn es 100.000 aktive Benutzer gibt (Superoptimismus: P), dann wäre meine sehr ungefähre Schätzung pro Tag
500.000 Auswahlen, 100.000 Einfügen und Löschen, 500.000 Aktualisierungen
Ich würde erwarten, dass der Tisch insgesamt auf 500.000 wächst.
Ich bin auf der Suche nach Updates, Insert und Compare-Operationen zu optimieren. Der Rang der Gegenstände wird sich ständig ändern und ich muss die Tabelle auf dem neuesten Stand halten.
quelle
Antworten:
Wenn der Rang nicht völlig willkürlich ist, sondern von einer anderen Eigenschaft abgeleitet werden kann (z. B. Name, Punktzahl des Spielers usw.), schauen Sie sich Joels Antwort genau an .
Wenn es sich um eine willkürliche Eigenschaft Ihrer Daten handelt, sollte diese als Spalte in Ihrer Datensatztabelle gespeichert werden. Angenommen, Amazon SimpleDB ähnelt dem typischen RDBMS, können Sie diese Spalte indizieren und alle oben genannten Abfragen schnell mit der entsprechenden Indizierungsstrategie beantworten. Dies ist normal für ein RDBMS.
Da Sie eine hohe Einfüge- und Aktualisierungsaktivität, aber auch eine relativ hohe Leseaktivität erwarten, empfehle ich Folgendes:
INCLUDE
Rang " Aufzeichnen und -en" oder nur, wenn Sie nach Rang gruppiert haben), würde die Abfrage 7 erfüllen.FILLFACTOR
in SQL Server festlegen). Dies ist besonders wichtig, wenn Sie sich nach Rang gruppieren.Wenn Sie mehr als 100.000 Lesevorgänge für eine Tabelle mit einer Größe von mehr als 100.000 erwarten, empfehle ich nicht, den Ansatz der verknüpften Liste zu verwenden. Es wird nicht gut auf diese Größen skaliert.
quelle
FILLFACTOR
Sie feststellen, dass es im Grunde genommen dazu gedacht ist, den zusätzlichen Platz für Datensätze in einem Index zu schaffen, genau wie die Ranglücken, die ich beschrieben habe, Platz für Rangänderungen und Einfügungen schaffen.Ich verwende im Allgemeinen die von Ihnen beschriebene "Rang" -Methode. Anstatt mit dem Aktualisieren von Zeilen herumzuspielen, wenn Elemente neu angeordnet werden mussten, konnte ich häufig alle Datensätze in der Liste löschen und neue Elemente in der richtigen Reihenfolge einfügen. Diese Methode ist eindeutig für den Abruf optimiert.
Ein alternativer Ansatz wäre, die Datensätze als verknüpfte Liste zu modellieren, indem eine reflexive "Vorgänger" -Fremdschlüsselspalte in der Tabelle verwendet wird:
Sie können problemlos eine Liste abrufen und Elemente mit geringem Aufwand hinzufügen und entfernen. Es ist jedoch schwierig, die Datensätze in der richtigen Reihenfolge zu veröffentlichen. Vielleicht gibt es eine clevere Möglichkeit, dies in einer einzigen Abfrage zu tun, wahrscheinlich mit vielen Alias-Table-Joins.
Ich benutze diesen letzteren Ansatz oft, wenn ich eine baumartige Beziehung modelliere (Kategorien, Ordner, Mengen und Teilmengen). Im Allgemeinen hatte ich eine Art rekursive Funktion, um den gesamten Baum in meiner Anwendung zu rekonstruieren.
quelle
Ich würde denken, dass die Sache zu tun ist, die Eigenschaft oder Eigenschaften zu speichern, die verwendet werden, um den Rang zu berechnen, und dann einen Index über sie zu erstellen. Anstatt zu versuchen, die Datenbank zu zwingen, die Daten physisch in einer Rangfolge zu speichern oder eine manuell verwaltete verknüpfte Liste zu verwenden, sollten Sie das Datenbankmodul das tun lassen, wofür es entwickelt wurde.
quelle
Dies sind die Einschränkungen eines Nicht-RDBMS wie simpleDB. Die Funktionen, die Sie benötigen, können nicht auf der DB-Seite in simpleDB implementiert werden, sondern müssen von der Programmierseite / -anwendung aus implementiert werden.
Für ein RDBMS wie dieses
SQL server
sind die Funktionen, die Sie benötigen, für den Clustered-Index rudimentär.Vorher (x, n) - Die 'n' Datensätze vor dem Datensatz x in der sortierten Liste zurückgeben. > Wählen Sie Top-n-Ergebnisse aus, bei denen x kleiner als der Wert ist, und sortieren Sie nach Klausel.
Nach (x, n) - Die 'n' Datensätze zurückgeben, die dem Datensatz x in der sortierten Liste folgen. > Wählen Sie Top-n-Ergebnisse aus, bei denen x größer als value ist, und sortieren Sie nach Klausel.
First (n) - Gibt die ersten n Datensätze aus der sortierten Liste zurück. > Wählen Sie die besten n Ergebnisse aus.
Last (n) - Gibt die letzten n Datensätze aus der sortierten Liste zurück. > Top n Ergebnisse nach Reihenfolge auswählen von absteigend.
quelle
Folgendes habe ich verwendet, um meine Postgres-Tabelle nach jeder Einfügung neu zu ordnen:
Für meinen Anwendungsfall ist die Leistung kein Problem, aber die Gewissheit, dass sie niemals kaputt geht oder sich merkwürdig verhält, ist wichtig.
quelle