Hallo,
ich möchte euch einmal die Alternative zu MySQL vorstellen, nämlich SQLite.
Im Forum kusieren bisher 2 Werke damit einmal die DT_SaveBox und einmal gPM.
Ich finde es relativ traurig, das viele glauben man müsse unbedingt MySQL als Datenverwaltung haben, weil es mega super toll und total schnell sei, das ist aber nicht so.
SQLite weist gewisse Vorzüge in der Geschwindigkeit bei kleineren Datenbanken im gegen Satz zu MySQL auf.
Erst wenn die Datenbank, verdammt groß wird weist es Geschwindigtkeitseinbußen auf.
Viele von euch sind ja der Meinung das man UCPs nur mit Hilfe von MySQL erstellen kann,
dies stimmt aber nicht.
SQLite weist in PHP den gleichen Funktionsumfang wie wie MySQL auf.
Eine Übersicht über die Funktionen von PHP in Verbindung mit SQLite findet ihr hier
Für normale User gibt es keinen wirklichen Unterschied,
aber es gibt wesentliche Unterschiede zum Funktionsumfang, wie der Name "Lite" schon vermuten lässt.
Sie sind nicht für den normalen Gebrauch wirklich wichtig, also keine Sorge
Fangen wir mit dem wesentlichen an.
Warum SQLite?
Warum SQLite?
Die Frage ist nicht so schwer zu beantworten.
Wie oben schon beschrieben ist es in vielen Fällen überhaupt nicht nötig MySQL zu nutzen.
Es gibt natürlich einen Nachteil in punkto Sicherheit.
Die Datenbank liegt nur im Scriptfiles Ordner und kann von jedem der darauf Zugriff hat ausgelesen werden.
Es gibt natürlich auch gewisse Vorzüge von SQLite.
z.B. die Datenbank besteht nur aus einer Datei und ist nur einige (hundert) Kilobyte groß, also kein wirklicher Speicherplatzverlust.
Dazu passt sich die Datenbank während der Laufzeit immer auf das System an, das gerade die Datenbank benutzt.
Das vereinfacht den Austausch zwischen verschiedenen Systemen, sogar zwischen Systemen mit unterschiedlichen Byte-Reihenfolgen.
Jede Spalte kann also Daten beliebiger Typen enthalten, die erst zur Laufzeit wird nötigenfalls konvertiert werden.
Diese Vorzüge sind natürlich nicht für jeden relevant, deshalb muss jeder selbst entscheiden, ob er lieber SQLite, MySQL oder gleich beim klassischen Filesystem bleibt.
Also gut fangen wir mit dem eigentlichen Coding-/Scriptteil an.
Erstellen bzw. öffnen einer Datenbank:
Falls eine Datenbank noch nicht existiert, man sie aber trotzdem öffnen möchte,
ist es in SA:MP nicht relevant diese per Hand zu erstellen,
wenn man die Datenbank trotzdem per Hand erstellen möchte, kann dies gerne tun.
Anleitung dazu findet ihr weiter unten.
Damit müssen wir uns aber nicht abgeben, da dies der SA:MP Server für uns übernimmt.
Die Funktion dafür lautet db_open();
hier ein kleines Beispiel:
new DB:Database;
/*
Die "ID" zu Datenbank speichern wir in Database, der Tag "DB" sorgt,
einfach gesagt dafür, das nur bestimmte Funktionen die Variable "überschreiben"
Warum die "ID" Speicherung wichtig ist, folgt später.
*/
public OnGameModeInit()
{
Database = db_open("Stats.db"); // wir wollen hier die Datenbank Stats erstellen bzw. öffnen
return 1;
}
Alles anzeigen
OK, wir haben jetzt eine Datenbank erstellt, aber wir wollen jetzt ja damit arbeiten.
Erstellen von Tabellen in der SQLite Datenbank:
Das erstellen von Tabellen in der Datenbank, läuft nicht unbedingt so einfach ab, wie bei MySQL, sofern man immer mit PhpMyAdmin gearbeitet hat.
Ich nehme jetzt als Beispiel Navicat, weil es eigentlich dafür am einfachsten ist.
Sofern ihr Navicat noch nicht installiert habt, hier ein Downloadlink: http://www.computerbild.de/dow…Navicat-Lite-1298757.html
Zuerst müssen wir eine Verbindung zur Datenbank herstellen, das geht aber nur wenn sie auch existiert^^
Gut zum erstellen der Verbindung gehen wir zuerst auf den "Button" Connection und wählen SQLite aus
Dann legen wir den Verbindungsnamen und die Datenbank Datei fest.
Dabei ist zu beachten das "Existierende Datenbank Datei" ausgewählt ist.
Als nächstes gilt es die Tabelle zu erstellen, dies geht über "New Table",
dort ist alles wie gehabt.
Felder erstellen und den Feldtypen festlegen.
Meistens braucht man hier allerdings nur Integer und Text.
Bei Text ist grundsätzlich die Länge anzugeben und bei den Integer nicht, diese passen sich selbstständig an.
Als nächstes wenn die Tabelle erstellt ist, speichern wir sie und geben ihr einen Namen.
Die Tabelle mit der wir arbeiten werden ist unten.
Nach dem wir die Tabelle erstellt haben, schließen wir Navicat und kümmern und uns wieder um den Scriptteil.
Einfügen von Daten in die Datenbank:
Das einfügen von Daten ist eigentlich das einfachste,
ich vollführe das einmal an einem Beispiel, da dies eigentlich selbsterklärend ist,
wenn man schon mal mit MySQL bzw. SQL gearbeitet hat.
public OnPlayerConnect(playerid)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // speichern der Spielernamens in query
format(query, 128, "INSERT INTO `Accounts` (`ID`, `Name`) VALUES (7, '%s')",query); // Formatierung des Strings bzw. des Querys und einfügen
/*
INSERT INTO | Suggeriert der Datenbank das nun etwas in eine Tabelle (Accounts) eingefügt wird
`Accounts` | Die Tabelle
(`ID`,`Name`) | Die einzelnen Felder
VALUES | Suggeriert der Datenbank, das nun die Werte folgen, die zu den Felder gehören
('%s','7') | Die Werte die in die Felder eingetragen werden
*/
db_query(Database, query); // Ausführen des Querys
/*
Hier kommt die variable Database zum Tragen.
Database bzw. die ID ist hier wichtig, falls man mehrere Datenbanken gleichzeitig offen hat.
Ein weiter Vorteil.
Man kann mehr als 4, wie bei den MySQL Plugins, Connections gleichzeitig haben.
*/
return 1;
}
Alles anzeigen
Die Tabelle sollte danach so aussehen.
Wenn nicht, beginnt von vorne oder lasst es,
wer es bis hier hin zum 2. mal nicht geschafft hat, sollte es lassen
Updaten von Werten:
Nun zum 2. einfachsten, das Updaten von Werten.
Es ist nicht viel anders als das einfügen, der Aufbau des Querys sind nur komplett anders.
public OnPlayerDisconnect(playerid,reason)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // speichern der Spielernamens in query
format(query, 128, "UPDATE `Accounts` SET `ID` = '77' WHERE `Name` = '%s'", query); // Formatierung des Strings bzw. des Querys und einfügen
/*
UPDATE | Suggeriert der Datenbank das nun etwas in der Tabelle (Accounts) geupdatet wird
`Accounts` | Die Tabelle
SET | Suggeriert der Datenbank das nun alle Felder mit ihren Werten folgen
`ID` = '77' | Setzt das Feld ID auf 77
WHERE `Name` = '%s' | Suggeriert der Datenbank in welcher Spalte etwas geändert bzw. geupdatet werden soll.
*/
db_query(Database, query); // Ausführen des Querys
return 1;
}
Alles anzeigen
Wenn der Code ausgeführt wurde sollte eure Tabelle wie folgt aussehen
Bild 4:
Wenn nicht, alles auf Anfang oder lasst es
Auslesen von Daten:
Nun zum schwierigsten Teil, das Auslesen von Daten.
Eigentlich ist es ganz einfach, wenn man es verstanden hat.
Problem hier allerdings, es gibt hier zwei verschiedene Möglichkeiten an die Daten zu kommen.
Ich arbeite sie von oben bis unten einmal ab.
Möglichkeit 1:
Das ist die schwierigste Möglichkeit.
Hier arbeiten wir direkt mit mehreren Feldern,
da es ziemlich blöd und umständlich ist alle Felder die man braucht einzeln aus zu lesen.
public OnPlayerSpawn(playerid)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // Speichern der Spielernamens in query
format(query,128,"SELECT * FROM `Accounts` WHERE `Name` = '%s'",query); // Formatierung des Strings bzw. des Querys und einfügen
/*
SELECT | Suggeriert der Datenbank das nun etwas "entnommen" wird
* | bedeutet nur das alles entnommen wird, macht nur dann Sinn, wenn man mehr als eine Sache aus der Tabelle laden möchte
FROM | Suggeriert von welcher Tabelle entnommen wird
`Accounts` | Die Tabelle
WHERE `Name` = '%s' | Die zu entnehmende Zeile
*/
new DBResult:result = db_query(Database, query); // Den Rückgabewert also das Ergebnis in der Variable result speichern | Achtung, das ist nicht das was wir wollen - ist später aber wichtig
db_get_field_assoc(result, "ID", query, 5); // Wir speichern den Wert aus der Tabelle im Feld ID im String query | 5 ist hier die Länge die der Wert maximal haben darf.
// Das heißt, wenn im Feld 123457 steht wird nur 12345 gespeichert. Da 123457 6 Zeichen enthält und nur 5 maximal enthalten sein dürfen, wird es auf 12345 gekürzt.
/*
Da der Wert nun in einem String ist und wir den so überhaupt nicht gebrauchen können, da es ja ein Integer bzw. eine Zahl ist müssen wir das umwandeln
und das geht mit strval();
*/
new ID = strval(query); // Umwandeln in ein Integer
/*
in einen Float würde das mit floatstr(); funktionieren
new Float:ID = floatstr(query),
*/
printf("ID: %d", ID); // Hier lassen wir uns das Ergebnis ausgeben
db_get_field_assoc(result, "Name", query, MAX_PLAYER_NAME);
print("Name");
print(query); // Wir können direkt damit arbeiten, da wir hier einen String brauchen
db_free_result(result); // Freigeben des Speichers, der durch das Auslesen belegt war
return 1;
}
Alles anzeigen
Wenn alles richtig gemacht wurde steht nun 7 und eure Namen in der Serverlog bzw. in der Serverkonsole.
Herzlichen Glückwunsch ihr könnt nun mehrere Daten auf einmal auslesen
Möglichkeit 2:
Nun zu der einfachsten Methode, das Auslesen von nur einem Feld.
Zur Verdeutlichung nutze ich hier das vorherige Beispiel ein abgeänderter Form.
public OnPlayerSpawn(playerid)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // Speichern der Spielernamens in query
format(query, 128, "SELECT `ID` FROM `Accounts` WHERE `Name` = '%s'", query); // Formatierung des Strings bzw. des Querys und einfügen
/*
SELECT | Suggeriert der Datenbank das nun etwas "entnommen" wird
`ID` | Das ist das Feld das wir auslesen wollen.
FROM | Suggeriert von welcher Tabelle entnommen wird
`Accounts` | Die Tabelle
WHERE `Name` = '%s' | Die zu entnehmende Zeile
*/
new DBResult:result = db_query(Database, query); // Den Rückgabewert also das Ergebnis in der Variable result speichern | Achtung, das ist nicht das was wir wollen - ist später aber wichtig
db_get_field(result, 0, query, 5);
/*
0 ist hier die Feld ID | Da nur das Feld ID ausgegeben werden kann ist die FeldID 0 | Der Rest ist wie gehabt.
Man kann mit dieser Funktion auch wie oben beschrieben, die Felder auslesen, dann muss man aber wissen welche ID die einzelnen Felder haben.
*/
new ID = strval(query); // Umwandeln in ein Integer
printf("ID: %d", ID); // Hier lassen wir uns das Ergebnis ausgeben
db_free_result(result); // Freigeben des Speichers, der durch das Auslesen belegt war
return 1;
}
Alles anzeigen
So nun habt ihr es fast überstanden.
Im 2. Post Folgen ein paar weitere Funktionen mit Anwendungsbeispielen.
Viel Spaß beim Lesen