MongDB浅学

内容分享11小时前发布 蛇骨酒
0 0 0

可以将 MongoDB 理解成一个 “灵活的文件柜”—— 它是一款非关系型数据库(NoSQL),不像 MySQL 那样用 “表格 + 行 + 列” 的固定结构存数据,而是用 “文档”(类似 JSON)的形式存数据,想存什么字段就存什么,特别适合存储非结构化、半结构化数据。

一、核心概念:用 “文件柜” 类比

MongoDB 里的专业术语,对应到 “文件柜整理文件” 的场景,全是熟悉的逻辑:

MongoDB 概念

生活类比(文件柜场景)

对应 MySQL 概念

通俗解释

数据库(Database)

整个文件柜(列如 “公司文件柜”)

数据库(Database)

存储一组相关数据的 “容器”,列如 “电商数据库”“社交 APP 数据库”

集合(Collection)

文件柜里的抽屉(列如 “员工档案抽屉”)

表(Table)

把同类文档归为一组,列如 “用户集合”“商品集合”,不用提前定义结构(列如 “员工抽屉” 里的文件,有的有 “学历” 页,有的没有,都能放)

文档(Document)

抽屉里的单份文件(列如 “张三的员工档案”)

行(Row)

MongoDB 最小的数据单元,用 BSON(二进制 JSON)格式存储,列如一条用户数据:{name: “张三”, age: 25, address: {city: “北京”, street: “XX路”}}

字段(Field)

文件里的具体条目(列如 “姓名:张三”)

列(Column)

文档里的 “细分信息”,列如上面的name“age”“address”,字段可以灵活增减(列如给张三的文档加个hobby: [“跑步”, “看书”],不用改其他文档)

BSON

带 “特殊附件” 的文件格式

比 JSON 功能强:支持日期、二进制、数组等类型(列如 JSON 存不了 “日期”,BSON 可以)

二、MongoDB 的核心特点:“灵活”

1. 文档模型灵活,不用固定 “表结构”

列如电商的 “商品”:

  • 手机商品需要 “品牌、内存、像素” 字段;
  • 衣服商品需要 “尺码、颜色、材质” 字段;
  • 在 MySQL 里,得建两张表(或用复杂的关联表),但在 MongoDB 里,直接存在同一个 “商品集合” 里,各自的文档有各自的字段,互不影响。

2. 天生支持海量数据和高并发

MongoDB 支持 “分片集群”(把数据分散到多台服务器),能轻松存上亿条数据,还能通过多台服务器分担读写压力,应对高并发(列如电商大促时的商品查询、用户下单)。

3. 支持复杂查询和索引

别看结构灵活,查询能力确很强:

  • 能按字段筛选(列如 “查年龄> 20 的用户”);
  • 能查嵌套字段(列如 “查地址在‘北京’的用户”);
  • 能给字段建索引(列如给name“商品 ID” 建索引,查询速度翻倍);
  • 还支持聚合查询(列如 “统计每个城市的用户数量”)。

4. 容易扩展

  • 水平扩展:想存更多数据?直接加服务器(分片),不用改代码;
  • 字段扩展:给文档加新字段,直接存就行,不用像 MySQL 那样 “ALTER TABLE” 改表结构(改表结构可能锁表,影响性能)。

三、优缺点:什么时候选 MongoDB?

优点

缺点

1. 结构灵活,适合非结构化 / 半结构化数据(列如日志、社交动态、商品属性);

1. 不支持事务的 “强一致性”(早期版本不支持事务,目前支持,但不如 MySQL 成熟,适合 “最终一致” 场景);

2. 海量数据存储 + 高并发读写能力强;

2. 不适合复杂的 “多表关联查询”(列如 “查用户 + 订单 + 物流” 的关联,MySQL 更高效);

3. 扩展简单,水平扩容成本低;

3. 占用空间比 MySQL 大(BSON 格式比表格存储冗余);

4. 查询语法直观(类似 JSON),容易上手。

4. 对 “数据一致性” 要求极高的场景(列如金融交易),不如 MySQL 靠谱。

四、典型应用场景

1. 电商商品 / 订单数据

  • 商品属性多样(不同品类字段不同)、订单数据包含嵌套信息(列如订单详情、收货地址、商品列表),用文档模型刚好适配;
  • 大促时高并发读写,分片集群能扛住压力。

