当前位置: 首页 > article >正文

不同的数据库操作方式:MongoDB(NoSQL)和 MySQL/SQL

这两种写法分别使用了不同的数据库操作方式:第一种是 MongoDB(NoSQL) 的写法,第二种是 MySQL/SQL 的写法。我们来对比它们的区别,并给出优化建议。


1. MongoDB(NoSQL)写法

const user = await db.collection('users').findOne({ email });
if (!user) {return res.status(404).json({ status: 'fail', message: '用户不存在' });
}
await db.collection('users').updateOne({ email }, { $set: { emailVerified: true } });

特点

  • 异步 await 语法:使用 Promise 风格,代码更清晰。
  • MongoDB 查询方式
    • findOne({ email }):查询单个用户(基于 email 字段)。
    • updateOne({ email }, { $set: { emailVerified: true } }):更新 emailVerified 字段。
  • 返回 JSON 响应:如果用户不存在,返回 404 状态码和错误信息。

优化建议

  1. 增加错误处理
    try {const user = await db.collection('users').findOne({ email });if (!user) {return res.status(404).json({ status: 'fail', message: '用户不存在' });}await db.collection('users').updateOne({ email }, { $set: { emailVerified: true } });res.json({ status: 'success', message: '邮箱验证成功' });
    } catch (err) {res.status(500).json({ status: 'error', message: '服务器错误' });
    }
    
  2. 使用 $exists 检查字段(如果需要):
    const user = await db.collection('users').findOne({ email, emailVerified: { $exists: true } });
    

2. MySQL/SQL 写法

db.query(`SELECT * FROM users WHERE openid = ?`, [openid], (err, results) => {if (err) throw err;if (results.length === 0) {return res.status(404).json({ status: 'fail', message: '用户不存在' });}db.query(`UPDATE users SET emailVerified = 1 WHERE openid = ?`, [openid], (err) => {if (err) throw err;res.json({ status: 'success', message: '邮箱验证成功' });});
});

特点

  • 回调函数风格db.query(sql, [params], callback),容易形成“回调地狱”。
  • SQL 语句
    • SELECT * FROM users WHERE openid = ?:查询用户(? 是参数占位符)。
    • UPDATE users SET emailVerified = 1 WHERE openid = ?:更新 emailVerified 字段(1 表示 true)。
  • 错误处理if (err) throw err; 直接抛出错误(不够友好)。

优化建议

  1. 改用 async/await(推荐)
    try {const [rows] = await db.query(`SELECT * FROM users WHERE openid = ?`, [openid]);if (rows.length === 0) {return res.status(404).json({ status: 'fail', message: '用户不存在' });}await db.query(`UPDATE users SET emailVerified = 1 WHERE openid = ?`, [openid]);res.json({ status: 'success', message: '邮箱验证成功' });
    } catch (err) {res.status(500).json({ status: 'error', message: '服务器错误' });
    }
    
  2. 使用 mysql2/promiseknex.js 等库,避免回调写法:
    import mysql from 'mysql2/promise';
    const db = await mysql.createConnection({ ... });
    

3. 主要区别对比

特性MongoDB(NoSQL)MySQL(SQL)
查询方式findOne({ email })SELECT * FROM users WHERE email = ?
更新方式updateOne({ email }, { $set: { ... } })UPDATE users SET emailVerified = 1 WHERE email = ?
错误处理try/catch回调或 try/catch(推荐)
异步风格Promiseawait回调或 Promise(推荐 mysql2/promise
适用场景非结构化数据(JSON)结构化数据(关系型数据库)

4. 最终推荐写法

MongoDB(推荐)

try {const user = await db.collection('users').findOne({ email });if (!user) {return res.status(404).json({ status: 'fail', message: '用户不存在' });}await db.collection('users').updateOne({ email }, { $set: { emailVerified: true } });res.json({ status: 'success', message: '邮箱验证成功' });
} catch (err) {res.status(500).json({ status: 'error', message: '服务器错误' });
}

MySQL(推荐 async/await

try {const [rows] = await db.query(`SELECT * FROM users WHERE email = ?`, [email]);if (rows.length === 0) {return res.status(404).json({ status: 'fail', message: '用户不存在' });}await db.query(`UPDATE users SET emailVerified = 1 WHERE email = ?`, [email]);res.json({ status: 'success', message: '邮箱验证成功' });
} catch (err) {res.status(500).json({ status: 'error', message: '服务器错误' });
}

总结

  • MongoDB 适合 JSON 数据,查询方式更灵活。
  • MySQL 适合结构化数据,推荐 async/await 避免回调地狱。
  • 错误处理 应该统一用 try/catch,返回合适的 HTTP 状态码(404500)。
  • SQL 注入防护:MySQL 使用 ? 占位符,MongoDB 自动防注入。

如果你的项目已经使用 MySQL,可以考虑 ORM(如 Sequelize、TypeORM)Query Builder(如 Knex.js) 来简化 SQL 操作。

http://www.lryc.cn/news/2397866.html

相关文章:

  • 0-EATSA-GNN:基于图节点分类师生机制的边缘感知和两阶段注意力增强图神经网络(code)
  • 大数据学习(124)-spark数据倾斜
  • 配置前端控制器
  • lua注意事项
  • Git的三种合并方式
  • 从零到一:我的技术博客导航(持续更新)
  • SpringBoot整合Flowable【08】- 前后端如何交互
  • DM达梦数据库开启SQL日志记录功能
  • 00 QEMU源码分析中文注释与架构讲解(v8.2.4版本)
  • 【五模型时间序列预测对比】Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN
  • 深入了解MCP基础与架构
  • 实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.13 R语言解题
  • 怎么选择合适的高防IP
  • 【java面试】MySQL篇
  • 贪心算法应用:欧拉路径(Fleury算法)详解
  • 【算法设计与分析】实验——二维0-1背包问题(算法分析题:算法思路),独立任务最优调度问题(算法实现题:实验过程,描述,小结)
  • P12592题解
  • ffmpeg命令(二):分解与复用命令
  • 【Git】View Submitted Updates——diff、show、log
  • deepseek原理和项目实战笔记2 -- deepseek核心架构
  • 在 MATLAB 2015a 中如何调用 Python
  • 房屋租赁系统 Java+Vue.js+SpringBoot,包括房屋类型、房屋信息、预约看房、合同信息、房屋报修、房屋评价、房主管理模块
  • 华为OD机试真题——生成哈夫曼树(2025B卷:100分)Java/python/JavaScript/C/C++/GO六种最佳实现
  • react与vue的渲染原理
  • 我提出结构学习的思路,意图用结构学习代替机器学习
  • Outbox模式:确保微服务间数据可靠交换的设计方案
  • 数据可视化的定义和类型
  • sqlite-vec:谁说SQLite不是向量数据库?
  • Redis最佳实践——性能优化技巧之监控与告警详解
  • R3GAN训练自己的数据集