前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版

MongoDB拾遗(一),环境搭建、基本概念与常用查询

首页2019-01-22 17:10:30DataBase
MongoDBNoSQL数据库

第一次装 MongoDB 的时候,我在「服务起不来」这一步卡了大半个下午。命令敲下去没报错,进程也不在,日志文件是空的。后来才发现是 --dbpath 指的那个目录我压根没建,MongoDB 找不到数据目录就直接退出了,而那个版本连一行提示都不给。

这篇是我把 MongoDB 从环境搭建到日常增删改查重新过了一遍的笔记。Windows 和 Linux 两套装法都记下来了,配置文件每一项在干什么也逐条说明,后面是概念对照表、用户授权和常用查询语句。最后给一个 Node 里用 mongoose 连库的完整例子。

在本篇文章中,我们将从浅入深,和大家一起学习以下知识:

  • MongoDB 是什么,它和关系型数据库的取舍点在哪
  • Windows 下三种启动方式,从命令行传参到注册成系统服务
  • Linux 下从上传安装包到建软链的完整流程
  • 配置文件每一项的含义,以及哪些配置在新版本里已经不能用了
  • database、collection、document、field 和 SQL 概念的对照
  • 开启授权、创建管理员账号、给业务库加用户
  • 增删改查的命令,以及常用查询语句和 SQL 的逐条对照
  • 在 Node 里用 mongoose 连接 MongoDB 的写法与新旧 API 差异

# 一、MongoDB 是什么

MongoDB 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

它把数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象,字段值可以包含其他文档、数组及文档数组。

MongoDB 文档结构示意

看这张图就明白它和 MySQL 最大的差别了。关系型数据库里一条订单和它的多个商品项,得拆成两张表再靠外键关联,查的时候 join 回来;MongoDB 里直接把商品项数组嵌在订单文档里,一次查询就全拿到了。

主要特点是这几条:

  • 高可扩展性
  • 分布式存储
  • 低成本
  • 结构灵活

「结构灵活」这条要辩证地看。刚起项目的时候不用写迁移脚本,加字段直接就加了,确实爽。但字段名写错也不会报错,只是多出来一个没人用的字段,等你发现的时候库里已经有两种结构的数据了。我的做法是应用层用 mongoose 的 Schema 把结构约束住,享受灵活的同时别真的什么都往里塞。

至于什么时候该用它,我的判断很简单:数据之间关联关系强、需要事务和复杂 join 的,老老实实用 MySQL;数据结构会经常变、单个文档能自包含、读多写少的,MongoDB 更省事。这块可以对照着看我另一篇 MySQL 基础复习,两边的概念放一起看会清晰很多。

# 二、Windows 下搭环境

整体就三步:下载安装包或压缩包、添加 db 存储和日志存储文件夹、添加服务配置环境变量启动 Mongo。

# 2.1 先把目录建出来

在任意目录创建几个文件夹。

创建 MongoDB 所需的目录结构

目录创建完成后的样子

开头说的那个坑就在这一步。data 和 logs 这两个目录必须提前手动建好,MongoDB 不会替你创建。目录不存在的时候进程会直接退出,老版本给的提示很弱,很容易以为是安装包有问题。

# 2.2 命令行传参启动

配好环境变量之后,最直接的启动方式是这样。

#  --dbpath指定数据存储位置
C:\Program Files\MongoDB\Server\3.4\bin\mongod --dbpath d:\mongodb\data
@前端进阶之旅: 代码已经复制到剪贴板

命令行启动 mongod 服务的输出

这种方式最快,适合第一次验证能不能跑起来。缺点也明显,参数一多命令就长得没法看,而且关掉这个命令行窗口服务就停了。

# 2.3 用配置文件启动

参数多了就写进配置文件。

# 配置d:\mongodb\etc\mongodb.conf

#数据库路径
dbpath=d:\mongodb\data\

#日志输出文件路径
logpath=d:\mongodb\logs\mongodb.log

#错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
logappend=true

#启用日志文件,默认启用
journal=true

