Warum JavaScript und PostgreSQL ein gutes Team sind?
\n\nWenn Sie in JavaScript (insbesondere Node.js) programmieren und immer noch MySQL oder, Gott bewahre, SQLite in der Produktion verwenden, verlieren Sie Geld und Nerven. PostgreSQL ist nicht nur "eine weitere Datenbank". Es ist ein Schweizer Taschenmesser für Daten, das alles kann: von komplexen JOINs über JSON-Dokumente, Volltextsuche und Geo-Abfragen. Und die Kombination JavaScript + PostgreSQL ist der moderne Standard für Webanwendungen, Microservices und Analysen.
\n\nIn diesem Leitfaden behandeln wir alles, was ein Node.js-Entwickler wissen muss: von der Treiberinstallation bis zu Transaktionen, Migrationen und Optimierung. Kein Blabla – nur Code und Praxis.
\n\nSchritt 1: Installation und Konfiguration des pg-Treibers
\n\nFür die Arbeit mit PostgreSQL aus JavaScript wird das Paket pg verwendet – der offizielle Client. Die Installation geht in Sekunden:
npm install pg\n\nJetzt erstellen wir eine Verbindung. Es gibt zwei Ansätze: Client (eine Verbindung) und Pool (Verbindungspool). Für die Produktion verwenden Sie immer Pool – er verwaltet die Wiederverwendung von Verbindungen und legt die Datenbank bei Last nicht lahm.
\n\nconst { Pool } = require('pg');\n\nconst pool = new Pool({\n user: 'your_user',\n host: 'localhost',\n database: 'your_db',\n password: 'your_password',\n port: 5432,\n max: 20, // max. Verbindungen im Pool\n idleTimeoutMillis: 30000,\n connectionTimeoutMillis: 2000,\n});\n\n// Verbindung testen\npool.query('SELECT NOW()')\n .then(res => console.log('✅ Verbunden:', res.rows[0].now))\n .catch(err => console.error('❌ Fehler:', err));\n\nWichtig: Härten Sie niemals Passwörter ein. Verwenden Sie Umgebungsvariablen (process.env.DATABASE_URL) oder einen Secret-Manager.
Schritt 2: CRUD – die Grundlage
\n\nJede Anwendung beginnt mit CRUD (Create, Read, Update, Delete). Wir gehen jede Operation mit JavaScript und PostgreSQL durch.
\n\nTabelle erstellen (DDL)
\n\nconst createTable = async () => {\n const query = `\n CREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n name VARCHAR(100) NOT NULL,\n email VARCHAR(255) UNIQUE NOT NULL,\n age INTEGER CHECK (age > 0),\n created_at TIMESTAMP DEFAULT NOW()\n );\n `;\n await pool.query(query);\n console.log('✅ Tabelle users erstellt');\n};\n\ncreateTable();\n\nINSERT – Daten hinzufügen
\n\nconst addUser = async (name, email, age) => {\n // Verwendung parametrisierter Abfragen – Schutz vor SQL-Injection!\n const query = `\n INSERT INTO users (name, email, age)\n VALUES ($1, $2, $3)\n RETURNING *;\n `;\n const values = [name, email, age];\n const res = await pool.query(query, values);\n console.log('✅ Benutzer hinzugefügt:', res.rows[0]);\n return res.rows[0];\n};\n\n// Beispielaufruf\naddUser('Anna Petrova', 'anna@example.com', 28);\n\nSELECT – Lesen mit Filterung
\n\nconst getUsers = async (minAge = 0) => {\n const query = 'SELECT * FROM users WHERE age > $1 ORDER BY created_at DESC';\n const res = await pool.query(query, [minAge]);\n console.log(`📊 Benutzer gefunden: ${res.rowCount}`);\n return res.rows;\n};\n\ngetUsers(25).then(users => console.log(users));\n\nUPDATE – Datensatz aktualisieren
\n\nconst updateUserEmail = async (id, newEmail) => {\n const query = `\n UPDATE users\n SET email = $2, updated_at = NOW()\n WHERE id = $1\n RETURNING *;\n `;\n const res = await pool.query(query, [id, newEmail]);\n if (res.rowCount === 0) {\n console.log('⚠️ Benutzer nicht gefunden');\n return null;\n }\n console.log('✅ E-Mail aktualisiert:', res.rows[0]);\n return res.rows[0];\n};\n\nDELETE – Löschen
\n\nconst deleteUser = async (id) => {\n const query = 'DELETE FROM users WHERE id = $1 RETURNING *';\n