Discord

  • Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

Spigot Erledigt MySQL Daten nummerieren

Yasuo Krieger

Kuhfänger
Mitglied seit
22 November 2015
Beiträge
60
Minecraft
NonPrimeYasuo
Hey Leute, Yasuo hier.

Ich habe mal ein neues Problem.
Ich Programmiere zur Zeit ein MySQL Plugin wo drinnen die Items gespeichert werden, wie in einem Shop.
Ich will jedes Item mit einer ID versehen die z.B. von 1 hochzählt und dann irgendwann 20 erreicht hat oder so.


Beispiel:
ID | Itemname | Itemid | Itemsubid | dies-das
1    bla bla        2        0                111
2    was weiß!    12        0            Wieso ich
3    ...            ....        ...        ....
und so weiter. Weiß da jemand wie das gehen könnte?

LG Yasuo
 

JOO200

Vorarbeiter
Osterei Experte
Mitglied seit
18 Dezember 2016
Beiträge
257
Was du suchst ist die Funktion "AUTO_INCREMENT". Durch diese ist es möglich, dass die Datenbank selbst den Wert einer Zelle ausfüllt und dabei den Wert immer um eins erhöht. Siehe auch hier: https://www.w3schools.com/sql/sql_autoincrement.asp
Oder zahlreiche andere Suchen.

Beim Eintragen eines Items über INSERT, lässt du die ID dann einfach leer.
Dein INSERT dürfte dann so aussehen: INSERT INTO tableId (Itemname, Itemid, Itemsubid, dies-das) VALUES (?,?,?,?);

Übrigens kannst du auch über die funktion RETURN_GENERATED_KEYS den erzeugten Key durch dein INSERT erhalten. https://stackoverflow.com/questions/1915166/how-to-get-the-insert-id-in-jdbc

Wenn du Items in die Datenbank speichern möchtest, schau mal hier: https://minecraft-server.eu/forum/threads/serialisieren-von-itemstacks-in-datenbanken-so-einfach-kann-es-gehen.43520/
 

Yasuo Krieger

Kuhfänger
Mitglied seit
22 November 2015
Beiträge
60
Minecraft
NonPrimeYasuo
Also wenn bin ich absolut zu dumm oder ich hab einfach keine Ahnung.
1. wie bringe ich das ein?
2. wie kann ich die zugegebene ID auslesen?
3, 4, 5 kannst du mir da nen Beispiel an meinem Code geben? ... @JOO200

Javascript:
public class MySQL {
   
    public static String username;
    public static String password;
    public static String database;
    public static String host;
    public static String port;
    public static Connection con;
   