#这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=true

#端口号 默认为27017
port=27017

#指定存储引擎(默认先不加此引擎,如果报错了,大家在加进去)
storageEngine=mmapv1

#http配置 开启这个服务才可以在网页中访问 端口28017
httpinterface=true
@前端进阶之旅: 代码已经复制到剪贴板

逐条说一下这里面值得注意的。

logappend=true 建议一直开着。关掉的话每次重启都会覆盖日志文件,你想回看上次为什么挂掉,日志已经没了。

quiet=true 是把大部分常规日志过滤掉,只留关键信息。生产上开着能省不少磁盘,但排查问题时一定要临时关掉,不然你什么线索都看不到。

journal=true 是预写日志,掉电或者进程被强杀之后靠它恢复数据。除非是纯临时的测试库,否则不要关。

这份配置有两处是时代痕迹,得说清楚,别照抄到新版本上。

storageEngine=mmapv1 指的是老的 MMAPv1 存储引擎。MongoDB 从 3.2 开始默认就换成 WiredTiger 了,MMAPv1 在后续版本中被移除。现在的版本不用写这一项,写了反而起不来。WiredTiger 支持文档级别的并发控制和压缩,比 MMAPv1 的库级别锁强太多,没有理由回头去用老引擎。

httpinterface=true 说的是那个 28017 端口的网页状态界面。这个功能后来也被移除了,现在看实例状态用 MongoDB Compass 或者 mongosh 里的 db.serverStatus()。

还有一点,这种 key=value 的配置文件格式是老写法,新版本推荐的是 YAML 格式(storage.dbPath 这种带层级的写法)。老格式在一段时间内还兼容,但新项目建议直接用 YAML。具体哪个版本移除了什么,以官方文档为准。

启动方式:

C:\Program Files\MongoDB\Server\3.4\bin\mongod --config d:\mongodb\etc\mongodb.conf 
@前端进阶之旅: 代码已经复制到剪贴板

原文这里的 --config 后面跟的是 d:\mongodb\data,那是数据目录不是配置文件,跟着敲一定起不来,我按上面配置文件的实际路径改正了。--config 必须指向那个 .conf 文件本身。

使用配置文件启动服务

# 2.4 注册成 Windows 服务

前面两种方式都得开着命令行窗口,更省事的是装进 Windows 的服务里。

C:\Program Files\MongoDB\Server\3.4\bin\mongod --config d:\mongodb\etc\mongodb.conf --install --serviceName "MongoDB"
@前端进阶之旅: 代码已经复制到剪贴板

MongoDB 注册为 Windows 服务后的样子

装完之后开机自启,也不用管命令行窗口了。要卸载的话把 --install 换成 --remove。这里同样把 --config 的路径改成了配置文件。

# 2.5 用客户端连上去看看

服务起来之后,用图形客户端连一下是最快的验证方式,比在命令行里敲 show dbs 直观。

MongoVue 连接数据库

MongoVue 中查看集合数据

图里用的是 MongoVue,那个年代比较流行。现在官方自己出了 MongoDB Compass,免费而且更新跟得上服务端版本,新装的话直接用它。

# 三、Linux 下搭环境

思路和 Windows 一样,下载安装包或压缩包、添加 db 存储和日志存储文件夹、添加服务配置环境变量启动 Mongo。区别在于文件传输和软链这两步。

远程登录服务器:

# 远程登录服务器
ssh root@123.142.25.36
@前端进阶之旅: 代码已经复制到剪贴板

把本地的安装包传上去:

# 上传文件夹,传文件不需要r
scp /mongodb/... -r root@123.142.25.36:/home

# 传到服务器的/home/
@前端进阶之旅: 代码已经复制到剪贴板

scp 传目录必须加 -r,传单个文件不用。这条命令传的量大的时候没有进度条会让人心里没底,可以换成 rsync -avP,它有进度显示而且断了能续传。

在指定的目录创建启动需要的文件:

$ cd /home/
$ mkdir etc logs data
$ touch logs/mongodb.log etc/mongo.conf
@前端进阶之旅: 代码已经复制到剪贴板