2. 日志 / 监控数据

  • 服务器日志、APP 埋点数据(列如用户点击行为),字段不固定(有的日志有 “错误码”,有的没有),MongoDB 不用固定结构,直接批量写入。

3. 社交 APP 数据

  • 用户动态、评论、关注关系:列如一条动态可能有文字、图片、视频链接、评论列表,用嵌套文档存,查询时一次就能取到所有相关数据(不用像 MySQL 那样多表关联)。

4. IoT 设备数据

  • 传感器采集的实时数据(列如温度、湿度、设备状态),数据量大、字段可能随设备升级增减,MongoDB 能灵活存储,还支持按时间范围快速查询。

5. 内容管理系统(CMS)

  • 文章、视频、音频等内容,有的有 “标签”,有的有 “作者简介”,有的有 “点赞数”,结构灵活,适合用文档存储。

五、MongoDB vs MySQL:怎么选?

对比维度

MongoDB

MySQL

数据结构

文档(BSON),灵活无固定结构

表格(行 + 列),固定结构

核心优势

灵活、海量数据、高并发、易扩展

强一致性、事务成熟、复杂关联查询高效

适用场景

非结构化 / 半结构化数据、高并发海量数据(电商商品、日志、社交)

结构化数据、强一致性要求高(金融交易、用户账户、订单支付)

选型提议:

  • 如果需要 “固定结构、数据不能错、要复杂关联查询”(列如银行转账、用户余额),选 MySQL;
  • 如果需要 “灵活结构、存海量数据、高并发读写”(列如电商商品、APP 日志),选 MongoDB;
  • 实际项目中,两者常 “配合使用”:列如电商系统,用 MySQL 存订单支付数据(强一致性),用 MongoDB 存商品和用户动态数据(灵活 + 高并发)。

六、总结

MongoDB 是一款 “灵活、能扛量” 的非关系型数据库,核心优势是文档模型无固定结构、支持海量数据和高并发,适合存储非结构化 / 半结构化数据;如果数据结构固定、一致性要求极高,还是得选 MySQL。

七、MongoDB 常用操作命令

命令基于 MongoDB Shell(类似 MySQL 命令行),用「用户集合(user)」「商品集合(product)」举例,语法直观(类似 JSON),上手即用:

1. 数据库操作

命令

语法

示例

说明

查看所有数据库

show dbs

show dbs

显示所有已创建的数据库(空数据库不显示)

切换 / 创建数据库

use 数据库名

use ecommerce(切换到电商数据库,不存在则创建)

切换后需插入数据,数据库才会实际存在

查看当前数据库

db

db

返回当前所在数据库名称

删除当前数据库

db.dropDatabase()

db.dropDatabase()

谨慎使用!删除当前选中的数据库

2. 集合操作(对应 “文件柜抽屉操作”)

命令

语法

示例

说明

查看所有集合

show collections

show collections

显示当前数据库下的所有集合

创建集合

db.createCollection(“集合名”)

db.createCollection(“user”)

手动创建集合(也可直接插入文档自动创建)

删除集合

db.集合名.drop()

db.user.drop()

删除指定集合及所有数据

3. 文档操作(核心!增删改查,对应 “文件操作”)

(1)新增文档(存文件)

  • 单个新增:db.集合名.insertOne(文档)示例:db.user.insertOne({name: “张三”, age: 25, address: {city: “北京”}, hobby: [“跑步”, “看书”]})说明:文档自动生成唯一_id(类似主键),字段灵活,可嵌套(address)、可存数组(hobby)。
  • 批量新增:db.集合名.insertMany([文档1, 文档2…])示例:db.user.insertMany([{name: “李四”, age: 28}, {name: “王五”, gender: “男”}])说明:允许文档字段不一致(李四没有 gender,王五没有 address,都能存)。

(2)查询文档(找文件)

  • 查询所有:db.集合名.find()示例:db.user.find() → 返回所有用户文档(默认显示 20 条,按_id排序)。
  • 条件查询:db.集合名.find(查询条件)示例 1(等值查询):db.user.find({name: “张三”}) → 查姓名为张三的用户。示例 2(范围查询):db.user.find({age: {$gt: 25}}) → 查年龄 > 25 的用户($gt= 大于,$lt= 小于,$eq= 等于)。示例 3(嵌套字段查询):db.user.find({“address.city”: “北京”}) → 查地址在北京市的用户(嵌套字段用引号 + 点分隔)。
  • 限制返回条数:db.集合名.find().limit(数量)示例:db.user.find().limit(5) → 返回前 5 条用户。
  • 排序:db.集合名.find().sort({字段: 1/-1})(1 = 升序,-1 = 降序)示例:db.user.find().sort({age: -1}) → 按年龄降序排列。

