MongoDB 笔记

一、基础概念

MongoDB 的特点是什么?

MongoDB是一种NoSQL数据库,具有以下特点:

  1. 文档存储模型

    • MongoDB 使用 BSON(Binary JSON) 格式存储数据,数据以文档的形式组织,类似于JSON对象。
    • 文档可以包含嵌套结构(如数组和对象),非常适合存储复杂、非结构化的数据。
  2. 高性能

    • MongoDB支持索引,能够快速查询数据。
    • 写入性能高,支持内存映射文件,能够高效处理大量数据。【内存映射文件是一种高效的文件访问技术,通过将文件直接映射到内存中,减少了传统文件 I/O 的开销。】
  3. 水平扩展能力

    • MongoDB支持分片(Sharding),可以将数据分布到多个服务器上,实现水平扩展,适合处理大规模数据和高并发场景。
  4. 高可用性

    • MongoDB通过 复制集 提供高可用性。复制集包含多个节点(主节点和从节点),当主节点故障时,系统会自动选举新的主节点,确保服务不中断。
  5. 丰富的查询功能

    • 支持丰富的查询操作,包括范围查询、正则表达式查询、地理空间查询等。
    • 提供 聚合管道,支持复杂的数据分析和处理。
  6. 事务支持

    • 从 MongoDB 4.0 开始,支持多文档事务,能够在分布式环境中保证数据的一致性。

MongoDB 和关系型数据库术语对比

概念 MongoDB 关系型数据库
数据库层级 数据库(Database) 数据库(Database)
数据集合 集合(Collection) 表(Table)
数据单元 文档(Document) 行(Row)
数据格式 BSON(Binary JSON) 行数据(Row Data)
数据结构 字段(Field) 列(Column)
嵌套结构 嵌套文档(Embedded Document) 关联表(Related Table)
数组支持 数组(Array) 多值列(Multi-value Column)
唯一标识 _id字段 主键(Primary Key)
查询语言 MongoDB 查询语言 SQL(Structured Query Language)
聚合操作 聚合管道(Aggregation Pipeline) SQL聚合函数(如GROUP BY)
索引 索引(Index) 索引(Index)
复合索引 复合索引(Compound Index) 复合索引(Composite Index)
事务 多文档事务(Multi-Document Transactions) 事务(Transactions)
数据一致性 最终一致性(Eventual Consistency) 强一致性(Strong Consistency)
水平扩展 分片(Sharding) 分区(Partitioning)
高可用性 复制集(Replica Set) 主从复制(Master-Slave Replication)

BSON 格式的优势有哪些?

1. 二进制编码,高效存储和传输

  • BSON 是二进制编码的 JSON,比文本格式的 JSON 更紧凑,减少了存储空间和网络传输的开销。
  • 二进制格式解析速度更快,适合高性能场景。

2. 支持丰富的数据类型

  • BSON 支持比 JSON 更多的数据类型,如 日期(Date)、二进制数据(BinData)、ObjectId、正则表达式(Regex)等。

3. 支持嵌套和复杂结构

  • BSON可以表示嵌套的文档和数组,适合存储复杂的数据结构。
  • 例如,一个文档中可以包含另一个文档或数组,而无需额外的关联表。

4. 高效查询

  • BSON格式在存储时会记录字段的长度和类型信息,使得查询时可以直接定位数据,无需解析整个文档。

5. 支持索引

  • BSON 格式允许 MongoDB 在文档的特定字段上创建索引,从而加速查询。
  • 例如,可以在嵌套字段或数组字段上创建索引。

MongoDB 支持哪些数据类型?

