MongoDB

MongoDB 简介与安装

了解 MongoDB 是什么、和 MySQL 有什么区别,学会用 Docker 在本地运行 MongoDB 并成功连接。

🎯 引言

这是一门 MongoDB 入门课程的开篇。如果你学过上一门 MySQL 课程,会发现 MongoDB 是另一种思路的数据库:它不建表、不写 SQL,而是直接存类似 JSON 的文档,对前端开发者来说格外亲切。

学完这篇文章,你能说清楚 MongoDB 是什么它和 MySQL 有什么区别,并用 Docker 在本地跑起一个 MongoDB 8,通过 mongosh 客户端连上去,插入并查出第一条数据。这是后续所有课程的基础环境。


🧱 什么是 MongoDB

MongoDB 是一个开源的 NoSQL 文档型数据库。拆开看这两个词:

  • NoSQL:泛指「不使用传统 SQL 表结构」的一类数据库。它们不强制你提前定义表结构,数据怎么存更自由。
  • 文档型:数据以**文档(Document)**为单位存储,文档的格式类似 JSON(MongoDB 内部实际用的是 BSON,可以理解为带更多数据类型的 JSON)。

MySQL 里的数据像一张 Excel 表格:先定好有哪些列,每行数据都得按列来填,整整齐齐。而 MongoDB 里的数据像一个个 JSON 对象:每个对象自带字段名和值,彼此的结构可以不完全一样。比如一个用户文档长这样:

{
    "_id": ObjectId("66f1a2b3c4d5e6f7a8b9c0d1"),
    "username": "小明",
    "age": 20,
    "city": "北京",
    "hobbies": ["篮球", "摄影"]
}

几个要点:

  • _id 是文档的主键,插入时 MongoDB 会自动生成一个唯一的 ObjectId,不用我们操心,作用类似 MySQL 里的自增主键。
  • 字段的值可以是字符串、数字,还可以是数组hobbies)和嵌套文档,这是 JSON 天然的能力,不需要像 MySQL 那样拆成多张表。
  • 不需要提前声明有哪些字段。下一条文档想加个 email 字段,直接写进去就行。

这种「所见即所得」的存法,和前端日常打交道的 JSON 几乎一致,这也是很多前端同学觉得 MongoDB 上手快的原因。


⚖️ 和 MySQL 对比

刚接触 MongoDB 时,可以用 MySQL 的概念来对照理解,术语几乎是一一对应的:

MySQLMongoDB
数据库(Database)数据库(Database)
表(Table)集合(Collection)
行(Row)文档(Document)
列(Column)字段(Field)

一个集合里放很多文档,就像一张表里放很多行。区别在于:MySQL 要求一张表的所有行遵守同一套列结构(要先 CREATE TABLE),而 MongoDB 的集合不强制文档结构一致,插入数据时才确定字段。

那什么时候用哪个呢?一个简单的选型思路:

  • 数据结构固定、表与表之间关联紧密(比如订单和商品),MySQL 这类关系型数据库更合适。
  • 数据结构灵活多变、需要快速迭代(比如内容字段经常调整),MongoDB 这种免建表、直接存 JSON 的方式更顺手。
两者没有绝对的好坏,不少项目会同时使用:核心业务数据放 MySQL,结构多变的日志、配置类数据放 MongoDB。先理解各自的特点,按场景选择就好。

🛠 用 Docker 安装运行

和 MySQL 课程一样,我们用 Docker 来安装,省去繁琐的本机配置。本文基于 MongoDB 8.0(Docker 镜像 mongo:8)编写和验证,请确保你已经装好 Docker。

执行下面的命令启动一个 MongoDB 容器:

docker run -d --name mongo-demo -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=123456 mongo:8

逐个参数来看:

  • -d:后台运行容器,不占用当前终端。
  • --name mongo-demo:给容器起个名字,方便后面操作。
  • -p 27017:27017:把本机的 27017 端口映射到容器的 27017 端口,27017 是 MongoDB 的默认端口。
  • -e MONGO_INITDB_ROOT_USERNAME=root:设置管理员账号为 root
  • -e MONGO_INITDB_ROOT_PASSWORD=123456:设置管理员密码为 123456
  • mongo:8:使用 mongo 镜像的 8.x 版本。

第一次运行会下载镜像,稍等片刻。启动后用下面的命令确认容器在运行:

docker ps

看到列表里有 mongo-demo、状态是 Up,就说明 MongoDB 已经跑起来了。

