4. 数据库环境搭建:MySQL 与 MongoDB 的安装、配置与基本操作

一个联调环境,说白了就是让前端能拿到后端的数据。而后端最核心的依赖,就是数据库。我见过不少同学,代码写得挺溜,结果卡在数据库装不上、连不上,一查就是配置不对。这一章,咱们就把 MySQL 和 MongoDB 的安装、配置和基本操作过一遍。

4.1 选 MySQL 还是 MongoDB?

这俩不是竞争关系。我在项目里通常这么选:
如果你需要严格的表结构、事务支持、比如订单系统、用户账户余额,首选 MySQL;
如果你要存 JSON 文档、日志、灵活的动态字段,MongoDB 更省事。

联调环境,我建议你把两个都装好。原因很简单 —— 你不知道测试同事会不会临时塞进来一个文档需求。嗯,我就吃过这亏。

维度MySQLMongoDB
数据模型关系型表结构文档型 JSON
事务支持 ACID4.0+ 支持多文档事务
主键自增 ID / UUIDObjectId
查询语言SQLMQL(JSON 风格)
适合场景金融、电商、ERP日志、CMS、实时分析

4.2 MySQL 安装与基础配置

我习惯用 Docker 装数据库,干净、版本可控、不污染宿主机。当然你如果非要在物理环境搞,我也拦不住你。

4.2.1 用 Docker 安装 MySQL 8.0

docker run -d \
  --name mysql8 \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=root123 \
  -e MYSQL_DATABASE=dev_db \
  mysql:8.0

等几十秒后,检查是否启动成功:

docker logs mysql8 | tail -5
docker exec -it mysql8 mysql -uroot -proot123 -e "SELECT VERSION();"

我个人的小习惯: 给 Docker 容器加上 --restart=always,这样电脑重启后数据库自动起来,不用每次手动 start。联调期间省心不少。

4.2.2 字符集与排序规则

你在连接 MySQL 时遇到乱码?十有八九是字符集没设对。我在一次联调中,前端传了 emoji,结果插进去全是问号……后来发现数据库默认是 latin1。

建议创建数据库时指定:

CREATE DATABASE dev_db 
  CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

连接串里也加上编码参数:

mysql -h127.0.0.1 -uroot -proot123 --default-character-set=utf8mb4

警告: 关系型数据库的密码不要用弱口令 root123,联调环境至少改成 Dev@2024! 级别。我曾经在客户内网看到有人用 123456,结果被内部扫描工具扫出漏洞,差点背锅。

4.3 MySQL 基本操作

你不需要成为 DBA,但 CRUD SQL 必须闭着眼写。

4.3.1 建表与插入

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(100) UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com');

4.3.2 查询与索引

SELECT * FROM users WHERE email = 'zhangsan@example.com';
-- 经常查询的字段加索引
CREATE INDEX idx_email ON users(email);

4.3.3 备份与恢复

# 导出
docker exec mysql8 mysqldump -uroot -proot123 dev_db > backup.sql
# 导入
docker exec -i mysql8 mysql -uroot -proot123 dev_db < backup.sql

4.4 MongoDB 安装与基础配置

MongoDB 的安装和 MySQL 类似,但有几个关键区别,你注意一下。我在刚接触 MongoDB 时,一上来就写 use test 然后往里怼数据,结果发现数据存哪了都不知道——因为没显式创建数据库和集合。

4.4.1 用 Docker 安装 MongoDB 7.0

docker run -d \
  --name mongo7 \
  -p 27017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=admin123 \
  mongo:7.0

验证连接:

docker exec -it mongo7 mongosh \
  -u admin -p admin123 \
  --authenticationDatabase admin \
  --eval "db.version()"

4.4.2 身份认证与用户创建

MongoDB 默认不开启认证,但联调环境必须开。我建议你把认证加上,免得测试数据被误删。

use admin
db.createUser({
  user: "dev_user",
  pwd: "DevP@ss2024",
  roles: [{ role: "readWrite", db: "dev_db" }]
})

避坑: 创建用户后,连接串要指定 authSource=admin,否则 MongoDB 会在目标数据库找用户,导致认证失败。连接格式:mongodb://dev_user:DevP@ss2024@localhost:27017/dev_db?authSource=admin

4.5 MongoDB 基本操作

文档型数据库的 CRUD 比 SQL 更直白,但坑也不少。

4.5.1 插入与查询

use dev_db

// 插入一条文档(集合自动创建)
db.users.insertOne({
  name: "李四",
  email: "lisi@example.com",
  tags: ["前端", "Vue"]
})

// 查询
db.users.find({ email: "lisi@example.com" })

4.5.2 索引创建

db.users.createIndex({ email: 1 }, { unique: true })

4.5.3 备份与恢复

# 导出
docker exec mongo7 mongodump \
  -u admin -p admin123 \
  --authenticationDatabase admin \
  -d dev_db -o /dump
# 恢复
docker exec mongo7 mongorestore \
  -u admin -p admin123 \
  --authenticationDatabase admin \
  -d dev_db /dump/dev_db

4.6 两张数据库的对比与选型决策流程

下面这张图,就是你在联调环境到底该用哪个数据库的决策路径。我自己画了很多次,最后简化成这个版本。

数据库选型决策流程 项目数据需求 数据高度结构化? MySQL 否,文档/JSON MongoDB 需要事务? InnoDB 考虑 NoSQL 字段动态变化? 文档灵活 考虑关系型 决策结论:强事务用 MySQL + InnoDB,文档灵活用 MongoDB 联调环境建议两种都装,方便随时切换

4.7 联调环境中的数据库连接最佳实践

数据库装好只是第一步。真正让前后端联调跑起来,连接配置才是大头。

  • 别用 root/管理员账号: 每个服务创建单独的数据库用户,权限最小化。我在一个项目里发现前端代码直接硬编码了 root 密码,吓得我连夜改了。
  • 连接池设置: 后端框架(比如 Node.js 的 Sequelize 或 Mongoose)默认连接池太小,联调时多开几个页面就超时。我会调大 pool: { max: 10, min: 2 }。
  • 网络可达性检查: 在宿主机执行 telnet 127.0.0.1 3306 或者 nc -zv localhost 27017,先确认端口通了,再怀疑代码问题。

联调环境验证三连:

  1. docker ps 确认容器都 running
  2. 从后端容器内部 curl/mysql/mongosh 直连数据库
  3. 前端调用后端接口,看返回数据是否真从数据库拿到

这三步走完,数据库环境才算“搭建完成”。

我记得有一次联调到凌晨两点,后端一直报 500,前端说接口不通。我直接登录服务器查,发现 docker 容器挂了,docker restart mysql8 十秒解决。嗯,这种低级问题,提前检查容器状态就能避免。

4.8 写在最后(本章小结)

我们搞定了俩数据库的安装、配置和基础增删改查。说实话,联调环境里数据库很少出奇奇怪怪的 bug,大多是你配错了字符集、忘了开认证、或者权限没弄对。你如果把前面那些步骤按顺序走一遍,后面联调跑起来会很顺。

现在,你的电脑上应该有两个数据库在跑。去试一下,用 Navicat 或 Compass 连一下,往里面插一条数据,再用命令行把它查出来。做到这一步,再往后就是后端怎么连数据库了。