Rolf B: Individuelle Datenbankzugriffe einrichten

Beitrag lesen

problematische Seite

Hallo borisbaer,

du hast auf deiner Demo-Seite nur 3 Spiele (bzw. 3 Editionen eines Spiels) gelistet. Du schreibst aber auch, dass das Ganze sehr lang werden könne.

Wie hast Du Dir das denn gedacht? Du hast eine Spiele-DB mit 4711 Spielen und zeigst diese Liste jedem Spieler an? Und er (oder sie) wählt dann in 4711 Zeilen aus, was vorhanden ist, was nicht und was man nicht haben will?

In diesem Fall wird es vermutlich eine Menge Zeilen geben, für die "Habe ich nicht" gilt, und nur wenige, bei denen "hab ich" oder "willichnich" angekreuzt ist.

Um das effizient zu speichern, brauchst Du

  • eine Tabelle mit den Usern
  • eine Tabelle mit den Spielen
  • eine Beziehungstabelle User-Spiel, wo der Checkbox-Status gespeichert wird.

Die SQL Query dafür würde dann sinngemäß so aussehen:

SELECT spiel.titel, spiel.edition, spiel.platform, spiel.region, spiel.jahr,
       us.status
FROM   spiel LEFT JOIN user_spiel us 
             ON us.spiel_id = spiel.id AND us.user_id = $user_id

Einen der 3 Status (habich, habichnich, willichnich) speicherst Du nicht. Der, den Du nicht speicherst, ist sinnvollerweise der Wert, der als häufigster zu erwarten ist. Nicht pro User, sondern über alle User betrachtet. Ich denke, das ist "habe ich nicht" und das ist ja auch die Ausgangssituation, wenn ein neuer User kommt.

Die Query liefert für diesen Status den Wert NULL (wegen des Left Join). Die beiden anderen Status kannst Du als 1 und 2 speichern.

Beim Zurückspeichern in die DB musst Du natürlich aufpassen. Ab besten ermittelst Du vor dem Zurückspeichern nochmal den aktuellen Stand, gleichst das mit den angekreuzten Werten ab und weißt dann, ob Du die Beziehungszeile für diesen User einfügen, ändern oder löschen musst.

Der Vorteil dieser Vorgehensweise ist, dass Du keine unnötigen Zeilen in der DB speicherst. Der Nachteil ist eine aufwändigere Programmierung beim Abspeichern, zugegeben.

Man kann die Sache auch als Stringwurst realisieren. Aber dann nicht als "2 0 1". Wenn überhaupt, musst Du die Zahlen mit der Spiel-ID verbinden.

Wenn das deine Spiele wären

ID   Titel          Edition        Plattform  Region  Jahr
1001 Demon's Souls  Standard       PS3        DEU     2010
1017 Demon's Souls  Black Phantom  PS3        DEU     2010
1372 Demon's Souls  Download...    PS3        DEU     2013

sähe der String so aus: "1001=2;1372=1". Die 0 nicht speichern, analog zu vorhin. Beim Laden: Erstmal das Besitz-Array an Hand der Spieleliste mit Nullen initialisieren. Dann den User-String aufsplitten und für die gefundenen Einträge den Wert setzen.

Der Vorteil ist die einfachere Handhabung beim Laden und Speichern. Der Nachteil ist, dass Du nicht eben mal in der DB selektieren kannst, wer die Black Phantom Edition hat. Oder wer die Standard-Edition partout nicht haben will. Das kannst Du nur mit der Beziehungstabelle elegant lösen. Wobei... die Abfrage auf den Wert, der nicht gespeichert wird, ist etwas mühsamer, denn da musst Du gucken welcher User für ein bestimmtes Spiel keinen Eintrag hat, das ist ein anderes SQL als für die beiden anderen Werte.

Beim UI bist Du mit einer Checkbox definitiv falsch bedient. Die kann nur "checked" oder "unchecked" speichern, d.h. du hast keine Chance, dass der Browser dem Server den ausgewählten Zustand meldet. Das geht nur mit einem select, mit zwei Checkboxen, mit radio buttons oder einem versteckten input-Element, in dem Du den Wert abspeicherst. Die visuelle Checkbox wäre dann ein reiner optischer Gimmick. An der Stelle wird die Anwendung unzugänglich - ohne JavaScript ginge gar nichts mehr und ein User ohne Maus oder ohne Sehvermögen rennt vermutlich in ein undurchdringliches Gestrüpp.

Das Problem bei Radiobuttons ist, dass sie die Pfeiltasten umwidmen und die Leertaste ignorieren. Das könntest Du mittels JavaScript noch lösen. Auf jeden Fall brauchst Du eine visuelle Hervorhebung der aktuellen Zelle, um die Bedienbarkeit der Seite zu gewährleisten. Im Moment drücke ich Tab und sehe nicht, wo der Eingabefokus ist.

Ob die Sache mit einem select Element, das man visuell versteckt, besser lösbar ist, weiß ich auch nicht recht. Aber so wie es ist, sollte es nicht bleiben. Es ist weder zugänglich noch bedienbar, es ist diskriminierenderweise nur für sehende Mausschubser geeignet, die obendrein erraten müssen, was deine Icons zu bedeuten haben. Als Screentoucher kann man zur Not klarkommen, benötigt aber einen Stylus, um mit dem dicken Finger nicht danebenzutippen. Das wird durch den Umstand, dass Du bei schmalem Viewport den Font verkleinerst und die "Checkboxen" gleich mit, nicht wirklich verbessert.

Rolf

--
sumpsi - posui - obstruxi