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 的概念来对照理解,术语几乎是一一对应的:
| MySQL | MongoDB |
|---|---|
| 数据库(Database) | 数据库(Database) |
| 表(Table) | 集合(Collection) |
| 行(Row) | 文档(Document) |
| 列(Column) | 字段(Field) |
一个集合里放很多文档,就像一张表里放很多行。区别在于:MySQL 要求一张表的所有行遵守同一套列结构(要先 CREATE TABLE),而 MongoDB 的集合不强制文档结构一致,插入数据时才确定字段。
那什么时候用哪个呢?一个简单的选型思路:
- 数据结构固定、表与表之间关联紧密(比如订单和商品),MySQL 这类关系型数据库更合适。
- 数据结构灵活多变、需要快速迭代(比如内容字段经常调整),MongoDB 这种免建表、直接存 JSON 的方式更顺手。
🛠 用 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
结果里会看到 admin、config、local 几个自带的数据库,它们是 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://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 stop 再 docker start 数据还在。但如果把容器删除(docker rm),数据就没了,学习场景下影响不大。
🧪 小练习
练习一:在 mongosh 中往 user 集合再插入一条文档,用户名随意,年龄和城市填你自己的信息。
// 请在这里编写代码
练习二:用 db.user.find() 查出所有文档,然后回答:现在集合里有几条文档?每条文档的 _id 一样吗?
// 请在这里编写代码
🎉 恭喜你已经成功在本地跑起 MongoDB 并完成了第一次读写!下一篇我们系统学习增删改查,掌握 insert、find、update、delete 的常用写法,让数据的进出都由你掌控。
