Ankündigung

Einklappen
Keine Ankündigung bisher.

Normalisierung der Datenbank

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Normalisierung der Datenbank

    Hallo,

    natürlich hab ich ein Problem, weswegen ich hier poste:

    ich hab derzeit folgende Datenbankstruktur (arbeite an einem Mini-Browsergame für die Einführung in PHP, will damit nichts großes anstellen, einfach nur aus spaß):

    Username | Holz | Stein | Nahrung | Wasser | Pech | Eisen

    das problem ist folgendes: Es wird teilweise ein wert falsch geupdatet bzw. es wird von der Datenbank der wert 0 zurückgegeben, und das hängt NICHT an meinen Scripten.

    ich sags mal so, von 1000 updates, macht 1 update ein fehler - und somit "verschwinden" ressourcen (holz, stein nahrung etc.)

    Dann hab ich mir die Normalisierung von Wikipedia durchgelesen und hab gemerkt: Das was ich gemacht habe, bringt nichts. Die Datenbank ist schlecht strukturiert

    also bin ich jetzt zu folgenden Entschluss gekommen:
    ID | Ressource | Anzahl

    wäre wohl angebrachter. Allerdings haben wir ca. 30-40 verschiedene Ressis, würde also heißen, für jeden User würden 30-40 Einträge gemacht werden - und das würde speicher fressen ohne ende (oder?).


    jetzt die eigentliche frage: Wie muss ich meine Datenbank richtig strukturieren, das sie wenig speicher frisst, dennoch keine falschupdates macht? Ich hab schonmal im IRC Channel angefragt, aber ich möchte mir 100% sicher sein, das ich diesmal alles richtig mache - denn das wird stunden dauern, bis ich alles geändert habe (ich programmiere ja noch nicht so professionell)...

  • #2
    Also wenn deine Anzahl an Rohstoffsorten fest ist dann würde ich die Tabellenstruktur so wie du sie bis jetzt hast beibehalten! Die Dinge in eine eigene Tabelle auszulagern lohnt sich eigentlich nur wenn sich die Anzahl häufig ändert und/oder verschiedene User verschiedene Rohstoffe haben.

    Und diese Fehlupdates die müssten vom Script her kommen. Also einfach so macht die Datenbank nicht nen falschen Update.

    Kommentar


    • #3
      NEIN! Die Scripte funktionieren, das ist ja das was mich stark verunsichert hat.

      Wenn man etwas "abbaut" (Ressourcen wie Stein), dann wird alles normal gutgeschrieben. Nur irgendwann passiert es dann. Ich hatte mal eine zeitlang "Platz" in der Datenbank geschaffen, indem ich User gelöscht habe. Dann trat das Problem lange Zeit nicht mehr auf - jetzt ist es wieder da. Ich habe es praktisch nur unter den Tisch gekehrt...

      PS: Ein normales MySQL update schaut bei mir so aus :

      mysql_query("UPDATE ressourcen SET Holz = Holz - '10' WHERE Username = '$username'")or DIE ("MySQL-Fehler: " . mysql_error());

      Kommentar


      • #4
        Naja ich kann mir ansich nicht erklären das ein Fehler der DB her dafür verantwortlich ist. Vlt. haste ja so komplexe Zustände dass unter bestimmten Umständen der Wert der abgezogen wird zu hoch oder so ist und dadurch alles abgezogen wird.

        Kommentar


        • #5
          und das hängt NICHT an meinen Scripten.
          Das behauptet jeder, letztendlich stellt sich das Gegenteil heraus.

          NEIN! Die Scripte funktionieren, das ist ja das was mich stark verunsichert hat.
          Aber wie du eben festgestellt hast nicht immer.
          Ein Script aufgebaut auf "funktioniert doch" funktioniert eben unter bestimmten Konstellationen eben nicht mehr.

          mysql_query("UPDATE ressourcen SET Holz = Holz - '10' WHERE Username = '$username'")or DIE ("MySQL-Fehler: " . mysql_error());
          String von Zahl abziehen, da wundert mich nichts mehr.

          Würde mich nicht nicht wundern wenn der Datentype von Holz varchar wäre.

          Kommentar


          • #6
            Zitat von DiBo33
            und das hängt NICHT an meinen Scripten.
            Das behauptet jeder, letztendlich stellt sich das Gegenteil heraus.
            nagut. Bedeutet also, es hängt nicht an meiner Datenbankstruktur, liege ich da richtig?

            Zitat von DiBo33
            mysql_query("UPDATE ressourcen SET Holz = Holz - '10' WHERE Username = '$username'")or DIE ("MySQL-Fehler: " . mysql_error());
            String von Zahl abziehen, da wundert mich nichts mehr.

            Würde mich nicht nicht wundern wenn der Datentype von Holz varchar wäre.
            schön das du den satz "da wundert mich nichts mehr" mit einbaust, würdest du sagen WARUM das schlecht ist, oder was man besser machenh könnte, dann würde es mir leichter fallen mit deiner Aussage irgendetwas anzufangen.

            und nein, es ist INT und nicht Varchar.

            Kommentar


            • #7
              nagut. Bedeutet also, es hängt nicht an meiner Datenbankstruktur, liege ich da richtig?
              ohne diese genauer zu kennen, aber ja, es ist richtiger.

              schön das du den satz "da wundert mich nichts mehr" mit einbaust, würdest du sagen WARUM das schlecht ist, oder was man besser machenh könnte, dann würde es mir leichter fallen mit deiner Aussage irgendetwas anzufangen.
              Mathematische Berechnungen erledigt man mit Zahlen nicht mit Strings.

              und nein, es ist INT und nicht Varchar.
              Um so besser, ich bin auch anderes gewöhnt.

              Fakt ist, ein DBMS kommst nicht auf die Idee, na heute will ich mal die Leute ärgern und setze alles auf 0.

              Nur irgendwann passiert es dann.
              Und nur hier kannst du ansetzen, indem du beobachtest und die Fehlerursache versuchst nachzustellen, alles andere kann nur auf Spekulation hinauslaufen.

              Ich würde mir dann auch die Mühe machen jeden Vorgang zu loggen um die Ursache überhaupt nachvollziehen zu können.

              Kommentar


              • #8
                Mathematische Berechnungen erledigt man mit Zahlen nicht mit Strings.
                Der String ist doch aber eine Zahl. Ich spar mir halt vorher die Variable und rechne direkt über MySQL. Ist das etwa so ausschlaggebend?


                Um so besser, ich bin auch anderes gewöhnt.
                damit deute ich mal, das ich das richtig gemacht hab und es daran nicht liegen kann.

                Fakt ist, ein DBMS kommst nicht auf die Idee, na heute will ich mal die Leute ärgern und setze alles auf 0.
                Es wird nicht alles auf 0 gesetzt, sondern nur ziemlich selten - jedoch zuoft. Wenn die Datenbank "nicht mehr will", dann gibt sie sehr wohl den Wert 0 zurück, sofern ich da richtig informiert bin. Ich lasse mich auch gerne berichtigen.

                Nur irgendwann passiert es dann.
                Und nur hier kannst du ansetzen, indem du beobachtest und die Fehlerursache versuchst nachzustellen, alles andere kann nur auf Spekulation hinauslaufen.
                das Problem ist, der User ist zu derzeit nichtmal online, und somit kann auch nicht sein Username bzw. seine UserID geupdatet werden. Früher hatte ich dreifach soviel Spalten, da kam es öfters vor, mittlerweile ist es seltener geworden, jedoch passiert es halt weiterhin.


                Wie schaut es eigentlich damit aus, ist das im Bereich des "möglichen"?

                also bin ich jetzt zu folgenden Entschluss gekommen:
                ID | Ressource | Anzahl

                wäre wohl angebrachter. Allerdings haben wir ca. 30-40 verschiedene Ressis, würde also heißen, für jeden User würden 30-40 Einträge gemacht werden - und das würde speicher fressen ohne ende (oder?).
                ich bin auch gerne bereit mal ein Cronjob hier reinzustellen, denn falls doch ein fehler in meinen Scripten vorliegt, so werde ich ihn wohl nicht finden, da ich ihn ja nicht kenne.

                Kommentar


                • #9
                  mysql_error
                  Man sollte Spaltennamen stets in `` schreiben. Etwa so:
                  PHP-Code:
                  <?php
                    $sql 
                  "SELECT
                                `feldname`, `nocheinfeldname`, `undnochfeldname`
                            FROM
                                `tabellenname`
                            WHERE
                                `feldname` LIKE '%suchwort%'
                              AND
                                `nocheinfeldname` = 'wert'
                            ORDER BY
                                `undnochfeldname` ASC
                            LIMIT
                                0 , 30"
                  ;
                    
                  $result mysql_query($sql) or exit('<h2>Fehler</h2>sql-querry: '$sql.'
                  error: '
                  .mysql_error());
                    
                  // ...
                  ?>
                  hinzu solltest du auch das Thema sql-injection nicht vernachlässigen!
                  http://forum.developers-guide.net/showthread.php?t=159

                  Kommentar


                  • #10
                    mit string ist wohl dies gemeint:
                    mysql_query("UPDATE ressourcen SET Holz = Holz - '10' WHERE Username = '$username'")or DIE ("MySQL-Fehler: " . mysql_error());
                    lass einfach die umschließenden ' ' für den Substrahent weg.
                    Diese Art ist zwar praktisch, aber könnte ein Problem geben, wenn die Query bspw. durch Seitenreload mehrmals aufgerufen wird. Vielleicht liegts ja daran??

                    Man sollte Spaltennamen stets in `` schreiben
                    Darf ich fragen warum? Wegen Spaltennamen die reservierten Woörtern gleichen?

                    Kommentar


                    • #11
                      Zitat von nikosch77
                      mit string ist wohl dies gemeint:
                      mysql_query("UPDATE ressourcen SET Holz = Holz - '10' WHERE Username = '$username'")or DIE ("MySQL-Fehler: " . mysql_error());
                      lass einfach die umschließenden ' ' für den Substrahent weg.
                      Diese Art ist zwar praktisch, aber könnte ein Problem geben, wenn die Query bspw. durch Seitenreload mehrmals aufgerufen wird. Vielleicht liegts ja daran??
                      werde ich mal bei allen "updates" ausbessern. Wäre zu schön um wahr zu sein


                      hier noch ein Auszug über den Aufbau meiner Datenbank:


                      --
                      -- Tabellenstruktur für Tabelle `Rustungen`
                      --

                      CREATE TABLE `Rustungen` (
                      `Username` varchar(15) collate latin1_general_ci NOT NULL,
                      `kettenhemdohnekopfteil` int(11) NOT NULL,
                      `hemdmitkopfteil` int(11) NOT NULL,
                      `rustungmetal` int(11) NOT NULL,
                      `rustungbronze` int(11) NOT NULL,
                      `rustungsilber` int(11) NOT NULL,
                      `rustunggold` int(11) NOT NULL
                      ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

                      Kommentar


                      • #12
                        Zitat von nikosch77
                        Man sollte Spaltennamen stets in `` schreiben
                        Darf ich fragen warum? Wegen Spaltennamen die reservierten Woörtern gleichen?
                        Die Frage kannst du eigentlich selbst beantworten: Weil es nur konsequent ist!

                        Schließlich ist
                        PHP-Code:
                        <?php
                        $var1 
                        "12";
                        $foo[bar] = "$var1";
                        ?>
                        ja auch nicht falsch, denn es funktioniert, aber eben unsauber. Gleiches gilt genaugenommen für SQL bei ` und '

                        Übrigens hilft ` nicht nur bei reservierten Wörtern, sondern auch bei Sonderzeichen (bzw. Leerzeichen) im Bezeichner-Namen. Wobei man die eigentlich nicht verwenden sollte (Grund: zuwenige Coder benutzen ` ).

                        Zum Thema: Dibo33's Postings ist nichts hinzuzufügen, bis auf diesen Link:
                        http://www.lugbz.org/documents/smart...l#dontclaimbug

                        Du unterstellst PHP oder MySQL einen Fehler und behauptest damit, als erster von Millionen von Usern diesen Bug gefunden zu haben. Sehr sehr unwahrscheinlich
                        Ich geb aber zu, dass aus den gelieferten SQL-Statements erstmal kein Fehler zu entnehmen ist. Aber dein Skript ist wahrscheinlich groß genug, du hast bisher wohl nur an der falschen Stelle gesucht.

                        Der Code hier von dir ist aber in Ordnung:
                        Code:
                        Holz = Holz - 10
                        // oder meinetwegen wenn Holz auch wirklich INT ist
                        Holz = Holz - "10"
                        läßt keine Dirty Reads (o.ä. bekannte Datenbank-Fehler) zu. Das Problem ("manchmal, aber ganz selten") klingt trotzdem etwas nach "SELECT Wert" und "UPDATE Wert = selektierten Wert + Operation" aus (genau zwischen SELECT und UPDATE kann es nun dazu kommen, dass etwas die Werte aber bereits geändert hat).
                        Übrigens: Wie kommst du darauf, dass es ein Fehler ist, wenn Attribute den Wert 0 annehmen? Schließlich kann es zwangsläufig dazu kommen, wenn du immer etwas abziehst und nie oder selten nur etwas addierst.

                        Kommentar


                        • #13
                          Konsequent. Hmm, bisher bin ich davon ausgegeangen, daß ` nur eine Quotation für spezielle Fälle ist. Hab das nie so gelernt. Sind andere Datenbanken da weniger freigiebig?

                          Kommentar


                          • #14
                            Zitat von Zergling
                            Du unterstellst PHP oder MySQL einen Fehler und behauptest damit, als erster von Millionen von Usern diesen Bug gefunden zu haben. Sehr sehr unwahrscheinlich
                            das einzigste was ich unterstelle ist, das ICH falsch strukturiert habe - das stimmt aber scheinbar nicht. Deshalb bin ich auch nicht von einem Fehler meiner Scripte ausgegangen.

                            Zitat von Zergling
                            Übrigens: Wie kommst du darauf, dass es ein Fehler ist, wenn Attribute den Wert 0 annehmen? Schließlich kann es zwangsläufig dazu kommen, wenn du immer etwas abziehst und nie oder selten nur etwas addierst.
                            da ist was dran. Ich werde heute nochmal alle Scripte durchgehen und nach Fehlern suchen und auch die ' durch ` ersetzen. Weiterhin bin ich für Tipps dankbar.

                            Kommentar


                            • #15
                              Ehrlich gesagt bin ich ne MySQL-Nutte und hab nur im Datenbank-Labor an der FH mal mit Oracle gearbeitet. Aber da war so ein Freak der schon alle Aufgaben gelöst hatte, bevor ich überhaupt mit Nachdenken anfangen konnte. Aber ich glaube da wurde ` (aus Schlampigkeit?) auch nicht verwendet. Ob man es dort hätte dürfen weiß ich nicht.

                              Aber zumindest auf MySQL bezogen ist es einfach nur "richtiger"!
                              Ich werde in letzter Zeit aber immer mehr zu einem Freund der Effizienz. Wenn man keine Spaltennamen verwendet, die bereits reserviert sind oder die Sonderzeichen enthalten: Wen interessiert es dann, ob man ` verwendet oder nicht? Die Datenbank-Engine zumindest nicht

                              Kommentar

                              Lädt...
                              X