MongoDB是一款基于文档模型的NoSQL数据库,它用BSON格式存储数据,每条记录是一个文档,不需要预先定义表结构。与传统关系型数据库把数据拆进多张表不同,MongoDB允许把一个对象的全部属性放在同一个文档里,读取时不用做大量连表查询。这种特性让开发人员在需求变动频繁的场景下,能直接往文档中加减字段,而不会像修改MySQL表那样执行锁表迁移。

NoSQL与关系型数据库的核心差异
关系型数据库强调ACID事务和严格的schema约束,数据要按行列表格存放,表与表之间通过外键关联。当业务模型还没稳定时,加一个字段可能要写ALTER TABLE语句,大表上这种操作会阻塞读写。NoSQL中的文档数据库如MongoDB,采用动态schema,同一个集合里的文档可以拥有不同的字段,程序侧自己处理兼容性即可。这在敏捷开发里能显著减少数据库迁移成本。
从查询方式看,关系型数据库依赖SQL这种声明式语言,通过JOIN把分散的数据拼起来;MongoDB使用面向文档的查询语句,以JSON风格的条件对象检索,例如find({age: {$gt: 18}})表示查找年龄大于18的文档。它在单文档级别保证原子性,跨文档事务从4.0版本后才逐渐完善,因此设计模型时更推荐用嵌套而非引用。下表列出两者在几个维度的区别:
| 对比维度 | 关系型数据库 | MongoDB文档库 |
|---|---|---|
| 数据模型 | 表、行、列 | 集合、文档、字段 |
| schema | 固定,需迁移 | 动态,随写随变 |
| 扩展方式 | 垂直扩展为主 | 原生分片水平扩展 |
| 典型查询 | SQL + JOIN | JSON风格查询 |
在一致性层面,MongoDB默认是最终一致性配置下的高可用,通过复制集保证数据冗余。关系型数据库通常主打强一致。选择哪类存储,要看业务更怕丢数据还是更怕停服务。很多内容型平台把用户资料放MongoDB,订单与支付仍用MySQL,形成混合持久化架构。
环境安装与基础增删改查
在本地体验MongoDB最简单的方式是用官方社区版。Linux下可用包管理器安装,macOS可用brew,Windows直接下载msi运行。启动服务后,使用自带shell工具mongo或mongosh连接。第一次连接不需要账号,但生产环境务必创建管理员并开启鉴权。下面是在Ubuntu中安装并启动的示例:
# 导入公钥并添加源后执行 sudo apt-get install -y mongodb-org sudo systemctl start mongod sudo systemctl enable mongod # 进入交互式客户端 mongosh
连接成功后,先用use blog切换到名为blog的数据库,该库在首次写入时才真正创建。插入文档用insertOne或insertMany,例如往posts集合加一篇随笔。MongoDB会自动生成_id字段作为主键,类型是ObjectId。查询时用find传过滤对象,不传则返回全部;findOne只取一条。更新操作要带$set修饰符,否则会用新文档替换旧文档。
// 插入一篇文档
db.posts.insertOne({
title: '我的第一篇',
content: '今天开始学MongoDB',
tags: ['nosql', 'mongodb'],
views: 0
});
// 查询标题包含MongoDB的
db.posts.find({ title: /MongoDB/ });
// 给所有文档浏览量加一
db.posts.updateMany({}, { $inc: { views: 1 } });
// 删除浏览量为0的
db.posts.deleteMany({ views: 0 });
删除操作分deleteOne和deleteMany,条件写错可能清掉整张表,所以执行前建议先用find确认影响范围。基础CRUD熟悉后,你会发现没有建表环节,写代码像在操作内存里的JSON对象,这种顺滑感正是NoSQL入门友好的原因。
索引机制与聚合框架入门
当集合中文档变多,全表扫描会让查询变慢。MongoDB的索引和关系型数据库类似,默认在主键_id上就有唯一索引。对常用查询字段如title、tags建索引能大幅提速。单字段索引用createIndex({title: 1}),1代表升序,-1降序。复合索引则传多个字段对象。要注意索引会占用内存和磁盘,写操作也要同步维护,所以不能盲目乱建。
// 为标题建升序索引
db.posts.createIndex({ title: 1 });
// 查看执行计划,确认是否用到索引
db.posts.find({ title: '我的第一篇' }).explain('executionStats');
聚合框架是MongoDB做数据分析的利器,它用管道概念把多个处理阶段串起来。常见阶段有$match过滤、$group分组、$sort排序、$project投射。比如统计每个标签下的文章数,先用$unwind把tags数组展开,再按标签分组计数。相比在程序里拉全量数据自己算,聚合下推到数据库边读边算更省网络带宽。
db.posts.aggregate([
{ $unwind: '$tags' },
{ $group: { _id: '$tags', count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]);
学会索引与聚合,你就从单纯存数据迈进数据利用阶段。实际项目中,配合复制集和分片集群,MongoDB能撑住千万级文档的读写。入门之后建议读官方文档的驱动部分,把Node.js或Python里的CRUD封装成服务层,再慢慢引入Schema校验规则,让灵活性与规范性达成平衡。