(3)修改文档(改文件)

  • 修改单个文档:db.集合名.updateOne(查询条件, {修改操作})示例:db.user.updateOne({name: “张三”}, {$set: {age: 26, hobby: [“跑步”, “旅行”]}})说明:$set表明 “更新指定字段”,不影响其他字段(列如张三原本的 address 字段保留);如果不加$set,会用新文档覆盖原文档。
  • 批量修改:db.集合名.updateMany(查询条件, {修改操作})示例:db.user.updateMany({age: {$lt: 25}}, {$set: {level: “年轻用户”}}) → 给所有年龄 < 25 的用户加 level 字段。

(4)删除文档(删文件)

  • 删除单个文档:db.集合名.deleteOne(查询条件)示例:db.user.deleteOne({name: “王五”}) → 删除姓名为王五的第一个匹配文档。
  • 批量删除:db.集合名.deleteMany(查询条件)示例:db.user.deleteMany({age: {$gt: 30}}) → 删除所有年龄 > 30 的用户。

4. 索引操作(提速查询,对应 “给文件贴标签”)

  • 创建索引:db.集合名.createIndex({字段: 1/-1})(1 = 升序索引,-1 = 降序索引)示例:db.user.createIndex({name: 1}) → 给 name 字段建升序索引,查询 name 时速度翻倍。
  • 查看索引:db.集合名.getIndexes()示例:db.user.getIndexes() → 显示 user 集合的所有索引(默认_id字段有主键索引)。
  • 删除索引:db.集合名.dropIndex({字段: 1/-1})示例:db.user.dropIndex({name: 1}) → 删除 name 字段的索引。

八、MongoDB 分片集群原理(类比:“文件柜分多个抽屉 + 管理员”)

当数据量达到千万 / 亿级,单台服务器存不下或扛不住高并发时,就需要 “分片集群”—— 把数据分散到多台服务器,共同承担存储和查询压力。

1. 核心组件(3 个角色缺一不可)

  • 分片(Shard):实际存储数据的 “服务器节点”(类似多个小文件柜)。每个分片存储数据的一部分,列如分片 1 存北京用户,分片 2 存上海用户。
  • 配置服务器(Config Server):“集群管理员”,存储集群的元数据(列如 “哪些数据存在哪个分片”“索引信息”)。查询时,先问配置服务器 “数据在哪个分片”,再直接去对应分片查,不用遍历所有分片。
  • 路由服务器(Mongos):“用户接口”,客户端(列如 APP、后端程序)只和路由服务器通信,不用关心分片在哪。路由服务器接收查询请求,通过配置服务器找到目标分片,返回结果(对客户端透明,像操作单台 MongoDB 一样)。

2. 数据分片规则(怎么把数据分到不同分片?)

核心是 “分片键(Shard Key)”—— 选择一个字段作为分片依据,列如用户集合选address.city(城市)、商品集合选price(价格)。

常见分片策略:

  • 范围分片:按分片键的范围分配数据。列如按价格分片,0-100 元的商品存在分片 1,101-500 元存在分片 2,501 元以上存在分片 3。适合范围查询(列如查 100-300 元的商品,只查分片 1 和 2)。
  • 哈希分片:对分片键做哈希计算,把数据均匀分散到所有分片。列如用户 ID 哈希后,随机分配到分片 1、2、3。适合随机查询(列如按用户 ID 查,数据均匀分布,所有分片分担压力)。

3. 分片集群的优势

  • 水平扩展:想存更多数据、扛更高并发,直接加分片服务器(不用改代码);
  • 高可用:每个分片可以配置副本(类似 Redis 主从),分片宕机后,副本自动接管,数据不丢失;
  • 负载均衡:配置服务器自动监控各分片的负载,把新数据分配到负载低的分片。
© 版权声明

相关文章

暂无评论

none
暂无评论...