Node.js数据库操作指南
目录
前言
数据库操作是后端应用的核心组成部分。在 Node.js 生态中,无论是使用原生驱动(如 mysql2
、pg
、mongodb
),还是借助 ORM(Sequelize、TypeORM 等),都能高效地完成数据持久化操作。本指南将带你系统了解:
- 如何在 Node.js 中安装、配置并连接常见关系型与 NoSQL 数据库
- 各类 CRUD 操作示例,并通过代码与图解帮助理解底层流程
- 连接池与事务的使用,以及性能优化思路
- ORM 框架(Sequelize、TypeORM)如何简化工作,并演示常见模型与关联操作
环境配置与通用准备
- Node.js 版本:建议 v14 或以上(支持
async/await
)。 - 包管理器:npm 或 yarn,以下示例均使用 npm。
- 数据库服务:本地或远程安装 MySQL、PostgreSQL、MongoDB。示例中假设本地数据库已启动并可连接。
打开终端,先初始化一个 Node.js 项目:
mkdir node-db-guide
cd node-db-guide
npm init -y
安装一些通用依赖(须根据后续示例逐个安装):
npm install dotenv
npm install --save-dev nodemon
dotenv
:用于加载.env
环境变量文件,统一管理数据库连接信息等配置。nodemon
:开发阶段热重启脚本。
在项目根目录创建接口:.env
,并填入示例数据库连接配置(请根据实际情况修改):
# .env 示例
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=123456
MYSQL_DATABASE=test_db
PG_HOST=localhost
PG_PORT=5432
PG_USER=postgres
PG_PASSWORD=123456
PG_DATABASE=test_db
MONGO_URI=mongodb://localhost:27017/test_db
在项目根目录新建 config.js
,统一读取环境变量:
// config.js
require('dotenv').config();
module.exports = {
mysql: {
host: process.env.MYSQL_HOST,
port: process.env.MYSQL_PORT,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE
},
pg: {
host: process.env.PG_HOST,
port: process.env.PG_PORT,
user: process.env.PG_USER,
password: process.env.PG_PASSWORD,
database: process.env.PG_DATABASE
},
mongoUri: process.env.MONGO_URI
};
Node.js 与 MySQL
3.1 安装与连接
推荐使用 mysql2
驱动,支持 Promise API。
npm install mysql2
代码示例:mysql-connection.js
// mysql-connection.js
const mysql = require('mysql2/promise');
const config = require('./config');
async function testMySQL() {
// 1. 创建连接
const connection = await mysql.createConnection({
host: config.mysql.host,
port: config.mysql.port,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database
});
console.log('已连接到 MySQL');
// 2. 执行简单查询
const [rows] = await connection.query('SELECT NOW() AS now;');
console.log('当前时间:', rows[0].now);
// 3. 关闭连接
await connection.end();
console.log('连接已关闭');
}
testMySQL().catch(console.error);
运行:
node mysql-connection.js
输出示意:
已连接到 MySQL
当前时间: 2023-08-10T12:34:56.000Z
连接已关闭
图解:MySQL 连接流程
┌──────────────┐ ┌───────────┐
│ Node.js 应用 │──发送连接请求──▶│ MySQL 服务 │
└──────────────┘ └───────────┘
▲ │
│ 连接成功/失败 │
│◀───────────────────────┘
3.2 增删改查示例
假设已有一个名为 users
的表:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
示例代码:mysql-crud.js
// mysql-crud.js
const mysql = require('mysql2/promise');
const config = require('./config');
async function runCRUD() {
const conn = await mysql.createConnection(config.mysql);
// 插入(Create)
const [insertResult] = await conn.execute(
'INSERT INTO users (username, email) VALUES (?, ?)',
['alice', 'alice@example.com']
);
console.log('插入用户 ID:', insertResult.insertId);
// 查询(Read)
const [rows] = await conn.execute('SELECT * FROM users WHERE id = ?', [
insertResult.insertId
]);
console.log('查询结果:', rows);
// 更新(Update)
const [updateResult] = await conn.execute(
'UPDATE users SET email = ? WHERE id = ?',
['alice_new@example.com', insertResult.insertId]
);
console.log('更新受影响行数:', updateResult.affectedRows);
// 删除(Delete)
const [deleteResult] = await conn.execute(
'DELETE FROM users WHERE id = ?',
[insertResult.insertId]
);
console.log('删除受影响行数:', deleteResult.affectedRows);
await conn.end();
}
runCRUD().catch(console.error);
执行与输出示意:
node mysql-crud.js
插入用户 ID: 1
查询结果: [ { id: 1, username: 'alice', email: 'alice@example.com', created_at: 2023-08-10T12:45:00.000Z } ]
更新受影响行数: 1
删除受影响行数: 1
3.3 连接池与性能优化
单次连接在高并发场景中非常 inefficient,推荐使用连接池。
示例代码:mysql-pool.js
// mysql-pool.js
const mysql = require('mysql2/promise');
const config = require('./config');
const pool = mysql.createPool({
host: config.mysql.host,
port: config.mysql.port,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database,
waitForConnections: true,
connectionLimit: 10, // 最大连接数
queueLimit: 0
});
async function queryUsers() {
// 从连接池获取连接
const conn = await pool.getConnection();
try {
const [rows] = await conn.query('SELECT * FROM users');
console.log('所有用户:', rows);
} finally {
conn.release(); // 归还连接到池中
}
}
async function main() {
await queryUsers();
// 程序结束时可以调用 pool.end() 关闭所有连接
await pool.end();
}
main().catch(console.error);
连接池流程图(ASCII)
┌──────────────┐
│ Node.js 应用 │
└──────────────┘
│
▼
┌─────────────────┐
│ 连接池 (Pool) │
│ ┌─────────────┐ │
│ │ Connection1 │ │
│ │ Connection2 │ │
│ │ ... │ │
│ └─────────────┘ │
└─────────────────┘
▲
│
多个并发请求
好处:
- 减少频繁创建/关闭连接的开销
- 复用空闲连接,提升并发吞吐
- 可通过
connectionLimit
控制最大并发连接数,防止数据库过载
3.4 事务示例
事务用于保证一系列 SQL 操作要么全部成功,要么全部回滚,常用于银行转账等场景。
示例代码:mysql-transaction.js
// mysql-transaction.js
const mysql = require('mysql2/promise');
const config = require('./config');
async function transferFunds(fromUserId, toUserId, amount) {
const conn = await mysql.createConnection(config.mysql);
try {
// 开启事务
await conn.beginTransaction();
// 扣减转出方余额
const [res1] = await conn.execute(
'UPDATE accounts SET balance = balance - ? WHERE user_id = ?',
[amount, fromUserId]
);
if (res1.affectedRows !== 1) throw new Error('扣款失败');
// 增加转入方余额
const [res2] = await conn.execute(
'UPDATE accounts SET balance = balance + ? WHERE user_id = ?',
[amount, toUserId]
);
if (res2.affectedRows !== 1) throw new Error('收款失败');
// 提交事务
await conn.commit();
console.log('转账成功');
} catch (err) {
// 回滚事务
await conn.rollback();
console.error('转账失败,已回滚:', err.message);
} finally {
await conn.end();
}
}
transferFunds(1, 2, 100).catch(console.error);
事务流程图(ASCII)
┌────────────────────────────────┐
│ conn.beginTransaction() │
└─────────────┬──────────────────┘
│
┌──────────▼──────────┐
│ UPDATE accounts ... │
│ res1 │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ UPDATE accounts ... │
│ res2 │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ conn.commit() │
└─────────────────────┘
(若任一步失败,则执行 conn.rollback())
Node.js 与 PostgreSQL
4.1 安装与连接
使用 pg
驱动,支持 Pool 与事务。
npm install pg
示例代码:pg-connection.js
// pg-connection.js
const { Client } = require('pg');
const config = require('./config');
async function testPG() {
const client = new Client({
host: config.pg.host,
port: config.pg.port,
user: config.pg.user,
password: config.pg.password,
database: config.pg.database
});
await client.connect();
console.log('已连接到 PostgreSQL');
const res = await client.query('SELECT NOW() AS now;');
console.log('当前时间:', res.rows[0].now);
await client.end();
console.log('连接已关闭');
}
testPG().catch(console.error);
运行:
node pg-connection.js
4.2 增删改查示例
假设有一个 products
表:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price NUMERIC NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
示例代码:pg-crud.js
// pg-crud.js
const { Pool } = require('pg');
const config = require('./config');
const pool = new Pool({
host: config.pg.host,
port: config.pg.port,
user: config.pg.user,
password: config.pg.password,
database: config.pg.database,
max: 10
});
async function runCRUD() {
// 插入
const insertRes = await pool.query(
'INSERT INTO products (name, price) VALUES ($1, $2) RETURNING id',
['Apple', 3.5]
);
const productId = insertRes.rows[0].id;
console.log('插入产品 ID:', productId);
// 查询
const selectRes = await pool.query('SELECT * FROM products WHERE id = $1', [
productId
]);
console.log('查询结果:', selectRes.rows);
// 更新
const updateRes = await pool.query(
'UPDATE products SET price = $1 WHERE id = $2',
[4.0, productId]
);
console.log('更新受影响行数:', updateRes.rowCount);
// 删除
const deleteRes = await pool.query('DELETE FROM products WHERE id = $1', [
productId
]);
console.log('删除受影响行数:', deleteRes.rowCount);
await pool.end();
}
runCRUD().catch(console.error);
4.3 事务示例
示例代码:pg-transaction.js
// pg-transaction.js
const { Pool } = require('pg');
const config = require('./config');
const pool = new Pool({
host: config.pg.host,
port: config.pg.port,
user: config.pg.user,
password: config.pg.password,
database: config.pg.database,
max: 10
});
async function transferFunds(fromId, toId, amount) {
const client = await pool.connect();
try {
await client.query('BEGIN');
const res1 = await client.query(
'UPDATE accounts SET balance = balance - $1 WHERE user_id = $2',
[amount, fromId]
);
if (res1.rowCount !== 1) throw new Error('扣款失败');
const res2 = await client.query(
'UPDATE accounts SET balance = balance + $1 WHERE user_id = $2',
[amount, toId]
);
if (res2.rowCount !== 1) throw new Error('收款失败');
await client.query('COMMIT');
console.log('转账成功');
} catch (err) {
await client.query('ROLLBACK');
console.error('转账失败,已回滚:', err.message);
} finally {
client.release();
}
}
transferFunds(1, 2, 50).catch(console.error);
Node.js 与 MongoDB
5.1 安装与连接
使用官方驱动 mongodb
或 ODM mongoose
。下面优先介绍 mongodb
官方驱动。
npm install mongodb
示例代码:mongo-connection.js
// mongo-connection.js
const { MongoClient } = require('mongodb');
const config = require('./config');
async function testMongo() {
const client = new MongoClient(config.mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
await client.connect();
console.log('已连接到 MongoDB');
const db = client.db(); // 默认 test_db
const coll = db.collection('test_collection');
// 插入文档
const insertRes = await coll.insertOne({ name: 'Bob', age: 28 });
console.log('插入文档 ID:', insertRes.insertedId);
// 查询文档
const doc = await coll.findOne({ _id: insertRes.insertedId });
console.log('查询文档:', doc);
await client.close();
}
testMongo().catch(console.error);
5.2 增删改查示例
假设使用 users
集合:
示例代码:mongo-crud.js
// mongo-crud.js
const { MongoClient, ObjectId } = require('mongodb');
const config = require('./config');
async function runCRUD() {
const client = new MongoClient(config.mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
await client.connect();
const db = client.db();
const users = db.collection('users');
// 插入
const { insertedId } = await users.insertOne({
username: 'charlie',
email: 'charlie@example.com',
createdAt: new Date()
});
console.log('插入文档 ID:', insertedId);
// 查询
const user = await users.findOne({ _id: insertedId });
console.log('查询结果:', user);
// 更新
const updateRes = await users.updateOne(
{ _id: insertedId },
{ $set: { email: 'charlie_new@example.com' } }
);
console.log('更新受影响文档数:', updateRes.modifiedCount);
// 删除
const deleteRes = await users.deleteOne({ _id: insertedId });
console.log('删除受影响文档数:', deleteRes.deletedCount);
await client.close();
}
runCRUD().catch(console.error);
5.3 常见索引与查询优化
在 MongoDB 中,为了让查询更高效,往往需要在常用筛选字段上创建索引。
示例:创建索引
// mongo-index.js
const { MongoClient } = require('mongodb');
const config = require('./config');
async function createIndex() {
const client = new MongoClient(config.mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
await client.connect();
const db = client.db();
const users = db.collection('users');
// 在 username 字段上创建唯一索引
await users.createIndex({ username: 1 }, { unique: true });
console.log('已在 username 字段创建唯一索引');
await client.close();
}
createIndex().catch(console.error);
查询优化思路
- 索引覆盖:只返回索引字段,无需回表。
- 分页查询:避免使用
skip
在大数据量时性能下降,推荐基于索引值做范围查询。 - 聚合管道:使用
$match
、$project
、$group
等聚合操作,以减少传输数据量并利用索引。
使用 ORM:Sequelize 示例
Sequelize 是 Node.js 中较为流行的 ORM,可同时支持 MySQL、PostgreSQL、SQLite 等。
6.1 安装与配置
npm install sequelize mysql2
示例代码:sequelize-setup.js
// sequelize-setup.js
const { Sequelize, DataTypes } = require('sequelize');
const config = require('./config');
const sequelize = new Sequelize(
config.mysql.database,
config.mysql.user,
config.mysql.password,
{
host: config.mysql.host,
port: config.mysql.port,
dialect: 'mysql',
logging: false
}
);
async function testSequelize() {
try {
await sequelize.authenticate();
console.log('Sequelize 已连接到数据库');
// 定义模型
const User = sequelize.define('User', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
username: { type: DataTypes.STRING(50), allowNull: false, unique: true },
email: { type: DataTypes.STRING(100), allowNull: false }
}, {
tableName: 'users',
timestamps: true, // 自动添加 createdAt 和 updatedAt
underscored: true // 字段名使用下划线风格
});
// 同步模型(如果表不存在则创建)
await User.sync({ alter: true });
console.log('User 模型已同步');
// 创建记录
const user = await User.create({ username: 'david', email: 'david@example.com' });
console.log('创建用户:', user.toJSON());
// 查询
const users = await User.findAll();
console.log('所有用户:', users.map(u => u.toJSON()));
// 更新
await User.update({ email: 'david_new@example.com' }, { where: { id: user.id } });
console.log('已更新用户 email');
// 删除
await User.destroy({ where: { id: user.id } });
console.log('已删除用户');
} catch (err) {
console.error('Sequelize 操作失败:', err);
} finally {
await sequelize.close();
}
}
testSequelize();
6.2 定义模型与同步
在实际项目中,一般会将模型定义与 Sequelize 实例分开,方便维护。推荐目录结构:
models/
index.js # Sequelize 实例与初始化
user.js # User 模型定义
app.js # 应用主入口
models/index.js
const { Sequelize } = require('sequelize');
const config = require('../config');
const sequelize = new Sequelize(
config.mysql.database,
config.mysql.user,
config.mysql.password,
{
host: config.mysql.host,
port: config.mysql.port,
dialect: 'mysql',
logging: false
}
);
const db = {};
db.sequelize = sequelize;
db.Sequelize = Sequelize;
// 导入模型
db.User = require('./user')(sequelize, Sequelize);
module.exports = db;
models/user.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
username: { type: DataTypes.STRING(50), allowNull: false, unique: true },
email: { type: DataTypes.STRING(100), allowNull: false }
}, {
tableName: 'users',
timestamps: true,
underscored: true
});
return User;
};
app.js
// app.js
const db = require('./models');
async function main() {
try {
await db.sequelize.authenticate();
console.log('已连接到数据库 (Sequelize)');
// 同步所有模型
await db.sequelize.sync({ alter: true });
console.log('模型同步完成');
// 创建用户示例
const newUser = await db.User.create({ username: 'eve', email: 'eve@example.com' });
console.log('创建用户:', newUser.toJSON());
} catch (err) {
console.error(err);
} finally {
await db.sequelize.close();
}
}
main();
6.3 增删改查示例
在 Sequelize 中,常用方法包括:
Model.create()
:插入单条记录Model.findAll({ where: {...} })
:查询多条Model.findOne({ where: {...} })
:查询单条Model.update({ fields }, { where: {...} })
:更新Model.destroy({ where: {...} })
:删除
示例已在上节中演示,读者可在控制台运行并观察效果。
6.4 关联关系与事务
关联关系示例
假设有两个模型:User
和 Post
,一对多关系,一个用户可有多篇文章。
定义模型:models/post.js
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
title: { type: DataTypes.STRING(200), allowNull: false },
content: { type: DataTypes.TEXT, allowNull: false },
userId: { type: DataTypes.INTEGER, allowNull: false }
}, {
tableName: 'posts',
timestamps: true,
underscored: true
});
return Post;
};
在 models/index.js
中配置关联:
const db = {};
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = require('./user')(sequelize, Sequelize);
db.Post = require('./post')(sequelize, Sequelize);
// 定义关联
db.User.hasMany(db.Post, { foreignKey: 'userId', as: 'posts' });
db.Post.belongsTo(db.User, { foreignKey: 'userId', as: 'author' });
module.exports = db;
使用关联:
// association-example.js
const db = require('./models');
async function associationDemo() {
await db.sequelize.sync({ alter: true });
// 创建用户与文章
const user = await db.User.create({ username: 'frank', email: 'frank@example.com' });
await db.Post.create({ title: 'Hello World', content: 'This is first post.', userId: user.id });
// 查询用户并包含文章
const result = await db.User.findOne({
where: { id: user.id },
include: [{ model: db.Post, as: 'posts' }]
});
console.log('用户与其文章:', JSON.stringify(result, null, 2));
await db.sequelize.close();
}
associationDemo().catch(console.error);
事务示例
// sequelize-transaction.js
const db = require('./models');
async function transactionDemo() {
const t = await db.sequelize.transaction();
try {
const user = await db.User.create({ username: 'grace', email: 'grace@example.com' }, { transaction: t });
await db.Post.create({ title: 'Transaction Post', content: 'Using transaction', userId: user.id }, { transaction: t });
// 提交
await t.commit();
console.log('事务提交成功');
} catch (err) {
await t.rollback();
console.error('事务回滚:', err);
} finally {
await db.sequelize.close();
}
}
transactionDemo().catch(console.error);
使用 ORM:TypeORM 示例
TypeORM 是另一个流行的 ORM,尤其在 TypeScript 项目中表现优异。这里以 JavaScript(可扩展到 TS)示例。
7.1 安装与配置
npm install typeorm reflect-metadata mysql2
在 tsconfig.json
中需要启用实验性装饰器和元数据:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2019",
"module": "commonjs",
"outDir": "dist",
"rootDir": "src"
// …其他选项
}
}
示例目录:
src/
entity/
User.js
index.js
ormconfig.json
ormconfig.json
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "123456",
"database": "test_db",
"synchronize": true,
"logging": false,
"entities": ["src/entity/**/*.js"]
}
7.2 定义实体与数据库同步
示例实体:src/entity/User.js
// src/entity/User.js
const { EntitySchema } = require('typeorm');
module.exports = new EntitySchema({
name: 'User',
tableName: 'users',
columns: {
id: {
type: 'int',
primary: true,
generated: true
},
username: {
type: 'varchar',
length: 50,
unique: true
},
email: {
type: 'varchar',
length: 100
},
createdAt: {
type: 'timestamp',
createDate: true
},
updatedAt: {
type: 'timestamp',
updateDate: true
}
}
});
src/index.js
// src/index.js
require('reflect-metadata');
const { createConnection, getRepository } = require('typeorm');
async function main() {
const connection = await createConnection();
console.log('已连接到数据库 (TypeORM)');
const userRepo = getRepository('User');
// 插入
const user = userRepo.create({ username: 'hannah', email: 'hannah@example.com' });
await userRepo.save(user);
console.log('插入用户:', user);
// 查询
const users = await userRepo.find();
console.log('所有用户:', users);
// 更新
user.email = 'hannah_new@example.com';
await userRepo.save(user);
console.log('更新用户:', user);
// 删除
await userRepo.delete(user.id);
console.log('删除用户 ID:', user.id);
await connection.close();
}
main().catch(console.error);
7.3 增删改查示例
在上节代码中,常用操作如下:
repo.create({ … })
:生成实体实例repo.save(entity)
:插入或更新(根据主键是否存在)repo.find()
:查询所有记录repo.findOne({ where: { … } })
:条件查询单条repo.delete(id)
:通过主键删除
7.4 关联关系示例
假设有 Post
实体与 User
实体,一对多关系:
src/entity/Post.js
const { EntitySchema } = require('typeorm');
module.exports = new EntitySchema({
name: 'Post',
tableName: 'posts',
columns: {
id: {
type: 'int',
primary: true,
generated: true
},
title: {
type: 'varchar',
length: 200
},
content: {
type: 'text'
}
},
relations: {
author: {
type: 'many-to-one',
target: 'User',
joinColumn: { name: 'userId' },
inverseSide: 'posts'
}
}
});
更新 src/entity/User.js
添加关联:
module.exports = new EntitySchema({
name: 'User',
tableName: 'users',
columns: {
id: { type: 'int', primary: true, generated: true },
username: { type: 'varchar', length: 50, unique: true },
email: { type: 'varchar', length: 100 },
createdAt: { type: 'timestamp', createDate: true },
updatedAt: { type: 'timestamp', updateDate: true }
},
relations: {
posts: {
type: 'one-to-many',
target: 'Post',
inverseSide: 'author'
}
}
});
更新 src/index.js
查询示例:
// src/index.js
require('reflect-metadata');
const { createConnection, getRepository } = require('typeorm');
async function main() {
const connection = await createConnection();
const userRepo = getRepository('User');
const postRepo = getRepository('Post');
// 创建用户
const user = userRepo.create({ username: 'ivan', email: 'ivan@example.com' });
await userRepo.save(user);
// 创建文章
const post = postRepo.create({
title: 'TypeORM Guide',
content: 'This is a post using TypeORM.',
author: user
});
await postRepo.save(post);
// 查询用户及其文章
const result = await userRepo.findOne({
where: { id: user.id },
relations: ['posts']
});
console.log('用户及其文章:', JSON.stringify(result, null, 2));
await connection.close();
}
main().catch(console.error);
常见问题与性能调优
连接超时或频繁断开
- 使用连接池替代单次连接。
- 在生产环境设置合理的
connectionLimit
或 pool 的idleTimeout
。
SQL 注入风险
- 强烈建议使用参数化查询(
?
或$1
语法),不要直接拼接字符串。
- 强烈建议使用参数化查询(
OOM / 大结果集拉取
- 对于大量数据,使用分页查询(
LIMIT/OFFSET
或基于主键范围查询)。 - Node.js 中对大结果集可使用流式查询(如
mysql2
的queryStream()
)。
- 对于大量数据,使用分页查询(
事务死锁
- 控制事务粒度,尽量在同一顺序访问表。
- 避免在事务中做长时间操作(如外部 API 调用)。
MongoDB 大数据查询性能
- 创建合适的索引,避免全表扫描;
- 使用聚合管道(
aggregation pipeline
)代替多次拉取。
ORM 性能开销
- ORM 便于开发,但对于极端性能场景,建议使用原生 SQL;
- 在 Sequelize/TypeORM 中,尽量使用批量操作(
bulkCreate
、saveMany
)减少网络往返。
总结
本文围绕 Node.js 与几种常见数据库(MySQL、PostgreSQL、MongoDB)以及两种主流 ORM 框架(Sequelize、TypeORM)进行了全面介绍:
- MySQL 驱动与连接池:包括基础 CRUD、连接池与事务示例。
- PostgreSQL 驱动示例:使用
pg
驱动完成类似操作。 - MongoDB 官方驱动:完成文档的插入、查询、更新、删除,并说明索引优化思路。
- Sequelize ORM:从安装、模型定义、增删改查到事务与关联操作全面举例。
- TypeORM 示例:同样展示创建连接、实体定义与关联映射。
- 性能与常见问题:给出连接超时、注入风险、大结果集处理与事务死锁等优化建议。
通过本文内容,您可以根据实际项目需求选择合适的数据库驱动或 ORM 工具,结合连接池与事务等技术,实现高效、可靠的数据库访问层。同时,图解与代码示例能够帮助您快速理解底层工作原理,并掌握常见坑点与优化思路。
评论已关闭