borisbaer: Individuelle Datenbankzugriffe einrichten

problematische Seite

Hallo zusammen,

ich habe eine Tabelle, in der es je Zeile eine Checkbox gibt, die drei Werte haben kann: unchecked (0), checked (1), indeterminate (2). Ich benötige diese drei Werte, sie sagen so etwas aus wie „habe ich nicht“ (0), „habe ich“ (1), „will ich nicht“ (2).

Ich möchte, dass diese Werte individuell für jeden Benutzer abgespeichert werden können. Ich dachte, ich erstelle eine Tabelle in der Datenbank mit zwei Spalten: user_id und values.

Jeder Benutzer sieht nur die values entsprechend seiner user_id und kann auch nur diese aktualisieren. Bei den values würde es sich um einen String mit Zahlen handeln, z.B. „2 0 1“, drei Ziffern für drei Zeilen in der Tabelle (angenommen die Tabelle hat jetzt mal nur drei Zeilen). Mit PHP wird dieser string dann in integers zerlegt, die dann auf die drei Zeilen verteilt werden:

Die Checkbox in Zeile 1 bekommt den Wert 2, die in Zeile 2 bekommt den Wert 0 und die in Zeile 3 den Wert 1. Wenn der Benutzer das Formular speichert wird aus den drei Ziffern wieder ein String gebaut und in der Tabelle aktualisiert.

Soweit meine Idee. Etwas Besseres fällt mir momentan nicht ein. Kann man das so machen bzw. ist das sinnvoll das so umzusetzen oder wie handhabt man so etwas für gewöhnlich?

Ein großer Nachteil des Ganzen ist wohl, dass, sobald eine neue Zeile dazu kommt, der „Zahlen-String“ nicht mehr stimmt, weil die Zeilen-Abfolge sich ändert.