写配置:

# /home/mongodb/etc/mongo.conf配置

dbpath=/home/mongodb/data
logpath=/home/mongodb/logs/mongodb.log
logappend=true
journal=true
quiet=true
port=27017
@前端进阶之旅: 代码已经复制到剪贴板

原文这份配置里 logpath 写的是 /mongodb/logs/...,少了 /home 前缀,和上面建目录的路径对不上;port 写的是 2701,少了一位,和默认端口 27017 不一致。这两处我都按上下文改齐了。配置文件里路径写错是最常见的启动失败原因,改完之后建议先 ls 一下确认每个路径都真实存在。

启动服务:

# 启动服务
mongod -f /home/mongodb/etc/mongo.conf
@前端进阶之旅: 代码已经复制到剪贴板

-f 就是 --config 的短写法。

最后建软链,这样在任意目录都能直接敲 mongo 和 mongod,不用写全路径。

ln -s /home/mongodb/bin/mongo /usr/local/bin/mongo

ln -s /home/mongodb/bin/mongod /usr/local/bin/mongod
@前端进阶之旅: 代码已经复制到剪贴板

补一句现状,mongo 这个旧的命令行客户端在新版本里已经被 mongosh 取代了,语法基本兼容,多了自动补全和语法高亮。装新版本的话软链的目标名字要跟着变。

# 四、基本概念

# 4.1 和关系型数据库的概念对照

刚从 MySQL 转过来的时候,最省事的入门方式就是把两边的概念对上号。

SQL术语/概念 MongoDB术语/概念 解析/说明
database database 数据库
table collection 数据表/集合
row document 数据记录/文档
column field 数据字段
index index 索引
table joins 无直接对应 表连接,早期 MongoDB 不支持
primary key primary key 主键,MongoDB 自动将 _id 字段设置为主键

关系型表结构到 MongoDB 集合的映射

表连接那一行要补充一下。「MongoDB 不支持 join」这个说法在早期是准确的,后来的版本提供了 $lookup 聚合阶段,可以做类似左外连接的操作。但它的性能特征和关系型数据库的 join 差别很大,设计数据模型时还是应该优先考虑内嵌而不是靠 $lookup 拼,具体能力和限制以官方文档为准。

_id 这个字段值得单独说。插入文档时你不给,MongoDB 会自动生成一个 ObjectId,它是 12 字节的值,里面编码了时间戳。所以 ObjectId 天然是按创建时间递增的,按 _id 排序约等于按创建时间排序,这个特性偶尔挺好用。

# 4.2 数据库

  • 一个 MongoDB 中可以建立多个数据库
  • 默认连上去所在的数据库是 test,数据文件存储在启动时 dbpath 指定的目录中
  • show dbs 命令可以显示所有数据库的列表
  • 执行 db 命令可以显示当前所在的数据库
  • use 命令可以切换到一个指定的数据库

原文这里写的是「MongoDB 的默认数据库为 db」,把 db 这个查看当前库的命令当成库名了,实际默认库是 test,我改正了。

# 4.3 文档

fe
  • 一、MongoDB 是什么
  • 二、Windows 下搭环境
    • 2.1 先把目录建出来
    • 2.2 命令行传参启动
    • 2.3 用配置文件启动
    • 2.4 注册成 Windows 服务
    • 2.5 用客户端连上去看看
  • 三、Linux 下搭环境
  • 四、基本概念
    • 4.1 和关系型数据库的概念对照
    • 4.2 数据库
    • 4.3 文档
    • 4.4 插入文档
    • 4.5 插入数据表
  • 五、常用操作
    • 5.1 创建用户与授权
    • 5.2 创建与删除数据库
    • 5.3 插入文档
    • 5.4 更新文档
  • 六、常用查询语句与 SQL 对照
  • 七、在 Node 里连接 MongoDB
  • 总结
  • 参考

← Node.js系列之WebSocket与socket.io实战MySQL 基础复习 从建表到查询的完整梳理 →