为什么 JavaScript 要与 PostgreSQL 交朋友?
\n\n如果您使用 JavaScript(尤其是 Node.js)编写代码,并且仍在生产环境中使用 MySQL,或者更糟的是使用 SQLite,那么您正在浪费金钱和精力。PostgreSQL 不仅仅是“另一个数据库”。它是数据的瑞士军刀,无所不能:从复杂的 JOIN 到 JSON 文档、全文搜索和地理查询。而 JavaScript + PostgreSQL 的组合是 Web 应用、微服务和分析领域的现代标准。
\n\n在本指南中,我们将涵盖 Node.js 开发者需要了解的所有内容:从驱动程序安装到事务、迁移和优化。没有废话——只有代码和实践。
\n\n步骤 1:安装和配置 pg 驱动程序
\n\n要使用 PostgreSQL 与 JavaScript,需要使用 pg 包——官方客户端。安装它只需一秒钟:
npm install pg\n\n现在,创建连接。有两种方法:Client(单个连接)和 Pool(连接池)。对于生产环境,始终使用 Pool——它管理连接复用,不会在高负载下拖垮数据库。
\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, // 池中最大连接数\n idleTimeoutMillis: 30000,\n connectionTimeoutMillis: 2000,\n});\n\n// 测试连接\npool.query('SELECT NOW()')\n .then(res => console.log('✅ 已连接:', res.rows[0].now))\n .catch(err => console.error('❌ 错误:', err));\n\n重要提示:切勿硬编码密码。请使用环境变量(process.env.DATABASE_URL)或密钥管理器。
步骤 2:CRUD——基础中的基础
\n\n任何应用都从 CRUD(创建、读取、更新、删除)开始。让我们逐一分析每个操作,使用 JavaScript 与 PostgreSQL。
\n\n创建表 (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('✅ 用户表已创建');\n};\n\ncreateTable();\n\nINSERT——添加数据
\n\nconst addUser = async (name, email, age) => {\n // 使用参数化查询——防止 SQL 注入!\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('✅ 已添加用户:', res.rows[0]);\n return res.rows[0];\n};\n\n// 调用示例\naddUser('安娜·彼得罗娃', 'anna@example.com', 28);\n\nSELECT——带过滤的读取
\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(`📊 找到用户数: ${res.rowCount}`);\n return res.rows;\n};\n\ngetUsers(25).then(users => console.log(users));\n\nUPDATE——更新记录
\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('⚠️ 未找到用户');\n return null;\n }\n console.log('✅ 邮箱已更新:', res.rows[0]);\n return res.rows[0];\n};\n\nDELETE——删除
\n\nconst deleteUser = async (id) => {\n const query = 'DELETE FROM users WHERE id = $1 RETURNING *';\n