Candid Dauth: SQLite: Highscores-Liste performant implementieren

Heißa, alle,

ich würde gerne eine Highscores-Liste mit SQLite implementieren. Gehen wir davon aus, dass für jeden Spieler drei verschiedene Punktzahlen in eigenen Spalten gespeichert werden, die er erreicht hat. Diese Punktzahlen ändern sich regelmäßig für jeden Spieler, eher selten kommen neue Spieler hinzu. Und ab und zu wird ein Spieler entfernt.
Abgerufen von den Highscores wird regelmäßig die ganze Liste, und zwar kann der Abrufende bestimmen, nach welcher Punktzahlspalte er sortieren will, immer absteigend. Außerdem wird häufig die Punktzahl des ersten Platzes (einer bestimmten Spalte) abgerufen. Ebenfalls häufig soll abgerufen werden, auf welchem Platz (in einer bestimmten Spalte) sich ein bestimmter Spieler gerade befindet.

Hier mal eine Beispiel-Tabelle:
+===========+=========+=========+=========+
| username  | scores1 | scores2 | scores3 |
+===========+=========+=========+=========+
| bla       |     100 |     200 |      50 |
+-----------+---------+---------+---------+
| gautera   |      50 |     150 |     100 |
+-----------+---------+---------+---------+
| wrtlprmft |     150 |     100 |      75 |
+===========+=========+=========+=========+

Hier einmal ein paar Beispiel-Abrufe, wie sie häufig vorkommen:

  • Wer ist mit scores1 auf Platz 1?
  • Die ganze Highscores-Liste, sortiert nach scores3.
  • Auf welchem Platz ist gautera in scores2?

Die ganze Tabelle enthält derzeit zwar erst 250 Spieler, aber es sollen doch noch deutlich mehr werden.

Mich würde jetzt interessieren, wie ich das ganze am performantesten machen kann. Ich kenne mich nicht allzu gut aus mit SQL, einige Lösungsansätze sind mir bereits eingefallen:

  • Livezugriff auf die Tabelle, jedesmal mit ORDER BY. Ich weiß nun nicht, wie SQLite da intern cachet, deswegen hört sich das für mich sehr unperformant an, wenn jedes Mal neu sortiert werden soll. Außerdem frage ich mich, wie ich hier den Platz zu einem bestimmten Spielernamen herausfinden kann.
  • Je einen View für die Sortierung nach jeder Spalte. Wie verhält sich das hier? Muss ich nach einer Änderung der Punkte den View neu erzeugen, oder macht SQLite das automatisch für mich? Und wieder frage ich mich, wie ich hier den Platz zu einem bestimmten Spielernamen herausfinden kann.
  • Zusätzliche Spalten, die die Platzierung des Spielers in bestimmten Punktspalten enthalten. Und dann einen Trigger, der bei Aktualisierung irgendeines Punktwertes die ganzen Platzierungswerte abändert. Das ganze stelle ich mir sehr umständlich vor, aber hier wüsste ich wenigstens, wie ich zu einem bestimmten Spieler die Platzierung herausfinde.

Welche der drei Möglichkeiten ist nun die performanteste, und wie kann ich bei Möglichkeit 1 und 2 den Platz zu einem Spieler herausfinden? Auch über einen Link auf eine gute SQLite-Dokumentation wäre ich dankbar, die auf sqlite.org gibt ja nicht allzu viel her.

Vielen Dank schonmal für eure Hilfe.

Gautera!
Grüße aus Biberach Riss,
Candid Dauth

--
Ein Fußball-Fan? Noch auf der Suche eine Schlafmöglichkeit im Großraum Stuttgart für die WM 2006? Wie wäre es mit Herrenberg, einer gemütlichen Kleinstadt am Rande des Schönbuchs – von der Lage her ideal, auch für andere Vorhaben im Urlaub. Ferienwohnungen-Herrenberg.com.
http://cdauth.de/
  1. yo,

    die entscheidene aussage ist diese:

    "Diese Punktzahlen ändern sich regelmäßig für jeden Spieler"

    das wird eine andere lösung als ständig neu zu sortieren schwierig machen. ich habe zwar mit SQLLite noch keine erfahrungen gemacht, aber im grunde handelt es sich ja "nur" um eine tabelle. und solange dort nicht tausende bis millionen von datensätze stehen, sehe ich keine probleme bezüglich der performance. wichtig ist das richtige setzen von indizes. aber wie immer gilt beim tuning probieren über studieren.

    • Wer ist mit scores1 auf Platz 1?

    hier kommen unterabfragen zum einsatz, falls das dbms das unterstützt, ansonsten zwei abfragen.

    • Die ganze Highscores-Liste, sortiert nach scores3.

    das ist ein einfacher SELECT mit ORDER BY und den zusatz DESC

    • Auf welchem Platz ist gautera in scores2?

    auch hier wieder eine unterabfrage, ansonsten zwei abfragen.

    • Je einen View für die Sortierung nach jeder Spalte. Wie verhält sich das hier? Muss ich nach einer Änderung der Punkte den View neu erzeugen, oder macht SQLite das automatisch für mich?

    die view (materilized views wird das dbms wohl nicht kennen) muss nicht wieder neu ausgeführt werden, wobei ich den einsatz von views für unnötig halte. views werden in aller regel der zugriffssteuerung und der datenunabhängigkeit eingesetzt. aber dein fall ist doch recht einfach und ich würde die tabelle nicht über views abfragen.

    Und wieder frage ich mich, wie ich hier den Platz zu einem bestimmten Spielernamen herausfinden kann.

    wie gesagt, mit einer unterabfrage, welche zuerst den score des entsprechen spielers ausließt und dann zählt, wieviele datensätze einen höheren score haben + 1. das sollte sein platz sein.

    Und dann einen Trigger, der bei Aktualisierung irgendeines Punktwertes die ganzen Platzierungswerte abändert.

    grundsätzllich sind tabellen eine unsortierte menge. es macht also keinen sinn. man kann sicherlich eine zusätzliche spalte einführungen, die die aktuelle platzierung enthält. ich würde mir aber diesen schritt sparen, wenn die tabelle regelmäßig aktualisiert wird, was du ja geschrieben hast.

    Ilja

    1. Heißa, Ilja,

      wie gesagt, mit einer unterabfrage, welche zuerst den score des entsprechen spielers ausließt und dann zählt, wieviele datensätze einen höheren score haben + 1. das sollte sein platz sein.

      Vielen Dank für diesen Ansatz, das ist eine sehr interessante Idee, auf die ich nicht selbst gekommen bin. Danke auch für deine Anregungen bezüglich der Performance, ich werde es dann jetzt wohl so lassen, dass ich die Live-Abfragen verwende.

      Gautera!
      Grüße aus Biberach Riss,
      Candid Dauth

      --
      Ein Fußball-Fan? Noch auf der Suche eine Schlafmöglichkeit im Großraum Stuttgart für die WM 2006? Wie wäre es mit Herrenberg, einer gemütlichen Kleinstadt am Rande des Schönbuchs – von der Lage her ideal, auch für andere Vorhaben im Urlaub. Ferienwohnungen-Herrenberg.com.
      http://cdauth.de/