Grüße
Boris

  1. problematische Seite

    Lieber borisbaer,

    Ich benötige diese drei Werte, sie sagen so etwas aus wie „habe ich nicht“ (0), „habe ich“ (1), „will ich nicht“ (2).

    Du hast also Benutzer und ihre Einstellungen. Das macht zwei Spalten, nämlich Benutzer und Einstellungswert. Aber da fällt mir doch gleich die Frage ein: Zu welcher Frage müssen sie so antworten? Und gibt es nur genau diese eine Frage, oder gibt es mehrere?

    Falls es nur eine Frage gibt, hast Du genau diese eine Fragetabelle, in der jeder Datensatz aus Benutzer-ID und dem Wert (0|1|2) besteht.

    Falls es mehr als eine Frage (lies: Einstellung) gibt, benötigst Du auch noch eine Spalte für die jeweilige Frage/Einstellung:

    |user|setting|value|
    |0001| 0001  |  0  |
    |0001| 0002  |  2  |
    |0002| 0001  |  1  |
    

    Vielleicht magst Du das Setting in einer weiteren Tabelle definieren?

    |setting|designation |
    | 0001  | dark mode  |
    | 0002  |display MOTD|
    

    So kannst Du Settings realisieren und dabei das System erweiterbar halten.

    Liebe Grüße

    Felix Riesterer

    1. problematische Seite

      Hallo Felix,

      Aber da fällt mir doch gleich die Frage ein: Zu welcher Frage müssen sie so antworten? Und gibt es nur genau diese eine Frage, oder gibt es mehrere?

      unter dem Link zur „problematischen Seite“ findest du die Tabelle. Ich denke, dann wird klar, was hier abgefragt wird. Es geht um das Dokumentieren einer Spiele-Sammlung: Diese Edition habe ich, diese nicht, an der habe ich kein Interesse. Und diese Listen können sehr lang sein.

      Falls es nur eine Frage gibt, hast Du genau diese eine Fragetabelle, in der jeder Datensatz aus Benutzer-ID und dem Wert (0|1|2) besteht.

      Ja, das wäre einfacher. 😄

      Falls es mehr als eine Frage (lies: Einstellung) gibt, benötigst Du auch noch eine Spalte für die jeweilige Frage/Einstellung:

      |user|setting|value|
      |0001| 0001  |  0  |
      |0001| 0002  |  2  |
      |0002| 0001  |  1  |
      

      Wenn ich das so machen würde, hätte ich aber sehr viele Zeilen bzw. Spalte in der Datenbank-Tabelle, nicht? Ich glaube, das wäre ziemlich unübersichtlich.

      Das war auch mein ersten Gedanke, aber ich möchte die Anzahl der Spalten bzw. Zeilen in der Datenbank so gering wie möglich halten.

      Gruß
      Boris

      1. problematische Seite

        Lieber borisbaer,

        Wenn ich das so machen würde, hätte ich aber sehr viele Zeilen bzw. Spalte in der Datenbank-Tabelle, nicht?

        das kommt auf die Anzahl von Benutzern und Settings an. Pro Benutzer und Setting eine Zeile, ja.

        Ich glaube, das wäre ziemlich unübersichtlich.

        In diesem unseren Lande herrscht Religionsfreiheit. Du darfst glauben, was immer Dich selig macht. Wenn es aber um DB-Technik geht, darfst Du darauf vertrauen, dass die Idee der Normalisierung nicht ohne Grund erfunden wurde, und Datenbankserver genau darauf spezialisiert und auf Leistung getrimmt wurden.

        Das war auch mein ersten Gedanke, aber ich möchte die Anzahl der Spalten bzw. Zeilen in der Datenbank so gering wie möglich halten.

        Dieser Wunsch entspringt nicht technischem Verständnis, sondern Unwissen.

        Liebe Grüße

        Felix Riesterer

      2. problematische Seite

        Es geht um das Dokumentieren einer Spiele-Sammlung: Diese Edition habe ich, diese nicht, an der habe ich kein Interesse.

        Verstehe ich das richtig, dass es n Spiele gibt und n Benutzer?

        Dann würde ich die DB-Tabelle Spiele und die DB-Tabelle Benutzer unverändert lassen und eine dritte DB-Tabelle einrichten.

        • id
        • spiele_id
        • benutzer_id
        • wertung set 0|1|2
        1. problematische Seite

          Verstehe ich das richtig, dass es n Spiele gibt und n Benutzer?

          Ja, genau!

          Dann würde ich die DB-Tabelle Spiele und die DB-Tabelle Benutzer unverändert lassen und eine dritte DB-Tabelle einrichten.

          • id
          • spiele_id
          • benutzer_id
          • wertung set 0|1|2

          Steht hier id für die jeweilige Checkbox?

          Dann würde die Datenbank-Tabelle also beispielsweise so aussehen?

          |user|spiele_id|id|value|
          |0001|0001     |0 |1    |
          |0001|0001     |1 |0    |
          |0002|0001     |2 |2    |
          

          Nehmen wir an, wir haben zwei Benutzer: 0001 und 0002. Außerdem haben wir zunächst einmal ein Spiel (0001). Bei diesem Spiel gibt es drei Checkboxen (0, 1, 2).
          Benutzer 0001 hat für das Spiel 0001 die Checkboxen mit der id 0 und mit der id 1 jeweils auf 1 gesetzt. Bei der dritten Checkbox hat er gar nichts gesetzt, insofern wurde da auch nichts in der Datenbank gespeichert. Benutzer 0002 hat beim Spiel 0001 nur bei der dritten Checkbox einen Wert gesetzt, und zwar 2.

          Ist das so zu begreifen? Natürlich gäbe es bei entsprechend vielen Benutzern dann entsprechend viele Einträge in der Datenbank und nicht wie bei meinem Beispiel mit dem String pro Benutzer nur eine Zeile in der Datenbank-Tabelle. Die Checkboxen wären jedoch einer konkreten id zugeordnet und man könnte einfach neue hinzufügen, ohne sich Gedanken um die alten machen zu müssen. Ich denke, das könnte für meine Zwecke funktionieren.

          P.S.: Man könnte es ja sogar so einrichten, dass nur die Werte 1 und 2 gespeichert werden und sobald der Wert auf 0 gesetzt wird, wird der Eintrag in der Datenbank wieder gelöscht. Wäre platzsparender.

          1. problematische Seite

            Lieber borisbaer,

            P.S.: Man könnte es ja sogar so einrichten, dass nur die Werte 1 und 2 gespeichert werden und sobald der Wert auf 0 gesetzt wird, wird der Eintrag in der Datenbank wieder gelöscht. Wäre platzsparender.

            das kommt darauf an, was Du genau aussagen willst.

            Wenn Du in der DB keinen Datensatz speicherst, dann kann Du keine Aussage über „habe ich nicht“ treffen. Speicherst Du dagegen eine 0, weißt Du, dass der User bereits eine Angabe gemacht hat und dass diese bedeutet, dass er diese Edition des Spiels nicht hat.

            Auf der problematischen Seite ist die Spalte mit den Checkboxen mit iB beschriftet. Was bedeutet dieses „iB“ genau? Etwa „in Besitz“? Das wird nicht intuitiv klar!

            Deine bisherige UI-Lösung signalisiert dem Benutzer eine nicht angehakte Checkbox, eine angehakte Checkbox und ein X anstelle der Checkbox:

            Screenshot mit Checkbox-Zuständen

            Diese UI-Lösung basiert auf JavaScript, das eine Klasse des <label>-Elements ändert, innerhalb dessen sich das <input> befindet. Jetzt ist mir klar, warum Du so keine vernünftigen Werte übermittelt bekommst, denn das Input-Element bekommt dabei keinerlei Wert zugewiesen. Ich sehe auch kein verstecktes <input>-Element, welches ersatzweise den beabsichtigten Wert übermitteln soll. Wie stellst Du Dir denn die Kommunikation zwischen Browser und DB vor, wenn das fragliche Input-Element keinen sinnvollen Wert liefern kann?

            Liebe Grüße

            Felix Riesterer

            1. problematische Seite

              Hallo Felix,

              witzig, dass die Idee des "hab ich nicht speichere ich nicht" jetzt mehrfach aufgekommen ist - ich habe borisbärs Beitrag erst gelesen als ich meinen fertig hatte - und so kontrovers gesehen wird.

              Aber Du hast schon recht, wenn man Wert darauf legt, ob ein User eine Eingabe gemacht hat oder nicht, dann muss man jeden Auswahlwert speichern.

              Ein UI, das bedienbar und zugänglich ist, zur Not auch ohne JavaScript funktioniert und für sehende Mausschubser die einfache Eleganz der aktuellen Lösung bietet, dürfte nicht ganz einfach zu bauen sein.

              Vermutlich: Drei Radiobuttons als Default. Mit vorhandenem JavaScript werden sie visuell versteckt und die SVG-Lösung präsentiert. Ein Tastaturuser tabbt - ohne es zu wissen - auf die Radiobuttons und kann damit auswählen. Man müsste nur noch einen Eventhandler für die Leertaste vorsehen, um damit die Radioauswahl durchlaufen zu können. D.h. die Tastaturbedienung erfolgt über die Radiobuttons. Vermutlich reicht dann ein click-Handler auf den svgs, der die Radiobuttons umselektiert, um die Mausschubser und Screentoucher zu befriedigen. Wichtig wäre für die Icon-Darstellung auch eine Legende, welches Symbol was bedeuten soll. Der Screenreader verwendet eh die Labels der Radiobuttons.

              Wäre das hinreichend zugänglich? Ich bin da nicht wirklich firm drin.

              Rolf

              --
              sumpsi - posui - obstruxi
            2. problematische Seite

              Hallo Felix,

              Wenn Du in der DB keinen Datensatz speicherst, dann kann Du keine Aussage über „habe ich nicht“ treffen. Speicherst Du dagegen eine 0, weißt Du, dass der User bereits eine Angabe gemacht hat und dass diese bedeutet, dass er diese Edition des Spiels nicht hat.

              ja, das stimmt wohl. Müsste man sich im Vorfeld überlegen, welche Vorteile das mit sich brächte.

              Auf der problematischen Seite ist die Spalte mit den Checkboxen mit iB beschriftet. Was bedeutet dieses „iB“ genau? Etwa „in Besitz“? Das wird nicht intuitiv klar!

              Ja, das soll „in Besitz“ bedeuten. Ich weiß auch, dass das nicht selbstverständlich ist und beabsichtige, dies noch anzupassen bzw. eine Legende einzufügen oder etwas Ähnliches.

              Deine bisherige UI-Lösung signalisiert dem Benutzer eine nicht angehakte Checkbox, eine angehakte Checkbox und ein X anstelle der Checkbox:

              UI ist WIP. Soll nichts Finales darstellen.
              Erst mal versuche ich, die Funktionalität auf die Beine zu stellen.

              Diese UI-Lösung basiert auf JavaScript, das eine Klasse des <label>-Elements ändert, innerhalb dessen sich das <input> befindet. Jetzt ist mir klar, warum Du so keine vernünftigen Werte übermittelt bekommst, denn das Input-Element bekommt dabei keinerlei Wert zugewiesen. Ich sehe auch kein verstecktes <input>-Element, welches ersatzweise den beabsichtigten Wert übermitteln soll. Wie stellst Du Dir denn die Kommunikation zwischen Browser und DB vor, wenn das fragliche Input-Element keinen sinnvollen Wert liefern kann?

              Dies habe ich nun geändert. Ist das erste Mal, dass ich so was mache. Mir ist aber auch aufgefallen, dass ich so nicht ausreichend Werte übermittelt bekomme. Nun ist es ein Text-Input mit dem Standard-Wert 0, der hochgezählt wird, wenn man auf den entsprechenden Button drückt.

              Viele Grüße
              Boris

              1. problematische Seite

                Lieber borisbaer,

                UI ist WIP. Soll nichts Finales darstellen.

                ist das hier eine Inspiration für Dich? tri state checkbox - habe ich hier aus dem Forum gelernt.

                Liebe Grüße

                Felix Riesterer

                1. problematische Seite

                  Hallo Felix,

                  Oha. Böse Falle, die Du da ausgelöst hast. Nicht inhaltlich zu diesem Thema, aber...

                  Du verlinkst ein altes Forenposting. Eine Antwort darauf verlinkt ins Wiki, auf einen Artikel dort, der als "Obsolet" gelöscht wurde (es war nur eine Weiterleitung).

                  Ich habe zwei Möglichkeiten. (1) Ich stelle im Wiki die Weiterleitung wieder her mit dem Hinweis, dass sie im Forum als Link-Target genutzt wird (2) Ich fixe den Link im Forenbeitrag (ist zwar archiviert, aber ich bin Admin, ich darf das).

                  Möglichkeit 2 löst die Folgefrage aus: gibt's noch mehr von diesen Links? Und nun: Wie suche ich im Forum nach Inhalten von Links? Scheinbar indexiert Christian die nicht.

                  Diese Folgefrage stellt sich eigentlich bei jedem Wiki-Artikel, den man löscht. Verlinkt jemand darauf? Der link: Operator bei Google existiert nicht mehr und war auch nie zuverlässig, und da wir keine Google Analytics betreiben, haben wir auch keine Google Search Console, in der man das abfragen könnte. Und die öffentlichen Backlink-Checker sind da auch nicht geeignet...

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                2. problematische Seite

                  Hallo Felix,

                  ist das hier eine Inspiration für Dich? tri state checkbox - habe ich hier aus dem Forum gelernt.

                  das scheint mir eine gute Idee zu sein! Vielen Dank für den Link!

                  Gruß
                  Boris

  2. problematische Seite

    Hallo Boris,

    ich habe eine Tabelle, in der es je Zeile eine Checkbox gibt, die drei Werte haben kann

    Das ist wohl ein Denkfehler. Eine HTML–Checkbox kann nur zwei Werte haben.

    Eine bestimmte Wertemenge sind in der Datenbank ein SET, in deinem Fall mit den Werten '0'.'1' und '2'. Womöglich noch mit dem Standard NULL, das bedeutet: Keine Information, wenn der Benutzer sich noch nicht geäußert hat.

    Bei den values würde es sich um einen String mit Zahlen handeln, z.B. „2 0 1“

    Das verstehe ich nicht, ich denke der User hat nur eine von den Möglichkeiten.

    Vielleich kann mein Rat besser ausfallen, wenn du beschreibst, was da gespeichert werden soll. Ein User meldet

    • „habe ich nicht“ (0),
    • „habe ich“ (1),
    • „will ich nicht“ (2).

    Das bezieht sich auf was?

    Gruß, Linuchs

  3. problematische Seite

    Lieber borisbaer,

    Du kannst drei Zustände für einen Wert als Radio-Buttons realisieren. Für jeden User bildest Du ein Set an Radio-Buttons ab:

    <fieldset>
      <legend>Einstellungen</legend>
      <form method="POST">
        <dl>
          <dt>Dark-Mode</dt>
          <dd>
            <label for="user_0001_setting_0001_value_0">
                <input
                  name="user_0001_setting_0001"
                  type="radio"
                  value="0"
                  id="user_0001_setting_0001_value_0"
                >
                Habe ich nicht
            </label>
            <label for="user_0001_setting_0001_value_1">
                <input
                  name="user_0001_setting_0001"
                  type="radio"
                  value="1"
                  id="user_0001_setting_0001_value_1"
                >
                Habe ich
            </label>
            <label for="user_0001_setting_0001_value_2">
                <input
                  name="user_0001_setting_0001"
                  type="radio"
                  value="2"
                  id="user_0001_setting_0001_value_2"
                >
                Will ich nicht
            </label>
          </dd>
          <dt>Display MOTD</dt>
          <dd>
            <label for="user_0001_setting_0002_value_0">
                <input
                  name="user_0001_setting_0002"
                  type="radio"
                  value="0"
                  id="user_0001_setting_0002_value_0"
                >
                Habe ich nicht
            </label>
            <label for="user_0001_setting_0002_value_1">
                <input
                  name="user_0001_setting_0002"
                  type="radio"
                  value="1"
                  id="user_0001_setting_0002_value_1"
                >
                Habe ich
            </label>
            <label for="user_0001_setting_0002_value_2">
                <input
                  name="user_0001_setting_0002"
                  type="radio"
                  value="2"
                  id="user_0001_setting_0002_value_2"
                >
                Will ich nicht
            </label>
          </dd>
        </dl>
      </form>
    </fieldset>
    

    Anstatt drei Radio-Buttons mit identischen name-Attributewerten kannst Du auch sein <select> verwenden. Ob das besser zu bedienen ist, kann ich nicht sagen. Auch weiß ich nicht, wie Du mit dem Fall "unbekannt" umgehen willst. In der DB wird dann als Wert sicherlich null stehen. Das wäre dann auch zu setzen, wenn beim Speichern kein (passender) Wert ankommt. Willst Du das verhindern, wirst Du einem Radio-Button ein Attribut selected mitgeben müssen, was im Zweifel aber nicht verlässlich ist.

    Liebe Grüße

    Felix Riesterer

  4. 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
    1. problematische Seite

      Hallo Rolf,

      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.

      Ja, ist eben nur zum Testen.

      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?

      Ja, jeder Benutzer wird die Liste sehen. Registrierte Benutzer sollen die Checkbox-Werte verändern können. Das Ganze hat tatsächlich so angefangen, dass ich viele Jahre Videospiele gesammelt habe und irgendwann keine Übersicht mehr hatte, welche Edition ich schon hatte und welche nicht. So ist die Idee zu der Website entstanden.

      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
      

      Klingt gut, das muss ich mal ausprobieren. Ich kenne nur ein paar SQL-Befehle und LEFT JOIN und ON gehören nicht dazu. Titel, Edition, Plattform usw. kommen übrigens nicht aus der Datenbank, sondern aus einer JSON-Datei. Ich habe nur den Wert der Checkboxen darin.

      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.

      Mir ist nicht daran gelegen, ein explizites „Habe ich nicht“ festzuhalten, daher würde ich diesen Wert nicht in der DB 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.

      So hatte ich es vor.

      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.

      Gut zu wissen!

      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.

      Ja, das Auslesen muss ich noch einmal überdenken.

      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.

      Kein Problem, dann löse ich das anders … vielleicht mit den Radio-Buttons. Muss ich mal noch schauen.

      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.

      Danke für die Hinweise, ich versuche, das noch zu optimieren. Die Bedeutung der Icons könnte man ganz einfach durch eine Legende lösen. Ist noch nichts final und einiges habe ich auch auf dem Schirm, jedoch noch nicht die Zeit gehabt, es auch umzusetzen.

      1. problematische Seite

        Hallo borisbaer,

        Left Join

        Rolf

        --
        sumpsi - posui - obstruxi