NUOVO 📢 Offerta di lancio limitata: fino al 70% di sconto sul tuo primo mese, per tutti i giochi!Vedi i piani

Come usare un database MySQL con un bot discord.js (mysql2)

Hosting di bot DiscordUpdated Nov 6, 20268 min read

Risposta breve. Aggiungi mysql2 al tuo bot discord.js, crea un solo pool di connessioni dalle variabili d'ambiente all'avvio del bot ed esegui ogni query attraverso di esso con segnaposto ?. Su PlayNHost ogni piano per bot include un database MySQL: crealo nella pagina Database, incolla i suoi dati nel riquadro Ambiente e il codice qui sotto funziona così com'è. Il database accetta connessioni dai tuoi server PlayNHost e da phpMyAdmin, non dal tuo computer. Abbiamo testato questo codice il 6 novembre 2026 con discord.js 14.28.1, mysql2 3.24.6 e Node.js 22, su MariaDB 10.11 con un account database configurato come il nostro (20 connessioni, limite di 120 secondi per query): l'avvio, la tabella e il gestore di /warn, ma non un vero login su Discord.

Cosa ti serve

1. Crea il database

  1. Apri il tuo server bot nel pannello e clicca su Database.
  2. Clicca su Nuovo database. Un'Etichetta è facoltativa; Verrà creato come mostra il nome completo. Clicca su Crea database.
  3. Si apre la pagina del nuovo database (più avanti, cliccalo in I tuoi database). La sua scheda Connessione mostra Host, Porta, Database, Nome utente e Password. Sotto Config pronta all’uso, Config per contiene uno snippet Node.js (mysql2) con gli stessi valori già compilati.

2. Metti i dati in Ambiente

  1. Apri la pagina Bot, il riquadro Ambiente, e clicca su Incolla un file .env.
  2. Incolla queste cinque righe con i valori della scheda Connessione:
    DB_HOST=your-host
    DB_PORT=3306
    DB_NAME=your-database
    DB_USER=your-username
    DB_PASSWORD=your-password
  3. DB_PASSWORD riceve un badge Segreto: viene salvata in sola scrittura e non viene mai più mostrata. Clicca su Importa 5 variabili.

Usa la porta reale della scheda Connessione. Tenere la password fuori dal codice significa che non finisce mai in un file o in un repository Git. Altro su questo riquadro: Come impostare variabili d'ambiente e segreti per il tuo bot Discord.

3. Il codice

package.json

{
  "name": "my-discord-bot",
  "private": true,
  "main": "index.js",
  "dependencies": {
    "discord.js": "^14",
    "mysql2": "^3"
  }
}

index.js

const { Client, Events, GatewayIntentBits, InteractionContextType, MessageFlags, REST, Routes, SlashCommandBuilder } = require('discord.js');
const mysql = require('mysql2/promise');

// One pool for the whole bot. The values come from the Environment pane.
const pool = mysql.createPool({
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  connectionLimit: 5,
});

const commands = [
  new SlashCommandBuilder()
    .setName('warn')
    .setDescription('Warn a member and count their warnings')
    .setContexts(InteractionContextType.Guild)
    .addUserOption((o) => o.setName('user').setDescription('Who to warn').setRequired(true))
    .addStringOption((o) => o.setName('reason').setDescription('Why').setRequired(true).setMaxLength(200))
    .toJSON(),
];

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.once(Events.ClientReady, async () => {
  await new REST().setToken(process.env.DISCORD_TOKEN).put(Routes.applicationCommands(client.user.id), { body: commands });
  console.log(`Logged in as ${client.user.tag}`);
});

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand() || interaction.commandName !== 'warn' || !interaction.guildId) return;
  const user = interaction.options.getUser('user', true);
  const reason = interaction.options.getString('reason', true);
  try {
    await pool.execute('INSERT INTO warnings (guild_id, user_id, reason) VALUES (?, ?, ?)', [interaction.guildId, user.id, reason]);
    const [rows] = await pool.execute('SELECT COUNT(*) AS total FROM warnings WHERE guild_id = ? AND user_id = ?', [interaction.guildId, user.id]);
    await interaction.reply(`${user} has ${rows[0].total} warning(s).`);
  } catch (err) {
    console.error(err);
    if (!interaction.replied) await interaction.reply({ content: 'Could not save the warning. Try again later.', flags: MessageFlags.Ephemeral }).catch(console.error);
  }
});