1. 基本数据类型

  • 字符串(String)
  • 整数(Integer)
  • 双精度浮点数(Double)
  • 布尔值(Boolean
  • 日期(Date)**
    • 用于存储日期和时间,例如:"createdAt": ISODate("2023-10-01T12:00:00Z")
  • 空值(Null)

2. 特殊数据类型

  • ObjectId

    • 用于唯一标识文档的12字节ID,例如:"_id": ObjectId("507f1f77bcf86cd799439011")
  • 二进制数据(BinData)

    • 用于存储二进制数据,例如图片或文件,例如:"file": BinData(0, "SGVsbG8gd29ybGQ=")
  • 正则表达式(Regex)

    • 用于存储正则表达式,例如:"pattern": /^[A-Za-z]+$/
  • JavaScript代码(JavaScript)

    • 用于存储JavaScript代码,例如:"script": "function() { return this.age > 18; }"
  • 时间戳(Timestamp)

    • 用于存储时间戳,通常用于内部操作,例如:"ts": Timestamp(1696156800, 1)

3. 复杂数据类型

  • 数组(Array)**
    • 用于存储一组值,例如:"hobbies": ["reading", "traveling", "coding"]
  • 嵌套文档(Embedded Document)**
    • 用于存储嵌套的文档,例如:
      "address": {
             
             
        "city": "New York",
        "zip": "10001"
      }
      

MongoDB 和 MySQL 哪个扩展性好一些?

一般来说,MongoDB的扩展性要优于MySQL,以下是从多个方面的分析:

  • 数据模型
    • MongoDB:采用文档型数据模型,数据以JSON或BSON格式存储,具有高度的灵活性和可扩展性。文档结构可以随意变化,无需事先定义固定的表结构,非常适合处理不断变化的业务需求和非结构化数据。例如,在一个内容管理系统中,随着业务发展,需要为文章添加新的字段,如摘要、关键词等,在MongoDB中只需直接在文档中添加相应字段即可,无需对整个数据库结构进行修改。
    • MySQL:是关系型数据库,基于固定的表结构存储数据,表中的列和数据类型在创建时就需要明确指定。当业务需求发生变化,需要添加或修改列时,可能需要执行复杂的表结构变更操作,如ALTER TABLE语句,这在大型生产环境中可能会带来一些风险和性能问题。
  • 分布式架构
    • MongoDB:原生支持分布式架构,其分片(Sharding)功能可以将数据分散存储在多个节点上,实现水平扩展。通过自动数据均衡和故障转移机制,能够轻松应对大规模数据和高并发读写场景。例如,一个大型电商系统的订单数据量非常大,使用MongoDB的分片功能可以将订单数据按照一定的分片键(如用户ID)分散到多个节点上,从而提高系统的读写性能和可扩展性。
    • MySQL:虽然也可以通过一些分布式方案来实现扩展,如主从复制、分布式数据库中间件等,但这些方案相对来说较为复杂,需要额外的配置和管理。而且,在分布式环境下,MySQL的事务处理和数据一致性保证可能会面临一些挑战。
  • 读写性能
    • MongoDB:在处理高并发的读写请求时,MongoDB具有较好的性能表现。它采用了内存映射文件、异步I/O等技术,能够快速地读写数据。同时,由于文档型数据模型的特点,对于一些复杂的查询操作,可以通过索引和聚合管道等功能来高效地实现。例如,在一个社交媒体应用中,需要实时统计用户的点赞、评论等数据,MongoDB可以利用聚合管道快速地进行数据处理和分析。
    • MySQL:在处理大规模数据和高并发读写时,性能可能会受到一定的限制。尤其是在进行复杂的关联查询和事务处理时,可能会导致性能下降。为了提高性能,通常需要进行一些优化措施,如索引优化、查询语句优化、数据库参数调整等。

虽然MongoDB在扩展性方面具有一定的优势,但MySQL也有其自身的特点和适用场景。在实际应用中,需要根据具体的业务需求、数据量、并发量等因素来综合考虑选择合适的数据库。


二、数据操作

如何创建数据库和集合?

创建数据库:

  • 使用 use 命令切换到指定数据库,如果数据库不存在则会自动创建。
    use myDatabase
    

创建集合:

  • 使用 db.createCollection() 方法显式创建集合。
    db.createCollection("myCollection")
    
  • 如果集合不存在,插入文档时会自动创建集合。

使用 insertOne()insertMany() 插入文档?

{ name: “Alice”, age: 25 } 表示一个文档
insertOne()

  • 插入单个文档。
    db.myCollection.insertOne({
         
          name: "Alice", age: 25 })
    
  • 注意事项:
    • 如果文档未指定 _id 字段,MongoDB 会自动生成一个唯一的 ObjectId
    • 如果文档已存在 _id 字段,且 _id 已存在,则会抛出重复键错误。

insertMany()

  • 插入多个文档。
    db.myCollection.insertMany([
      {
         
          name: "Bob", age: 30 },
      {
         
          name: "Charlie", age: 35 }
    ])
    
  • 注意事项:
    • 如果插入的文档中有重复的 _id,整个操作会失败(默认行为)。
    • 可以通过 ordered: false 选项忽略重复键错误,继续插入其他文档。
      db.myCollection.insertMany([
        {
             
              _id: 1, name: "Bob" },
        {
             
              _id: 1, name: "Charlie" }
      ], {
             
              ordered: false })
      

如何编写多条件查询语句(如年龄>25且性别为男)?

  • 使用 $and 操作符或直接在查询对象中指定多个条件。
    db.myCollection.find({
         
         
      age: {
         
          $gt: 25 },
      gender: "male"
    })
    

如何使用投影操作符返回部分字段?

  • find() 的第二个参数中指定需要返回的字段(1 表示返回,0 表示不返回)。
    db.myCollection.find(
      {
         
          age: {
         
          $gt: 25 } },
      {
         
          name: 1, age: 1, _id: 0 }
    )
    

如何对查询结果进行排序?

  • 使用 sort() 方法,1 表示升序,-1 表示降序。
    db.myCollection.find().sort({
         
          age: 1 })
    

如何使用聚合管道进行复杂数据处理?

  • 使用 aggregate() 方法,结合多个阶段(如 $match$group$sort 等)处理数据。
db.users.aggregate([
  // 1. 过滤年龄大于 25 的用户
  {
   
    $match: {
   
    age: {
   
    $gt: 25 } } },

  // 2. 只保留 name 和 gender 字段
  {
   
    $project: {
   
    name: 1, gender: 1, _id: 0 } },

  // 3. 按 gender 分组,计算每组人数
  {
   
    $group: {
   
    _id: "$gender", total: {
   
    $sum: 1 } } },

  // 4. 按 total 字段降序排序
  {
   
    $sort: {
   
    total: -1 } },

  // 5. 只返回前 5 条结果
  {
   
    $limit: 5 }
])

如何更新满足条件的多个文档?

  • 使用 updateMany() 方法。
    db.myCollection.updateMany(
      {
         
          age: {
         
          $gt: 25 } },
      {
         
          $set: {
         
          status: "active" } }
    )
    

如何删除满足条件的文档?

  • 使用 deleteMany() 方法。
    db.myCollection.deleteMany({
         
          age: {
         
          $lt: 18 } })
    

如何实现文档的部分更新?

  • 使用 $set 操作符更新指定字段。
    db.myCollection.updateOne(
      {
         
          name: "Alice" },
      {
         
          $set: {
         
          age: 26 } }
    )
    

三、索引

索引底层原理?

索引数据通过 B 树来存储,所有节点都有 Data 域,只要找到指定索引就可以进行访问,
单次查询从结构上来看要快于MySql(B+ 树)。

B 树结构:
在这里插入图片描述

<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值