这里的账号密码仅用于本地学习,真实项目要使用足够复杂的密码。另外 -e 设置的账号密码只在第一次初始化容器时生效,之后修改这两个环境变量不会改变已有容器的密码。

✨ 用 mongosh 连接并跑通第一条命令

mongosh 是 MongoDB 官方的命令行客户端,mongo:8 镜像里已经自带。用它连接刚才启动的容器:

docker exec -it mongo-demo mongosh -u root -p 123456 --authenticationDatabase admin
  • docker exec -it mongo-demo:进入名为 mongo-demo 的容器执行命令。
  • -u root -p 123456:用刚才设置的账号密码登录。
  • --authenticationDatabase admin:表示账号信息存放在 admin 这个系统数据库里,Docker 方式初始化的 root 账号就属于它,登录时必须指明。

看到 test> 提示符,就说明连接成功了。 mongosh 里直接写 JavaScript 风格的命令。先看看当前有哪些数据库:

show dbs

结果里会看到 adminconfiglocal 几个自带的数据库,它们是 MongoDB 自己用的。注意到没有 blog_demo?没关系,MongoDB 不需要提前创建数据库,第一次往里写数据时会自动创建。

切换到 blog_demo 数据库:

use blog_demo

接下来往 user 集合里插入一条文档。集合同样不需要提前创建:

db.user.insertOne({ username: '小明', age: 20, city: '北京' })

执行后会返回 acknowledged: true 和自动生成的 insertedId,说明插入成功。再把这条数据查出来:

db.user.find()

就能看到刚才插入的文档,带着 MongoDB 自动生成的 _id。到这里,一条完整的「写入 → 读取」链路就通了。

如果你更喜欢图形界面,可以试试官方的 MongoDB Compass,连接地址填 mongodb://root:123456@localhost:27017/?authSource=admin 即可。命令行和图形工具二选一,效果一样,本课程统一使用 mongosh。

🧾 小节总结

  • MongoDB 是 NoSQL 文档型数据库,数据以类似 JSON 的文档(BSON)存储,不需要提前定义结构。
  • 术语对照:表对应集合(Collection),行对应文档(Document),列对应字段(Field)。
  • 结构固定、关联紧密的场景适合 MySQL;结构灵活、快速迭代的场景可以考虑 MongoDB。
  • docker run -d --name mongo-demo -p 27017:27017 -e ... mongo:8 一条命令跑起 MongoDB 8,docker ps 确认运行状态。
  • docker exec -it mongo-demo mongosh -u root -p 123456 --authenticationDatabase admin 连接数据库。
  • use blog_demo 切换数据库,db.user.insertOne() 插入文档,db.user.find() 查询文档,数据库和集合都会随写入自动创建。

❓ 知识问答

Q1:MongoDB 不需要建表,那数据结构不就乱套了吗?

不会乱。MongoDB 把「保证结构一致」的责任交给了代码:只要你的 Node.js 代码写入时字段统一,数据自然整齐。后面讲 Mongoose 时会看到,还可以在代码层给文档定义结构约束,兼顾灵活和规范。

Q2:show dbs 里为什么没有刚用过的 blog_demo

空数据库不会显示在列表里。use blog_demo 只是做了个切换标记,等你真正插入数据后,再执行 show dbs 就能看到它了。

Q3:为什么登录时要加 --authenticationDatabase admin

MongoDB 的账号是存放在某个具体数据库里的。Docker 镜像初始化的 root 账号存放在系统数据库 admin 中,所以登录时要告诉 mongosh 去 admin 里校验账号密码,否则会认证失败。

Q4:db 是什么意思?为什么命令都以它开头?

db 是 mongosh 里的一个内置变量,代表当前正在使用的数据库(也就是 use 切换到的那个)。db.user 就是「当前数据库下的 user 集合」。

Q5:容器重启后数据会丢吗?

不会。Docker 容器的文件在容器存续期间都会保留,docker stopdocker start 数据还在。但如果把容器删除(docker rm),数据就没了,学习场景下影响不大。


🧪 小练习

练习一:在 mongosh 中往 user 集合再插入一条文档,用户名随意,年龄和城市填你自己的信息。

// 请在这里编写代码

练习二:用 db.user.find() 查出所有文档,然后回答:现在集合里有几条文档?每条文档的 _id 一样吗?

// 请在这里编写代码

🎉 恭喜你已经成功在本地跑起 MongoDB 并完成了第一次读写!下一篇我们系统学习增删改查,掌握 insert、find、update、delete 的常用写法,让数据的进出都由你掌控。