async function main() {
  await pool.query(`CREATE TABLE IF NOT EXISTS warnings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    guild_id VARCHAR(20) NOT NULL,
    user_id VARCHAR(20) NOT NULL,
    reason VARCHAR(200) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    KEY guild_user (guild_id, user_id)
  )`);
  console.log('Database ready');
  await client.login(process.env.DISCORD_TOKEN);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

Cosa fa: all'avvio il bot crea la tabella warnings se manca, stampa Database ready e poi effettua il login. /warn salva un avvertimento e risponde con il totale del membro. discord.js fornisce gli ID Discord come stringhe, perché sono troppo grandi per un numero JavaScript, quindi vengono salvati come testo. I segnaposto ? inviano il testo del membro al database separatamente dall'SQL, quindi un motivo come '); DROP TABLE warnings; -- viene salvato come semplice testo.

Due righe tengono vivo il bot. setContexts(InteractionContextType.Guild) e il controllo !interaction.guildId impediscono /warn in un messaggio privato, dove non c'è nessun server a cui associare l'avvertimento. Il try/catch risponde con un breve messaggio privato quando una query fallisce. Senza, discord.js passa l'errore al suo evento error e, se nessuno lo ascolta, Node.js ferma il bot. Nel nostro test abbiamo eliminato la tabella ed eseguito /warn: il bot ha registrato ER_NO_SUCH_TABLE, ha risposto Could not save the warning. Try again later. ed è rimasto in esecuzione.

4. Avvialo

  1. Carica index.js e package.json in Files. Non caricare node_modules.
  2. Premi Avvia e apri Console. All'avvio vengono installati i pacchetti, poi compaiono [PlayNHost] Starting your bot, Database ready e Logged in as ....
  3. Su Discord, scrivi /warn. Per vedere le righe, apri la pagina del database e clicca su Apri in phpMyAdmin.

I limiti che contano per il tuo pool

  • 20 connessioni contemporanee per utente del database. Conta ogni processo che usa lo stesso accesso: il tuo bot, una sua seconda copia, una dashboard. La connessione 21 viene rifiutata con ER_USER_LIMIT_REACHED. Nel nostro test un pool con connectionLimit: 30 è fallito con quell'errore non appena 30 query sono partite insieme. Un pool da 5 non apre mai più di 5 connessioni: le query in più aspettano una connessione libera.
  • Una query che dura più di 120 secondi viene interrotta. MariaDB la termina con l'errore 1969, Query execution was interrupted (max_statement_time exceeded). Nel nostro test è successo dopo 120.03 secondi. Le query di un bot di solito durano millisecondi, quindi questo riguarda solo una query fuori controllo.
  • 500 MB per database. La pagina Database mostra quanto spazio è usato. A 500 MB le scritture vengono bloccate finché non elimini delle righe.
  • I backup del server non includono il database. Esportalo da phpMyAdmin ogni tanto.

Errori e cosa significano

Questi sono i messaggi esatti che mysql2 ha dato nel nostro test:

  • ER_ACCESS_DENIED_ERROR ... Access denied for user: DB_USER o DB_PASSWORD errati. Dopo Reimposta password nella scheda Connessione, la vecchia password smette di funzionare subito: sostituisci DB_PASSWORD e riavvia il bot.
  • ECONNREFUSED: nessuno ha accettato la connessione a quell'host e a quella porta. Controlla DB_HOST e DB_PORT. Anche un DB_HOST mancante finisce qui, perché mysql2 si collega allora a localhost, dove non gira nessun database: la variabile manca in Ambiente, oppure il bot non è stato riavviato dopo averla aggiunta.
  • ENOTFOUND: DB_HOST è scritto male, quindi il nome non esiste.
  • ETIMEDOUT: nulla ha risposto entro 10 secondi, l'attesa predefinita di mysql2. Qualunque sia il messaggio, una connessione dal tuo computer fallisce: il database accetta solo connessioni dai server PlayNHost e da phpMyAdmin.
  • ER_USER_LIMIT_REACHED ... has exceeded the 'max_user_connections' resource (current value: 20): troppe connessioni aperte, vedi i limiti qui sopra. Di solito è una nuova connessione per ogni comando che non viene mai chiusa, oppure una seconda copia del bot.

Altri errori dei bot: Errori comuni dei bot Discord e cosa significano.

Quanta memoria aggiunge

Installare discord.js e mysql2 da zero ha toccato un picco di 147 MB di memoria (cache dei file esclusa) nel nostro test, in un container limitato a 512 MB come il nostro piano bot più piccolo. Dall'avvio fino al rifiuto del nostro token di prova da parte di Discord, il bot ha usato al massimo 31 MB; aveva creato la tabella ma non aveva mai effettuato il login. Un bot connesso e presente in molti server usa di più: Di quanta RAM ha bisogno un bot Discord?

Lo stesso in Python, o con Prisma

Ti serve un server bot con database incluso? Guarda i piani per bot.

Il tuo bot è già ospitato altrove? Spostalo da noi

ULTIMI ARTICOLI