    public static void connect() {
        if(!isConnected()) {
            try {
                con = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password);
                Bukkit.getConsoleSender().sendMessage(Main.getInstance().prefix + "§7Die MySQL-Verbindung wurde aufgebaut");
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
   
    public static void close() {
        if(isConnected()) {
            try {
                con.close();

                Bukkit.getConsoleSender().sendMessage(Main.getInstance().prefix + "§7Die MySQL-Verbindung wurde geschlossen");
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
   
    public static boolean isConnected() {
        return con != null;
    }
   
    public static void createTable() {
        if(isConnected()) {
            try {
                con.createStatement().executeUpdate("CREATE TABLE IF NOT EXISTS PlayerTab (spielername VARCHAR(100), UUID VARCHAR(100), coins VARCHAR(100), money VARCHAR(100))");
                con.createStatement().executeUpdate("CREATE TABLE IF NOT EXISTS PlayerTime (spielername VARCHAR(100), UUID VARCHAR(100), second VARCHAR(100), minute VARCHAR(100), hour VARCHAR(100))");
                con.createStatement().executeUpdate("CREATE TABLE IF NOT EXISTS Locations (NAME VARCHAR(100), world VARCHAR(100), x VARCHAR(100), y VARCHAR(100), z VARCHAR(100), pitch VARCHAR(100), yaw VARCHAR(100))");
                con.createStatement().executeUpdate("CREATE TABLE IF NOT EXISTS Navigator (FINDID VARCHAR(100), ITEMNAME VARCHAR(100), ID VARCHAR(100), SUBID VARCHAR(100))");
               
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
   
    public static void update(String qry) {
        if(isConnected()) {
            try {
                con.createStatement().executeUpdate(qry);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
   
    public static ResultSet getResult(String qry) {
        if(isConnected()) {
            try {
                return con.createStatement().executeQuery(qry);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }
}
 

❤️可愛いちゃん️❤️

Threadripper
Osterei Experte
Mitglied seit
19 Mai 2014
Beiträge
1.273
Alter
2
Wie sieht denn das aktuelle Datenbankschema aus? Autoinrenent ist Teil der Tabellendefinition.

Nvm, hab den Spoiler übersehen.
 
Zuletzt bearbeitet:

Hadde-chan

Social Media Manager
Social Media
Moderator
Showcase Teilnehmer
Redakteur
Osterei Experte
Mitglied seit
24 März 2013
Beiträge
177
Alter
24
Minecraft
Hadde
Du legst eine Spalte an und weist ihr den Typ AUTO_INCREMENT zu beim erstellen der Tabelle zu. Oder addest sie nachträglich:

SQL:
alter table
tablename
ADD id AUTO_INCREMENT;
Löschst du einen Eintrag daraus, wird die ID nicht wiederverwendet. das ist eine fortlaufende Nummer. Kann dir aber nicht garantieren, dass das rückwirkend funktioniert. Eigentlich setzt man Tabellen von Anfang an richtig auf.

Kleines Beispiel, dass der Index nicht gleichzusetzen ist mit der row Position.


Wenn du nun in die Tabelle mit einem insert values addest, setzt du alles was du setzen willst außer dem Index. Dieser wird beim INSERT automatisch eingefügt.


Ansonsten empfehle ich dir dich ausführlicher mit der Doku deiner Datenbank zu beschäftigen. Zu etwas wie einem AUTO_INCREMENT gibts mehr als genug fertige Code Snippets.

Kleiner Nachtrag zu deiner Tabellen Definition:
Wenn du schon die Datentyp länge definierst, dann definiere sie auch richtig. Eine uuid kommt auf 36 Zeichen nicht auf 100.

Warum speicherst du Coins und Money als VARCHAR, wenn du auch einen NUMERIC benutzen kannst? Erspart dir doofes casten zwischendrin.

Oder ids als INTEGER oder auch BIGINT abspeichern.
Oder die Koordianten. SQL hat eine riesige Bandbreite an Datentypen. Alles als VARCHAR zu speichern ist Bad Practice. Zudem SQL für numerische Zahlen viel bessere interne Suchindices erstellen kann. VARCHAR ist schrecklich zum Suchen.

Außerdem sind Tabellen ohne Primary Keys ganz böse für eine Datenbank. Dont do this! Zumindest nicht, wenn du darin vor hast Daten gezielt zu suchen.

Erstmal solltest du also deine generelle Tabellenstruktur überarbeiten, bevor du da irgendwas reinschreibst. Damit wirst du aktuell nicht viel Freude haben.
 
Zuletzt bearbeitet:

Yasuo Krieger

Kuhfänger
Mitglied seit
22 November 2015
Beiträge
60
Minecraft
NonPrimeYasuo
Du legst eine Spalte an und weist ihr den Typ AUTO_INCREMENT zu beim erstellen der Tabelle zu. Oder addest sie nachträglich:

SQL:
alter table
tablename
ADD id AUTO_INCREMENT;
Löschst du einen Eintrag daraus, wird die ID nicht wiederverwendet. das ist eine fortlaufende Nummer. Kann dir aber nicht garantieren, dass das rückwirkend funktioniert. Eigentlich setzt man Tabellen von Anfang an richtig auf.

Kleines Beispiel, dass der Index nicht gleichzusetzen ist mit der row Position.


Wenn du nun in die Tabelle mit einem insert values addest, setzt du alles was du setzen willst außer dem Index. Dieser wird beim INSERT automatisch eingefügt.


Ansonsten empfehle ich dir dich ausführlicher mit der Doku deiner Datenbank zu beschäftigen. Zu etwas wie einem AUTO_INCREMENT gibts mehr als genug fertige Code Snippets.

Kleiner Nachtrag zu deiner Tabellen Definition:
Wenn du schon die Datentyp länge definierst, dann definiere sie auch richtig. Eine uuid kommt auf 36 Zeichen nicht auf 100.

Warum speicherst du Coins und Money als VARCHAR, wenn du auch einen NUMERIC benutzen kannst? Erspart dir doofes casten zwischendrin.

Oder ids als INTEGER oder auch BIGINT abspeichern.
Oder die Koordianten. SQL hat eine riesige Bandbreite an Datentypen. Alles als VARCHAR zu speichern ist Bad Practice. Zudem SQL für numerische Zahlen viel bessere interne Suchindices erstellen kann. VARCHAR ist schrecklich zum Suchen.

Außerdem sind Tabellen ohne Primary Keys ganz böse für eine Datenbank. Dont do this! Zumindest nicht, wenn du darin vor hast Daten gezielt zu suchen.

Erstmal solltest du also deine generelle Tabellenstruktur überarbeiten, bevor du da irgendwas reinschreibst. Damit wirst du aktuell nicht viel Freude haben.
Ich checke nur wenig mit dem "Auto_increment" schnippsel helfen mir nicht. Ich muss das verstehen. Anders gehts nicht. Wegen der richtigen Formatierungen kann ich mir mal gedanken machen. Kannst du mir mal an einer meiner Tabellenerstellung ein Beispiel machen?

Beispielcode:
con.createStatement().executeUpdate("CREATE TABLE IF NOT EXISTS Navigator (FINDID VARCHAR(100), ITEMNAME VARCHAR(100), ID VARCHAR(100), SUBID VARCHAR(100))");
 

Hadde-chan

Social Media Manager
Social Media
Moderator
Showcase Teilnehmer
Redakteur
Osterei Experte
Mitglied seit
24 März 2013
Beiträge
177
Alter
24
Minecraft
Hadde
Das erstellt eine Tabelle mit einem autoincrement auf der ID Column.
Erstellst du eine Spalte mit einem Autoincrement legt deine Datenbank im hintergrund eine so genannte Squenz an. Diese Speichert die zuletzt gesetzte zahl und sorgt dafür, dass keine zahlen doppelt vorkommen oder erneut verwendet werden.
SQL:
CREATE TABLE IF NOT EXISTS Navigator (
    ID INT NOT NULL AUTO_INCREMENT,
    FINDID INTEGER,
    ITEMNAME VARCHAR(100),
    SUBID INTEGER,
    PRIMARY KEY (ID)
Um dir ein gutes Datenbankschema zu entwerfen müsste ich erstmal wissen, welchen sinn die einzelnen IDs haben. In einigen Fällen machst du es dir auch viel zu kompliziert. Du speicherst zum Beispiel Stunden, Minuten etc einzeln, anstatt sie in einem Timestamp zu speichern.

Dabei wird ebenfall der Primary Key auf die ID gesetzt. Die bedeutet, dass wenn du mit einem select statement drüber rennst wie unten, der Query erheblich schneller durch läuft:
SQL:
select *
    from Navigator
    where ID = 1
Der Sinn von Primary Keys ist, dass die Datenbank bereits im vorraus Suchindices erstellt und so eine erheblich schnellere suche ermöglicht.
Da ein Primary Key vor allem nur einmal existieren kann, wird die Tabelle nur bis zu einem Match und nicht komplett durchsucht.
 
Zuletzt bearbeitet:

❤️可愛いちゃん️❤️

Threadripper
Osterei Experte
Mitglied seit
19 Mai 2014
Beiträge
1.273
Alter
2
Ich bin mir nicht sicher ob das PostgreSQL dich nicht versaut hat. Glaub AI ist ne Option und kein Datentyp, vielleicht gibt's das aber auch als Alias. Hab gerade keine Möglichkeit das zu testen. Könnte aber sein, dass das nicht so geht.
 

Hadde-chan

Social Media Manager
Social Media
Moderator
Showcase Teilnehmer
Redakteur
Osterei Experte
Mitglied seit
24 März 2013
Beiträge
177
Alter
24
Minecraft
Hadde
Ich bin mir nicht sicher ob das PostgreSQL dich nicht versaut hat. Glaub AI ist ne Option und kein Datentyp, vielleicht gibt's das aber auch als Alias. Hab gerade keine Möglichkeit das zu testen. Könnte aber sein, dass das nicht so geht.
Muss dich enttäuschen. In Postgres ist das etwas anders xD Hab extra nachgeschaut wie es für MySQL geht.
AI setzt du direkt auf die column beim erstellen der Tabelle.

Wenn er aber sql benutzt ist das IDENTITY. Aber ich gehe mal davon aus, dass wir es hier mit dem 0815 MySQL auf ner MariaDB oä zu tun haben.
 

petomka

Redstoneengineer
Osterei Experte
Mitglied seit
8 Oktober 2012
Beiträge
35
Alter
20
Hallo,

Nun hast du ja schon bereits das Wissen, das du benötigst, um eine Tabelle mit einer ID-Spalte mit Auto-Increment anzulegen. Wenn du nun noch in deinem Java-Code direkt bei einem Insert wissen möchtest, welche Schlüssel (also welche IDs) dabei generiert wurden, musst du das in deinem execute(String, int) als zweites Argument mit übergeben (siehe Statement - besser wären übrigens PreparedStatements (aus Sicherheitsgründen), da kannst du es direkt beim Erzeugen des selbigen in der Connection angeben).

Das sieht dann in etwa so aus:
Java:
public void something() throws Exception {
    Connection connection = ...;
    PreparedStatement stmt = connection.prepareStatement("SELECT * FROM `table` WHERE a = ?", Statement.RETURN_GENERATED_KEYS);
    stmt.setInt(1, 1337);
    stmt.executeUpdate();
    ResultSet generatedKeys = stmt.getGeneratedKeys();
    //in diesem ResultSet steht deine generierte ID.
    while(generatedKeys.next()) {
        int id = generatedKeys.getInt(1); //Bei einem Insert hast du auch nur einen Key generiert, also keine Schleife notwendig. Das next() schon!
    }
}
Wenn du kein PreparedStatement verwendest, kannst du all das natürlich auch mit dem normalen Statement mit den entsprechenden Methoden erreichen.

Gruß,
petomka
 
Oben