当前位置: 首页 > 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 操作。

相关文章:

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

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

0-EATSA-GNN:基于图节点分类师生机制的边缘感知和两阶段注意力增强图神经网络(code)

code:https://github.com/afofanah/EATSA-GNN. 文章目录 Abstract1. Introduction1.1.动态图场景1.2.EATSA-GNN框架的背景化2. Background2.1.GNN边缘感知挑战2.2.GNN的可解释性问题2.3.EATSA-GNN可解释性3. Related worksAbstract 图神经网络(GNNs)从根本上改变了我们处理和…...

大数据学习(124)-spark数据倾斜

🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...

配置前端控制器

一、DispatcherServlet 详解 在使用 Spring MVC 框架构建 Web 应用时,DispatcherServlet是整个请求处理流程的核心。本文将深入解析DispatcherServlet的作用、工作原理及其在 Spring MVC 架构中的关键地位。 1.DispatcherServlet 是什么? DispatcherS…...

lua注意事项

感觉是lua的一大坑啊,它还不如函数内部就局部变量呢 注意函数等内部,全部给加上local得了...

Git的三种合并方式

在 Gitee(码云)中合并分支主要有三种方式:​普通合并(Merge Commit)、压缩合并(Squash Merge)​和变基合并(Rebase Merge)​。每种方式适用于不同的场景,各有…...

从零到一:我的技术博客导航(持续更新)

作者:冰茶 最后更新:2025年6月3日 本文收录了我的C#编程学习心得与技术探索,将持续更新 前言 作为一名.NET开发者,C#语言的学习与探索一直是我技术成长的核心路径。本文集整理了我在C#学习过程中的思考与实践,希望能够…...

SpringBoot整合Flowable【08】- 前后端如何交互

引子 在第02篇中,我通过 Flowable-UI 绘制了一个简单的绩效流程,并在后续章节中基于这个流程演示了 Flowable 的各种API调用。然而,在实际业务场景中,如果要求前端将用户绘制的流程文件发送给后端再进行解析处理,这种…...

DM达梦数据库开启SQL日志记录功能

DM达梦数据库开启SQL日志记录功能 配置SQL日志(非必须的配置步骤,与主备集群配置无关,如果没有需求可以跳过配置SQL日志) sqllog.ini 配置文件用于SQL日志的配置,当且仅当 INI(dm.ini) 参数 SV…...

00 QEMU源码分析中文注释与架构讲解(v8.2.4版本)

QEMU-v8.2.4源码中文注释与架构讲解 文档会不定期更新 注释作者将狼才鲸创建日期2025-05-30更新日期2025-06-02 CSDN阅读地址:QEMU源码中文注释与架构讲解Gitee源码仓库地址:才鲸嵌入式/qemu 一、前言 其它参考教程的网址: QEMU 源码目录…...

【五模型时间序列预测对比】Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN

【五模型时间序列预测对比】Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN 目录 【五模型时间序列预测对比】Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Transformer-LSTM、Transformer、CNN-LSTM、LSTM、…...

深入了解MCP基础与架构

