Connecter un bot Discord à une base de données
Niveaux, économie, configuration par serveur… dès qu'un bot Discord doit se souvenir de quelque chose, il lui faut une base de données. Voici comment choisir et connecter la bonne.
Pourquoi utiliser une base de données pour un bot Discord ?
Une base de données bot Discord permet de conserver les informations après un redémarrage, un crash ou une mise à jour. Sans persistance, les variables stockées uniquement dans la mémoire du programme disparaissent dès que le processus s’arrête.
Prenons un compteur conservé dans une variable JavaScript :
const niveaux = new Map();
Cette structure fonctionne tant que le bot reste en ligne. Si PM2 le redémarre ou si le serveur est mis à jour, son contenu est perdu.
Une base de données permet de conserver durablement :
- les niveaux et points d’expérience ;
- les soldes d’une économie virtuelle ;
- les avertissements et sanctions ;
- la configuration propre à chaque serveur Discord ;
- les rôles automatiques ;
- les tickets ;
- les statistiques d’utilisation ;
- les préférences des membres.
Chaque donnée doit être associée à des identifiants stables. Pour une configuration par serveur, utilisez généralement l’identifiant de la guilde Discord. Pour une donnée liée à un membre, enregistrez aussi son identifiant utilisateur.
Exemple de clé logique :
guild_id + user_id
N’utilisez pas le pseudo comme identifiant principal. Un membre peut changer de nom, alors que son identifiant Discord reste stable.
SQLite : le choix le plus simple pour commencer
SQLite enregistre les données dans un fichier local, généralement avec une extension .db ou .sqlite. Aucun serveur de base de données séparé n’est nécessaire.
Une arborescence simple peut ressembler à ceci :
mon-bot/
├── index.js
├── package.json
├── data/
│ └── bot.sqlite
└── .env
SQLite convient particulièrement bien pour :
- un bot personnel ;
- une petite ou moyenne communauté ;
- un seul processus de bot ;
- un projet en développement ;
- une configuration et un volume de données modérés.
Ses avantages sont clairs :
- installation rapide ;
- aucun service MySQL ou MongoDB à administrer ;
- fichier facile à déplacer ;
- prise en charge des transactions ;
- langage SQL standard pour les opérations courantes.
Exemple de table :
CREATE TABLE IF NOT EXISTS guild_settings (
guild_id TEXT PRIMARY KEY,
welcome_channel_id TEXT,
language TEXT NOT NULL DEFAULT 'fr'
);
SQLite accepte plusieurs lectures, mais les écritures concurrentes restent plus limitées qu’avec un serveur MySQL ou MongoDB. Il est donc moins adapté lorsque plusieurs instances du bot, plusieurs services ou de nombreuses opérations simultanées utilisent la même base.
SQLite est un excellent point de départ. Ne migrez vers une base plus complexe que lorsque votre architecture ou votre charge le justifie réellement.
Le fichier SQLite doit être stocké sur un espace persistant. S’il se trouve dans un dossier temporaire recréé à chaque déploiement, vos données disparaîtront malgré l’utilisation d’une base.
MySQL ou MariaDB : une base relationnelle robuste
MySQL et MariaDB fonctionnent comme des services indépendants auxquels le bot se connecte par le réseau. Les données sont organisées en tables liées entre elles.
Cette approche convient lorsque vous avez :
- un volume de données important ;
- plusieurs processus ou services ;
- un tableau de bord web relié au bot ;
- des relations complexes entre membres, serveurs, sanctions et transactions ;
- des besoins de recherche et de statistiques avancés.
Une structure relationnelle peut séparer les données :
guilds
members
warnings
transactions
tickets
Les relations permettent, par exemple, de rattacher plusieurs sanctions à un membre ou plusieurs configurations à une guilde.
La chaîne de connexion doit être chargée depuis une variable d’environnement :
DATABASE_URL=mysql://bot_user:MOT_DE_PASSE@mysql.exemple.fr:3306/bot_discord
Avec Node.js et mysql2, une connexion avec pool peut prendre cette forme :
const mysql = require("mysql2/promise");
const pool = mysql.createPool(process.env.DATABASE_URL);
async function getMemberLevel(guildId, userId) {
const [rows] = await pool.execute(
`SELECT level
FROM members
WHERE guild_id = ? AND user_id = ?`,
[guildId, userId]
);
return rows[0]?.level ?? 0;
}
Le pool réutilise plusieurs connexions au lieu d’en ouvrir une nouvelle pour chaque commande Discord.
N’utilisez pas le compte administrateur global de MySQL. Créez un utilisateur réservé au bot avec uniquement les droits nécessaires sur sa propre base.
Si vous déployez votre bot sur un VPS, commencez par le guide pour vous connecter en SSH.
MongoDB : une structure documentaire flexible
MongoDB stocke les données sous forme de documents proches du JSON. Au lieu de répartir systématiquement les informations dans plusieurs tables, vous pouvez regrouper une configuration dans un même document.
Exemple conceptuel :
{
"guildId": "123456789",
"language": "fr",
"welcome": {
"enabled": true,
"channelId": "987654321",
"message": "Bienvenue !"
},
"moderation": {
"logChannelId": "456789123",
"maxWarnings": 3
}
}
MongoDB peut être pratique pour :
- des configurations différentes selon chaque serveur ;
- des objets imbriqués ;
- des structures qui évoluent souvent ;
- un projet déjà intégré à un écosystème JavaScript ;
- des données ne nécessitant pas beaucoup de relations complexes.
La connexion doit, elle aussi, rester dans une variable d’environnement :
MONGODB_URI=mongodb://bot_user:MOT_DE_PASSE@mongo.exemple.fr:27017/bot_discord
Une recherche doit utiliser des valeurs contrôlées :
const settings = await collection.findOne({
guildId: interaction.guildId,
});
MongoDB offre un schéma flexible, mais cela ne dispense pas de valider les données. Sans règles claires, deux documents représentant la même fonction peuvent finir par utiliser des structures incompatibles.
Un schéma flexible ne signifie pas une absence de schéma. Définissez les champs attendus, leurs types et leurs valeurs par défaut.
Quelle base de données bot Discord choisir ?
Le bon choix dépend de votre architecture, pas uniquement du nombre actuel de membres.
| Critère | SQLite | MySQL / MariaDB | MongoDB |
|---|---|---|---|
| Installation | Très simple | Service séparé | Service séparé |
| Stockage | Fichier local | Tables relationnelles | Documents |
| Petit bot | Excellent | Possible | Possible |
| Plusieurs processus | Limité | Très adapté | Très adapté |
| Relations complexes | Possible, mais moins pratique à grande échelle | Excellent | Moins naturel |
| Configurations imbriquées | Correct | Nécessite plusieurs colonnes ou tables | Excellent |
| Administration | Faible | Intermédiaire | Intermédiaire |
| Sauvegarde | Copie cohérente du fichier | Export SQL | Export MongoDB |
| Évolution du schéma | Migrations SQL | Migrations SQL | Migrations documentaires |
Choisissez généralement :
- SQLite pour débuter ou pour un seul bot de taille modérée ;
- MySQL/MariaDB pour une application structurée, relationnelle ou utilisée par plusieurs services ;
- MongoDB pour des documents flexibles et des configurations fortement imbriquées.
Ne changez pas de technologie uniquement parce que votre bot rejoint davantage de serveurs. Mesurez d’abord les limites réellement rencontrées : contention, temps de réponse, volume, disponibilité ou besoin de partager les données.
Se connecter à la base en sécurité
Ne placez jamais vos identifiants directement dans le code.
Mauvais exemple :
const password = "MonVraiMotDePasse";
Utilisez plutôt une variable d’environnement :
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("La variable DATABASE_URL est absente.");
}
Ajoutez les fichiers contenant des secrets à .gitignore :
.env
.env.*
!.env.example
Les identifiants de base, tokens Discord, clés API et webhooks doivent tous suivre les mêmes règles. Le guide pour sécuriser le token de votre bot Discord complète ces précautions.
Pour MySQL ou MariaDB, utilisez toujours des requêtes préparées ou paramétrées.
Mauvais exemple :
const query =
`SELECT * FROM members WHERE user_id = '${userInput}'`;
Bon exemple :
const [rows] = await pool.execute(
"SELECT * FROM members WHERE user_id = ?",
[userId]
);
La valeur est alors transmise séparément de la commande SQL, ce qui réduit le risque d’injection.
Appliquez également ces mesures :
- créez un utilisateur dédié à la base ;
- limitez ses permissions ;
- utilisez une connexion chiffrée lorsque le service le permet ;
- n’exposez pas inutilement les ports
3306ou27017à Internet ; - filtrez les adresses autorisées ;
- ne journalisez jamais le mot de passe ou la chaîne complète de connexion.
Bonnes pratiques de persistance
Créez des index sur les champs fréquemment recherchés.
Pour un bot Discord, les index utiles concernent souvent :
guild_id
user_id
ticket_id
created_at
Une table peut utiliser un index composite :
CREATE UNIQUE INDEX idx_member_guild
ON members (guild_id, user_id);
Cet index accélère la recherche d’un membre dans une guilde et empêche la création accidentelle de doublons.
Utilisez aussi :
- des transactions pour les opérations financières ;
- des contraintes uniques ;
- des valeurs par défaut ;
- une validation des données avant l’écriture ;
- un pool de connexions ;
- des délais d’expiration pour les données temporaires ;
- des migrations versionnées.
Avant de modifier une table ou de transformer des milliers de documents, testez la migration sur une copie. Préparez également une méthode de retour arrière.
Des sauvegardes automatiques sont incluses pour vous aider à restaurer. Conservez aussi vos propres exports réguliers : vous restez responsable de vos données.
Pour SQLite, sauvegardez le fichier lorsque les écritures sont correctement suspendues ou utilisez une méthode de sauvegarde prévue par la bibliothèque.
Pour MySQL ou MariaDB, réalisez des exports SQL réguliers. Pour MongoDB, utilisez un export adapté aux collections et vérifiez qu’il peut réellement être restauré.
Enfin, ne conservez pas une connexion globale non surveillée sans gestion d’erreur. Votre bot doit détecter une déconnexion, journaliser clairement le problème et éviter de confirmer une action Discord si l’écriture en base a échoué.
Pour maintenir le programme actif après un redémarrage, consultez le guide pour héberger un bot Discord 24 h/24 et 7 j/7.
En résumé
- Une base de données bot Discord conserve les niveaux, configurations, sanctions et autres informations après un redémarrage.
- Utilisez les identifiants Discord stables plutôt que les pseudos.
- Choisissez SQLite pour un bot simple fonctionnant avec un seul processus.
- Choisissez MySQL ou MariaDB pour des données relationnelles et plusieurs services.
- Choisissez MongoDB pour des documents flexibles et des configurations imbriquées.
- Stockez les chaînes de connexion dans des variables d’environnement.
- N’intégrez jamais un mot de passe ou une clé directement dans le code.
- Utilisez des requêtes SQL préparées ou paramétrées.
- Créez un utilisateur de base limité aux droits nécessaires.
- Ajoutez des index sur les identifiants et champs fréquemment recherchés.
- Sauvegardez régulièrement les données et testez vos restaurations.
- Pour déployer une base de données bot Discord sur un hébergement avec panel de gestion et support francophone, découvrez l’offre hébergement bot Discord TalCloud.