Node.js SQL数据库:MySQL/PostgreSQL集成

引言:SQL数据库与Sequelize------关系型持久化的结构化力量

欢迎继续《Node.js 服务端开发》专栏的第四个模块!在上篇文章《MongoDB基础与Mongoose ODM》中,我们深入了MongoDB 8.2的安装、Schema模型定义和CRUD操作的Mongoose 8.19.2实践,帮助你掌握NoSQL的灵活性。现在,让我们转向关系型数据库(RDBMS):集成MySQL和PostgreSQL,使用Sequelize ORM。这不仅仅是存储结构化数据,更是处理关系、事务和优化的实践,帮助你从非结构化转向 ACID 保证的应用,如电商或金融系统。

随着Node.js Current版本25.0.0的成熟(于2025年10月15日发布,由@targos等贡献)和LTS版本22.21.0 'Jod'的稳定支持,Sequelize的最新版本7.2.0(于2025年9月15日发布)提供了更强劲的性能,如增强的TypeScript支持和PostgreSQL 17兼容。

Sequelize的历史源于2010年,由Sascha Depold创建,作为Node.js的ORM,支持多种方言。 从v1的基 pp 本查询,到v7.2.0的异步迁移和连接池优化,它已成为Express生态的标准。 为什么Sequelize?它抽象SQL,提供迁移、事务和池化,简化MySQL/PostgreSQL集成。 在2025年,v7.2.0的PostgreSQL 17支持和AI辅助查询,让它在企业级应用中闪耀。 准备好你的Node环境,让我们从安装开始,实践一个用户管理应用。

Sequelize ORM的使用:连接与模型定义

Sequelize是Node.js的ORM,支持MySQL、PostgreSQL等,抽象SQL为JS API。

安装Sequelize

npm install sequelize@7.2.0 mysql2 pg pg-hstore(mysql2 for MySQL, pg for PostgreSQL)。

连接(index.js):

javascript 复制代码
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('mydb', 'user', 'pass', {
  host: 'localhost',
  dialect: 'mysql'  // 或 'postgres'
});

sequelize.authenticate().then(() => console.log('Connected')).catch(err => console.error(err));

深度剖析:dialect指定方言,sequelize.sync()自动创建表。 历史:v1简单连接,v7.2.0添加异步authenticate。 性能:用环境变量配置。 误区:忽略dialect导致错误。

模型定义(user.js):

javascript 复制代码
const { DataTypes } = require('sequelize');
const User = sequelize.define('User', {
  id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
  name: { type: DataTypes.STRING, allowNull: false },
  email: { type: DataTypes.STRING, unique: true, allowNull: false },
  age: { type: DataTypes.INTEGER, validate: { min: 18 } }
}, { tableName: 'users', timestamps: true });

module.exports = User;

深度:define创建模型,timestamps添加createdAt/updatedAt。 validate内置验证。

迁移脚本:数据库版本控制

迁移是Sequelize的CLI工具,管理schema变更。

安装CLI

npm install --save-dev sequelize-cli@6.6.2。 npx sequelize-cli init创建config/migrations/models。

config/config.json:

json 复制代码
{
  "development": {
    "username": "user",
    "password": "pass",
    "database": "mydb",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

创建迁移:npx sequelize-cli migration:generate --name create-users

migrations/xxx-create-users.js:

javascript 复制代码
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('users', {
      id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
      name: { type: Sequelize.STRING, allowNull: false },
      email: { type: Sequelize.STRING, unique: true, allowNull: false },
      age: { type: Sequelize.INTEGER },
      createdAt: { type: Sequelize.DATE, allowNull: false },
      updatedAt: { type: Sequelize.DATE, allowNull: false }
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('users');
  }
};

运行:npx sequelize-cli db:migrate

深度剖析:up应用变更,down回滚。 历史:v2引入CLI,v7.2.0优化异步迁移。 性能:批量迁移减停机。误区:忽略down导致不可逆。

最佳实践:用seeders填充数据,如npx sequelize-cli seed:generate。

事务处理:保证数据一致性

事务确保操作原子性。

示例:

javascript 复制代码
async function transferMoney(fromId, toId, amount) {
  const t = await sequelize.transaction();

  try {
    await Account.update({ balance: Sequelize.literal(`balance - ${amount}`) }, { where: { id: fromId }, transaction: t });
    await Account.update({ balance: Sequelize.literal(`balance + ${amount}`) }, { where: { id: toId }, transaction: t });
    await t.commit();
  } catch (err) {
    await t.rollback();
    throw err;
  }
}

深度剖析:transaction创建事务,commit/rollback管理。 隔离级别:{ isolationLevel: Transaction.ISOLATION_LEVELS.READ_COMMITTED }。 性能:事务锁表,短事务优。误区:嵌套事务需managed模式。

最佳实践:用CLS (Continuation Local Storage)跨请求事务。

连接池配置:高效资源管理

连接池复用连接,减开销。

配置:

javascript 复制代码
const sequelize = new Sequelize('mydb', 'user', 'pass', {
  host: 'localhost',
  dialect: 'mysql',
  pool: {
    max: 10,  // 最大连接
    min: 0,   // 最小
    acquire: 30000,  // 获取超时
    idle: 10000      // 空闲超时
  }
});

深度剖析:max限并发,idle释放闲置。 历史:v3引入池,v7.2.0优化动态调整。 性能:调max匹配负载,monitor sequelize.connectionManager.pool.size。 误区:过大max耗资源。

最佳实践:云如RDS用外部池;2025年,v7.2.0支持AI调优池。

MySQL vs PostgreSQL:2025对比与选择

以下表格总结:

维度 MySQL (8.0+) PostgreSQL (17+)
存储引擎 InnoDB默认,事务支持 内置事务,MVCC
JSON支持 好,内置函数 优秀,JSONB二进制
扩展性 复制/分片 扩展插件如PostGIS
性能 读重载优 复杂查询优
Sequelize 好支持 优秀,GIS等

深度:PostgreSQL标准合规高,MySQL社区大。 2025趋势:PostgreSQL在AI向量搜索领先。

高级主题:关联、钩子与2025优化

  • 关联:User.hasMany(Post)关系。
  • 钩子:User.beforeCreate(async (user) => user.email = user.email.toLowerCase())。
  • 2025优化:v7.2.0的异步池,MySQL 8.0的JSON表。 趋势:Sequelize with Prisma混合。

结语:Sequelize,SQL集成的桥梁

通过Sequelize 7.2.0的使用、迁移、事务和池配置,你已掌握MySQL/PostgreSQL集成。 从2010起源,到2025的优化,它让Node.js应用更结构化。

相关推荐
咖啡の猫6 小时前
Vue收集表单数据
前端·javascript·vue.js
知识分享小能手6 小时前
uni-app 入门学习教程,从入门到精通, uni-app常用API的详细语法知识点(上)(5)
前端·javascript·vue.js·学习·微信小程序·小程序·uni-app
大杯咖啡6 小时前
一篇文章搞懂,浏览器强缓存以及协商缓存
前端·javascript
王六岁6 小时前
# 🐍 前端开发 0 基础学 Python 入门指南: Python 元组和映射类型深入指南
前端·javascript·python
_志哥_6 小时前
多行文本超出,中间显示省略号的终极方法(适配多语言)
前端·javascript·vue.js
王六岁6 小时前
# 🐍 前端开发 0 基础学 Python 入门指南:常用的数据类型和列表
前端·javascript·python
1_2_3_6 小时前
神级JS API,谁用谁好用
前端·javascript
用户6600676685396 小时前
从送花表白实例读懂 JavaScript 对象字面量与代理模式
javascript
我是日安6 小时前
从零到一打造 Vue3 响应式系统 Day 29 - readonly:数据保护实现
前端·javascript·vue.js