一、引言 在人工智能技术以指数级速度渗透各行业领域的今天,我们正站在一个关键的技术拐点。当ChatGPT月活突破亿级、Gemini Pro实现多模态实时交互、Claude 3.5 Sonnet突破百万上下文长度,这些里程碑事件背后,一个崭新的大门逐步打开&#…...

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.13 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.13 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图。 dataframe<-data.frame( yc(36,18,30,39,20…...

怎么选择合适的高防IP

选择合适的高防IP需要综合考虑业务需求、防护能力、服务稳定性、成本效益等多方面因素。以下是从多个权威来源整理的关键要点&#xff0c;帮助您做出科学决策&#xff1a; 一、明确业务需求 业务类型与规模 网站/应用类&#xff1a;需支持HTTP/HTTPS协议&#xff0c;并配置域名…...

【java面试】MySQL篇

MySQL篇 一、总体结构二、优化&#xff08;一&#xff09;定位慢查询1.1 开源工具1.2Mysql自带的慢日志查询1.3 总结 &#xff08;二&#xff09;定位后优化2.1 优化2.2 总结 &#xff08;三&#xff09;索引3.1 索引3.2 索引底层数据结构——B树3.3 总结 &#xff08;四&#…...

贪心算法应用:欧拉路径(Fleury算法)详解

Java中的贪心算法应用&#xff1a;欧拉路径&#xff08;Fleury算法&#xff09;详解 一、欧拉路径与欧拉回路基础 1.1 基本概念 欧拉路径&#xff08;Eulerian Path&#xff09;是指在一个图中&#xff0c;经过图中每一条边且每一条边只经过一次的路径。如果这条路径的起点和…...

【算法设计与分析】实验——二维0-1背包问题(算法分析题:算法思路),独立任务最优调度问题(算法实现题:实验过程,描述,小结)

说明&#xff1a;博主是大学生&#xff0c;有一门课是算法设计与分析&#xff0c;这是博主记录课程实验报告的内容&#xff0c;题目是老师给的&#xff0c;其他内容和代码均为原创&#xff0c;可以参考学习&#xff0c;转载和搬运需评论吱声并注明出处哦。 要求&#xff1a;3-…...

P12592题解

题目传送门 思路 由于题目中说了可以任意交换两个字符的位置&#xff0c;我们只需要判断这个字符串是否满足回文串的条件即可。 代码&#xff1a; #include<bits/stdc.h> using namespace std; int a[30]; int main(){int T;cin>>T;while(T--){fill(a,a29,0);/…...

ffmpeg命令(二):分解与复用命令

分解&#xff08;Demuxing&#xff09; 提取视频流&#xff08;不含音频&#xff09; ffmpeg -i input.mp4 -an -vcodec copy video.h264-an&#xff1a;去掉音频 -vcodec copy&#xff1a;拷贝视频码流&#xff0c;不重新编码 提取音频流&#xff08;不含视频&#xff09…...

【Git】View Submitted Updates——diff、show、log

在 Git 中查看更新的内容&#xff08;即工作区、暂存区或提交之间的差异&#xff09;是日常开发中的常见操作。以下是常用的命令和场景说明&#xff1a; 文章目录 1、查看工作区与暂存区的差异2、查看提交历史中的差异3、查看工作区与最新提交的差异4、查看两个提交之间的差异5…...

deepseek原理和项目实战笔记2 -- deepseek核心架构

混合专家&#xff08;MoE&#xff09; ​​混合专家&#xff08;Mixture of Experts, MoE&#xff09;​​ 是一种机器学习模型架构&#xff0c;其核心思想是通过组合多个“专家”子模型&#xff08;通常为小型神经网络&#xff09;来处理不同输入&#xff0c;从而提高模型的容…...

在 MATLAB 2015a 中如何调用 Python

在 MATLAB 2015a 中调用 Python 可通过系统命令调用、.NET 交互层包装、MEX 接口间接桥接、环境变量配置四种方式&#xff0c;但因该版本对 Python 支持有限&#xff0c;主要依赖的是系统命令调用与间接脚本交互。其中&#xff0c;通过 system() 函数调用 Python 脚本是最简单且…...

房屋租赁系统 Java+Vue.js+SpringBoot,包括房屋类型、房屋信息、预约看房、合同信息、房屋报修、房屋评价、房主管理模块

房屋租赁系统 JavaVue.jsSpringBoot&#xff0c;包括房屋类型、房屋信息、预约看房、合同信息、房屋报修、房屋评价、房主管理模块 百度云盘链接&#xff1a;https://pan.baidu.com/s/1KmwOFzN9qogyaLQei3b6qw 密码&#xff1a;l2yn 摘 要 社会的发展和科学技术的进步&#xf…...

华为OD机试真题——生成哈夫曼树(2025B卷:100分)Java/python/JavaScript/C/C++/GO六种最佳实现

2025 B卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》 华为OD机试真题《生成…...

react与vue的渲染原理

vue&#xff1a;响应式驱动模板编译 &#xff08;1&#xff09;模板编译 将模板&#xff08;.vue 文件或 HTML 模板&#xff09;编译为 渲染函数&#xff08;Render Function&#xff09;&#xff1b; &#xff08;2&#xff09;响应式依赖收集 初始化时&#xff0c;通过 Ob…...

我提出结构学习的思路,意图用结构学习代替机器学习

我提出结构学习的思路&#xff0c;意图用结构学习代替机器学习 1.机器学习的本质和缺点 机器学习的规律是设计算法、用数据训练算法、让算法学会产生正确的数据回答问题&#xff0c;其缺点在于&#xff0c;需要大规模训练数据和巨大算力还其次&#xff0c;机器学习不能产生智…...

Outbox模式:确保微服务间数据可靠交换的设计方案

https://debezium.io/blog/2019/02/19/reliable-microservices-data-exchange-with-the-outbox-pattern/ Outbox模式是一种在微服务架构中确保数据更改和消息/事件发布之间可靠性的设计模式。它解决了在更新数据库和发送消息这两个独立操作中可能出现的不一致问题&#xff08;…...

数据可视化的定义和类型

数据可视化是一种将数据转换为图形或视觉表示的方法。想象一下&#xff0c;你面前有一堆数字和表格&#xff0c;看着这些&#xff0c;可能会让人头大。数据可视化就像是给这些枯燥的数字画上一幅画。它用图表、地图和各种有趣的图形&#xff0c;帮我们把难懂的数字变得容易看懂…...

sqlite-vec:谁说SQLite不是向量数据库?

sqlite-vec 是一个 SQLite 向量搜索插件&#xff0c;具有以零依赖、轻量级、跨平台和高效 KNN 搜索等优势&#xff0c;是本地化向量检索&#xff08;例如 RAG&#xff09;、轻量级 AI 应用以及边缘计算等场景的理想工具。 sqlite-vec 使用纯 C 语言实现&#xff0c;零外部依赖…...

Redis最佳实践——性能优化技巧之监控与告警详解

Redis 在电商应用的性能优化技巧之监控与告警全面详解 一、监控体系构建 1. 核心监控指标矩阵 指标类别关键指标计算方式/说明健康阈值&#xff08;参考值&#xff09;内存相关used_memoryINFO Memory 获取不超过 maxmemory 的 80%mem_fragmentation_ratio内存碎片率 used_m…...