Beiträge von LeijaT

    mysql_num_rows() gibt immer die Anzahl der Zeilen wieder, die zu der Query passen. Also musst du einfach eine Query nehmen die irgentwas von allen Zeilen wiedergibt zum Beispiel: SELECT * FROM Tabelle.
    Mehr ist das nicht.

    Und bevor sich wieder irgendein Neuling deinen Nonsens abguckt, stellen wir hier direkt mal klar, dass man bei sowas kein * benutzt, da * (für Info an die Anfänger) für ALLE FELDER steht und dadurch unnötig große Belastung für das Script entsteht. Da sowieso nur die Zeilen gezählt werden, reicht es ein x-beliebiges Feld zu nehmen.

    Der Fehler liegt darin, dass du mysql_num_rows() aufrufst, nachdem du das Ergebnis via mysql_free_result(); schon wieder freigegeben hattest. Das darf natürlich nicht sein :p

    von einer Person wo man denken sollte ' hm Seriös '.


    Dachte ich vorher nicht von deinem Profil, denke ich auch jetzt nicht. Deine Verwarnung macht offenbar keinen Unterschied.

    Zudem wollte ich mit meinem Post, eigentlich auch nur darauf hinweisen, das die Person gesperrt ist, und das ein Moderator den Thread hätte schließen können.


    mit:

    Das war aber ein kurzer Aufenthalt

    ? Ja, das macht Sinn, so würde ich die Moderation vermutlich auch am Ehesten darauf hinweisen wollen.

    Klar, im nachhinein wäre die ' Melde ' Funktion besser gewesen


    Richtig.

    aber es erfüllte anscheinend beides seinen Sinn &' Zweck


    Falsch.

    also nach ' Spam ' sieht es meiner Meinung nach dann nicht aus da dieser Beitrag ja nicht zur Beitragszählung dazugehört.


    Dann solltest du dir mal ein paar Begriffserklärungen zum Wort "Spam" anschauen, denn der Beitragscounter hat damit absolut 0 zu tun.

    // cmd für veh (playerid, params[]) {
    if (!strcmp(params, "infernus")) CreateVehicle(...);
    else if (!strcmp(params, "Bullet")) CreateVehicle(...);
    return 1;
    }[/pwn]

    userId ist das Feld deines auto incremented primary keys. Dient einfach nur dazu, der mySQL nicht unnötig Arbeit aufzuhalsen. Da du für die Anzahl der User nicht die alle Felder abfragen musst (*) sondern eines reicht (da bietet die Normalisierung nunmal PRIMARY KEYs als Erstes an), fragst du einfach irgendein Feld ab, da der Wert darin sowieso völlig irrelevant ist.

    mysql_query("SELECT `userId` FROM `users`");
    mysql_store_result();
    printf("Es sind %d Spieler registriert", mysql_num_rows());
    mysql_free_result();

    Psychologen werden dir sagen, es ist ein psychopathisches Merkmal für Ordnungszwang,
    Therapeuten werden dir sagen, du leidest unter Stress,
    Freud würde dir sagen, du willst Sex mit deiner Mutter oder wurdest von deinem Vater geschlagen
    und jeder Mensch mit Verstand wird dir sagen: Es ist ne Spielerei die man immer und überall im Leben treiben kann.

    hehe das mit Galileo habe ich mir auch schonmal gedacht,aber ganz im ernst.
    Denkt ihr ich mache mir darüber keine Sorgen? Sowas ist doch langsam nicht normal,erstrecht mit dem Beitrag den ich um 01:28 gepostet habe und 0 + 1 + 2 +8 = 11 Sind o.0

    Schau dir mal "Number 23" mit Jim Carrey an - viel Spaß bei deiner Paranoia.

    Viel unheimlicher finde ich, dass du über 888 Kilometer für nen Zahnarzt fährst, der muss es ja echt drauf haben.


    Sorry wenn ich dir die Illusion nehme, aber: Dein Post war um 01:28 und nicht 01:01, es ist 01:32 während du eine Antwort bekommst und vermutlich 01:33 während du die Antwort liest. Der Mensch sieht eben immer gern das, was er sehen möchte. Psychospielchen sind schon was tolles :p

    Guten Tag zusammen,


    da das Tutorial von maddin ja doch schon ein paar Donnerstage zurückliegt und eigentlich eher für Anfänger konzipiert ist, dachte ich mir - da die Methode von maddin nicht wirklich serverfreundlich ist - versuch ich dem Ein oder Anderen hier im Raume zu vermitteln, wie mySQL nun wirklich funktioniert, worauf zu achten ist und welche Fehler vermieden werden sollten. Oftmals sehe ich hier im Forum, dass der Umgang mit mySQL völlig falsch gehandhabt wird, ständig Threads auftauchen wie "Was ist besser? mySQL oder Dini?", dort dann gekonnt mit "mySQL" geantwortet wird und die Halbwahrheit dahinter gut versteckt bleibt.


    Durchaus, so meine Meinung, ist SQL definitiv schneller als jedes Dateisystem, spart Platz und nimmt einem einiges an Arbeit ab - wenn man denn richtig damit umgeht! Ich versuche mich in diesem Tutorial so abstrakt wie möglich, aber dennoch so verständlich wie nötig zu halten, um garnicht groß auf die verschiedenen Plugins einzugehen, sondern mir erschwert auf mySQL zu beziehen.


    Insgesamt müssen wir eigentlich nur 3 Punkte beachten, damit wir das Maximum aus den Vorteilen einer SQL-Datenbank holen können:

    • Versucht, die Datenbank so klein wie möglich zu halten.
    • Lasst die SQL-Datenbank alles übernehmen, was sie übernehmen kann.
    • Versucht Punkt 2 mit so wenig Queries wie möglich zu erzielen.

    1. Versucht, die Datenbank so klein wie möglich zu halten.
    Klingt im Grunde eigentlich ganz einfach, oder? Der Schein trügt! Oftmals bedarf es einer detailverliebten Berechnung und Konzipierung im Vorfeld, damit eine Datenbank wirklich die Leistung erzielt, die sie erzielen könnte. Auch die regelmäßigen Updates einer Datenbankstruktur sind nicht außer Acht zu lassen. Doch für den Anfang beschränken wir uns auf die wohl 2 wichtigsten Regeln im Umgang mit SQL Datenbanken:

    • Eine Spalte sollte immer im richtigen Typus deklariert und niemals größer als der später größtmögliche Inhalt sein.
    • Versucht stets Doppelindizierungen zu vermeiden!

    Punkt 1: Ihr solltet euch im Vorfeld klar machen, was für ein Inhalt eigentlich in die Spalte eurer SQL-Tabelle eingetragen wird. Ist es eine Zahl? Wenn ja, wie groß ist ihr höchster/tiefster Wert? Liegt er über 2.14 Millionen? Liegt er darunter? (Integers können nur Zahlen von -2.147.483.648 bis +2.147.483.647 verarbeiten) - An dieser Stelle ist es ratsam, sich auch mal die Worte "Tinyint", "Smallint", "Mediumint" und "Bigint" anzuschauen - Sie alle erlauben eine chronologisch sortiert größere Zahlenreichweite.

    • Tinyint: 0 bis 255 (1 byte)
    • Smallint: -32.768 bis 32.767 (2 bytes)
    • ...
    • Bigint: -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807

    Wer also weiß, dass seine Zahl die Zahlengrenze von Smallint nicht überschreiten wird, sollte auch keinen größeren Integer verbrauchen. Selbes System gilt natürlich auch für Floats und Strings - nur ein wenig anders:
    Bei der Erstellung eurer SQL-Tabelle könnt ihr immer maximale Längen angeben (Length/Values in phpMyAdmin): Wenn ihr z.B. ihr braucht für die Koordinaten eines Spielers maximal die 2. Nachkommastelle um genau genug sein zu können,
    wäre die maximale Länge einer Koordinate also 8 (-1234.56) - Zeichen. 8, weil das Minuszeichen ebenso in der Länge relevant ist. Gleiches gilt natürlich für Strings: Die maximale, von SA:MP bestimmte Länge eines Spielernamens ist 24 (ist das noch aktuell?) also braucht eure Spalte auch nur eine Länge von 24, mehr wird niemals möglich sein, da SA:MP das nicht zulässt ;)
    An diesem Punkt kommen wir auf die Aktualisierung der Tabellen: Wenn SA:MP irgendwann mal 32 Zeichen im Namen erlauben sollte, müsst ihr dementsprechend natürlich auch eure Tabellen anpassen, ist ja wohl klar ;)
    Zuletzt sei an dieser Stelle wohl noch der Tabellentypus "boolean" nennenswert. Spalten mit diesem Typus können NUR die Werte true & false enthalten, nichts Anderes. Wer interessiert daran ist, noch detailierter an Größe sparen zu können, sollte sich einfach mal die verschiedenen Typen von SQL-Spalten anschauen und diese Googlen, über die mySQL Dokumentation erfährt mein eigentlich alles relevante, was hier nur die Größe des Tutorials ins unermessliche sprengen würde.
    Punkt 2: Doppelindizierungen sind des Satan's Werk einer jeden SQL-Datenbank und kommen leider auch unter erfahrenen Leuten öfter vor, als man es sich wünscht. Die Doppelindizierung bedeutet, dass ein und der selbe Wert in 2 verschiedenen Spalten/Tabellen unnötig gespeichert wird. Das erschwert die Verarbeitung eines Queries und belastet unnötig die Größe. Das wohl bekannteste Beispiel dafür ist das "Vorname, Nachname" Beispiel:
    Der klischeehafte Laie wird eine Tabelle mit den Werten
    accountId | vorname | nachname | name
    erstellen, in denen die Werte "1", "Max", "Mustermann" und "Max Mustermann" stehen, weil er sich dabei vermutlich denkt: "Brauche ich nur den Vornamen, nehme ich das passende Feld. Brauche ich nur den Nachnamen, nehme ich das andere Feld und brauche ich den vollen Namen habe ich ja das dritte Feld!" - Klingt logisch, ist aber unsinnig. Wenn man den Vornamen und Nachnamen schon irgendwo stehen hat, gibt es schönere Methoden (auch Methoden direkt über SQL) diese miteinander zu verbinden bzw wieder auseinander zu reißen. (Beispiele dafür findet man ebenfalls über Google und die mySQL Doku und werden hier nicht weiter erläutert)


    2. Lasst die SQL-Datenbank alles übernehmen, was sie übernehmen kann!
    Nicht selten sehe ich Codeschnipsel, in denen unnötige Stocks, parasitäre Querys und ausbremsende, logische Vorgänge angewandt werden - Dabei muss die Leistung garnicht so sehr leiden! Ich behaupte hier einfach mal blind, dass mySQL bei 90% aller Server hier schneller rechnen kann, als es das Script auf eurem Server könnte (da das ständig auf die Antwort von mySQL warten muss *g*), wenn der logische Vorgang dahinter sinnvoll ist. Wichtig hierbei zu überlegen ist: Was MUSS ich eigentlich alles haben, um mein Vorhaben umsetzen zu können (Welche Werte)? Muss ich diese Werte wirklich speichern und ausgeben, oder reicht es, wenn sie verarbeitet werden? Was davon kann vllt auch mySQL für mein Script übernehmen?
    Gehen wir mal vom Schlimmsten aus und euer momentaner Query sieht so aus:
    mysql_query("SELECT * FROM accounts");mysql_store_result();while (mysql_fetch_row(result)) { mysql_fetch_field("accountName", result); if (!strcmp(result, "DeinBenutzer")) { // tu dies und das... }}mysql_free_result();
    Dann hat mySQL - vor allem ab einer großen Anzahl an Datenbankeinträgen - unnötig viel Leistung zu erbringen, die man sich ersparen könnte. Gehen wir davon aus, wir wollen das Level eines Spielers mit dem Namen "DeinBenutzer" haben,so würde folgender Query absolut ausreichen:
    mysql_query("SELECT `spielerLevel` FROM `accounts` WHERE `accountName` = 'DeinBenutzer' LIMIT 1");
    mySQL überprüft also in jedem Eintrag nur noch die Spalte "spielerLevel" und liefert das Ergebnis, sobald die Zeile, in der die Spalte "accountName" = "DeinBenutzer" ist. Durch das LIMIT 1 sagen wir mySQL, dass wir mit dem ersten, gefundenen Eintrag zufrieden sind und sich die Datenbank wieder ausruhen darf. Wenden wir dies nicht an, sucht mySQL weiter nach Einträgen, auch wenn der Account schon lange gefunden wurde. (Geht mal davon aus, die 7. Spalte ist ein Treffer und es folgen noch 100.000 weitere, die alle unnötig abgefragt werden)
    Wir wollen diesen Datensatz nun also verarbeiten. Für unser Beispiel wollen wir einfach mal, das Level um 1 erhöhen, wenn der Spieler 1000 Erfahrung erreicht hat. Ein guter Weg wäre demnach einen Query an der Stelle eures Scripts zu platzieren, an dem der User seine Erfahrung erhält:
    mysql_query("UPDATE `accounts` SET `spielerLevel` = `spielerLevel` + 1, `spielerErfahrung` = '0' WHERE `accountName` = 'DeinBenutzer' AND `spielerErfahrung` >= 1000 LIMIT 1");
    Statt also nun erstmal alle Accounts zu überprüfen, dann die Werte auszulesen, zu vergleichen und neu einzutragen, brauchen wir nur noch einen einzigen Query.


    Die hier geführten Beispiele sind natürlich nur firlefanz und werden, abgesehen von Ausnahmefällen, natürlich keinen großen Belang für eure Geschwindigkeiten machen, doch das kann natürlich auch anders aussehen. Überlegen wir uns mal, wir haben 3 Tabellen, in denen 4 Einträge abhängig von einem Datensatz geändert werden sollen: (Für die Übersicht mache ich das jetzt mehrzeilig, was natürlich in PAWN so NICHT funktionieren würde, außer ihr benutzt strcat o.Ä.)


    mysql_query("UPDATE
    `accounts`, `fraktionen`, `staat`
    SET
    `accounts`.`spielerGeld` = `accounts`.`spielerGeld` + (`fraktionen`.`gehalt` * (1 - 0.03)),
    `accounts`.`spielerLevel` = `accounts`.`spielerLevel` + 1,
    `fraktionen`.`kasse` = `fraktionen`.`kasse` - `fraktionen`.`gehalt`,
    `staat`.`kasse` = `staat`.`kasse` + (`fraktionen`.`kasse` * 0.03)
    WHERE
    `accounts`.`accountName` = 'DeinBenutzer` AND
    `accounts`.`fraktion` = `fraktionen`.`fraktionsId` AND
    `staat`.`staatId` = '1'
    ");


    Wir geben in diesem einen Query also nun an, dass der Spieler das Gehalt seiner Fraktion abzüglich 3% Steuern bekommen soll, gleichzeitig das Geld für das Gehalt aus der Fraktionskasse abgerechnet wird und der Staat seine 3% gutgeschrieben bekommt und noch dazu der Spieler einen Levelaufstieg erhält. Das wären, so wie viele es hier bislang machen, vermutlich 6 Querys, den man auf einen reduzieren konnte. (Die meisten SQL Anfänger rufen via SELECT jeweils die Tabelle accounts, fraktionen und staat auf (3 Querys), rechnen dann den Wert der Spalte + den gewünschten Wert und erneuern den Inahlt via UPDATE (3 weitere Querys).
    Das bringt unserem Script schonmal eindeutig mehr Geschwindigkeit und entlastet das System. Wenn man sich anbei das Tutorial von maddin anschaut, in dem nun wirklich JEDES Feld einen eigenen Query bekommt, wären das "[Anzahl der Felder] * 2 (für mysql_get und mysql_set). Bei beispielsweise 16 Feldern, die zu erneuern sind, benötigen wir hier nur noch einen Query statt 32. Das Spiel lässt sich natürlich noch ins Unermessliche weiterspielen und bei mir im Script sind teilweise Queries, die noch einiges mehr tun, als da oben. Doch für die Verständlichkeit, warum man darauf achten sollte, reicht das hier gegebene Beispiel hoffentlich.
    3. Versucht Punkt 2 mit so wenig Queries wie möglich zu erzielen.
    In diesem Sinne, solltet ihr also versuchen, die Anzahl eurer Queries immer so gering wie möglich zu halten. Denn EIN Query mit 128 Änderungen ist immer noch produktiver und schneller als 128 Queries mit EINER Änderung. Anfangs bedarf dies sicherlich etwas Übung, aber hier hilft oftmals die altbewährte Methode mit dem Griff zu Stift und Papier und sich den logischen Vorgang der Queries erstmal aufzuschreiben.
    Ich hoffe, ich konnte dem Ein oder Anderen die Grundlagen der SQL-Verwaltung etwas näher bringen und wünsche euch viel Spaß mit einem schnelleren Script ;)