Diese umfassende Anleitung beschreibt die Integration einer MySQL-Datenbank in eine Echtzeit-Anwendung mit Node.js und Socket.io. Sie lernen praktische Schritte, um ein persistentes Wahlsystem zu erstellen, in dem Daten Server-Neustarts überstehen. Diese Anleitung richtet sich an Entwickler, die ihre Echtzeit-Apps mit zuverlässigem Datenspeicher erweitern möchten.
In früheren Tutorials speicherten Echtzeit-Node.js-Anwendungen Daten nur im flüchtigen Arbeitsspeicher und verloren sie beim Server-Neustart. Für den Produktionseinsatz ist persistenter Speicher unerlässlich. Die MySQL-Datenbank wurde aufgrund ihrer Zuverlässigkeit und weiten Verbreitung gewählt. Daher konzentriert sich diese Anleitung auf die Integration von MySQL, um eine robuste Echtzeit-Node.js-Anwendung zu erstellen.
Dieses Projekt baut auf einem grundlegenden Tutorial für eine Echtzeit-Wahlanwendung auf. Stellen Sie sicher, dass Ihre Node.js-Entwicklungsumgebung und das Basisprojekt eingerichtet sind, bevor Sie fortfahren.
Schritte zur Integration von MySQL in eine Echtzeit-Node.js-App
Die Datenbankintegration umfasst mehrere wichtige, aufeinanderfolgende Schritte. Stellen Sie zunächst sicher, dass MySQL auf Ihrem System installiert ist, indem Sie das offizielle Installationsprogramm von der MySQL-Website herunterladen. Erstellen Sie dann eine dedizierte Datenbank und Tabelle für dieses Projekt.
1. Das Wahl-Datenbankschema erstellen
Das Tabellenschema definiert die Datenstruktur. Führen Sie den folgenden SQL-Befehl in einem MySQL-Client wie MySQL Workbench oder phpMyAdmin aus. Diese Tabelle protokolliert jede Stimme mit einem automatischen Zeitstempel.
CREATE TABLE `voting` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(12) NOT NULL,
`time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Schema-Erklärung: Die Spalte id ist ein automatisch inkrementierender Primärschlüssel. Die Spalte name speichert den Namen des Kandidaten (z.B. „akbar“ oder „goldie“). Die Spalte time erfasst automatisch den Zeitstempel der Abstimmung. Die InnoDB-Engine wird aufgrund ihrer Transaktions- und Fremdschlüsselunterstützung bevorzugt.
2. Den MySQL-Treiber für Node.js installieren
Node.js benötigt einen spezifischen Treiber, um mit MySQL zu kommunizieren. Das Paket mysql2 wird gegenüber mysql empfohlen, da es native Promise-Unterstützung bietet, was zu saubererem und besser verwaltbarem Code führt. Öffnen Sie ein Terminal in Ihrem Projektverzeichnis und führen Sie den folgenden Befehl aus.
npm install mysql2Diese Installation fügt den Treiber zur package.json-Datei Ihres Projekts hinzu. Stellen Sie sicher, dass Sie sich im selben Verzeichnis wie Ihre server.js-Datei befinden, wenn Sie diesen Befehl ausführen.
3. Die Datenbankverbindung in server.js konfigurieren
Der nächste Schritt besteht darin, die Datei server.js zu bearbeiten. Erstellen Sie einen Verbindungspool zur MySQL-Datenbank mit dem installierten Treiber. Eine Pool-Konfiguration ist für die Handhabung gleichzeitiger Verbindungen effizienter als eine einzelne Verbindung.
const mysql = require('mysql2/promise');
// Einen MySQL-Verbindungspool erstellen
const pool = mysql.createPool({
host: 'localhost',
user: 'root', // Ersetzen Sie durch Ihren MySQL-Benutzernamen
password: '', // Ersetzen Sie durch Ihr MySQL-Passwort
database: 'Ihr_Datenbankname', // Ersetzen Sie durch Ihren Datenbanknamen
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});Konfigurationsdetails: Die Option connectionLimit: 10 legt die maximale Anzahl von Verbindungen im Pool fest. waitForConnections: true ermöglicht es Anfragen zu warten, wenn der Pool voll ist. queueLimit: 0 bedeutet keine Warteschlangenbeschränkung. Verwenden Sie in der Produktion immer Umgebungsvariablen, um Datenbankzugangsdaten zu speichern.
4. Funktionen zum Abrufen und Speichern von Daten erstellen
Die Anwendung benötigt zwei Hauptfunktionen. Die erste initialisiert Daten, wenn der Server startet. Die zweite verwaltet das Speichern neuer Daten, jedes Mal wenn ein Benutzer abstimmt. Die Verwendung von async/await führt im Vergleich zu Callbacks zu besser lesbarem Code.
// Globale Variable für Daten im Arbeitsspeicher
let voteCount = { akbar: 0, goldie: 0 };
// Funktion zum Initialisieren von Daten aus der Datenbank
async function initData() {
try {
const [rows] = await pool.query('SELECT `name`, COUNT(*) AS `total` FROM `voting` GROUP BY `name`');
rows.forEach(row => {
voteCount[row.name] = row.total;
});
console.log('Daten erfolgreich aus der Datenbank initialisiert.');
} catch (error) {
console.error('Fehler beim Initialisieren der Daten:', error);
}
}
// Funktion zum Hinzufügen einer neuen Stimme
async function addVote(candidateName) {
try {
await pool.query('INSERT INTO voting (name) VALUES (?)', [candidateName]);
voteCount[candidateName]++;
return true;
} catch (error) {
console.error('Fehler beim Speichern der Stimme:', error);
return false;
}
}Funktionsdetails: Die Funktion initData() verwendet eine GROUP BY-Abfrage, um die Gesamtstimmen pro Kandidat zu zählen und lädt die Ergebnisse in das voteCount-Objekt. Die Funktion addVote() verwendet eine vorbereitete Anweisung (?), um SQL-Injection zu verhindern. Beide Funktionen enthalten eine grundlegende Fehlerbehandlung mit try-catch-Blöcken.
5. Datenbankfunktionen mit Socket.io integrieren
Die Integration erfolgt innerhalb des Socket.io-Verbindungsereignisses. Wenn ein Client eine Verbindung herstellt, sendet der Server die neuesten Daten. Der Server lauscht auch auf Stimmabgabe-Ereignisse von Clients. Dieses Muster stellt sicher, dass alle Clients Echtzeit-Updates erhalten.
io.on('connection', async (socket) => {
console.log('Client verbunden');
// Aktuelle Daten an den neu verbundenen Client senden
socket.emit('updateData', voteCount);
// Stimmabgabe-Ereignis vom Client behandeln
socket.on('submitVote', async (candidate) => {
const success = await addVote(candidate);
if (success) {
// Aktualisierte Daten an ALLE verbundenen Clients senden
io.emit('updateData', voteCount);
} else {
socket.emit('voteError', 'Fehler beim Speichern der Stimme.');
}
});
});
// Daten beim Serverstart initialisieren
initData();Ereignisablauf: Erstens, wenn ein Client eine Verbindung herstellt, sendet der Server ein updateData-Ereignis mit den aktuellen Daten. Zweitens, wenn ein Client ein submitVote-Ereignis sendet, verarbeitet der Server es in der Datenbank. Bei Erfolg sendet der Server das Update an alle Clients. Bei einem Fehler erhält nur der abstimmende Client eine Fehlerbenachrichtigung.
6. Optimierung und Best Practices für die Produktion
Für eine Produktionsumgebung sollten wichtige Optimierungen berücksichtigt werden. Erstens: Verwenden Sie Umgebungsvariablen für die Datenbankkonfiguration. Zweitens: Implementieren Sie Wiederholungslogik für Datenbankverbindungen. Drittens: Ziehen Sie die Verwendung von Redis-Cache vor MySQL für Szenarien mit sehr hohem Datenverkehr in Betracht.
// Beispiel für die Verwendung von Umgebungsvariablen mit dotenv
require('dotenv').config();
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});Validieren Sie außerdem immer Client-Eingaben, bevor Sie sie in der Datenbank verarbeiten. Stellen Sie bei einer Wahlanwendung sicher, dass der empfangene Kandidatenwert einer gültigen Option entspricht.
Wenn Sie diese Schritte befolgen, verfügt Ihre Echtzeit-Node.js-Anwendung nun über einen permanenten Datenspeicher unter Verwendung einer MySQL-Datenbank. Die Codestruktur ist besser organisiert und bereit für die weitere Entwicklung.
Als nächsten Schritt können Sie Funktionen wie Benutzerauthentifizierung, Protokollierung oder komplexere Echtzeit-Datenvisualisierung hinzufügen. Konsultieren Sie immer die offizielle Node.js-Dokumentation und die mysql2-Dokumentation für Best Practices und Updates. Diese Implementierung bietet eine solide Grundlage für Echtzeit-Anwendungen, die Datenpersistenz erfordern.


