MongoDB知識點總結

来源:https://www.cnblogs.com/mh20131118/archive/2020/06/09/12116138.html
-Advertisement-
Play Games

一:MongoDB 概述 一、NoSQL 簡介 1. 概念:NoSQL(Not Only SQL的縮寫),指的是非關係型資料庫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱。用於超大規模數據的存儲,數據存儲不需要固定的模式,無需多餘操作就可以橫向擴展。 2. 特點 1. 優點:具有高可擴展性、 ...


一:MongoDB 概述
    一、NoSQL 簡介

       1. 概念:NoSQL(Not Only SQL的縮寫),指的是非關係型資料庫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱。用於超大規模數據的存儲,數據存儲不需要固定的模式,無需多餘操作就可以橫向擴展。

       2. 特點

           1. 優點:具有高可擴展性、分散式計算、低成本、架構靈活且是半結構化數據,沒有複雜的關係等。

           2. 缺點:沒有標準化、有限的查詢功能、最終一致是不直觀的程式等。

 

       3. 分類

         

             

 

       4. NoSQL 和 RDBMS 的對比

          

 

    二、MongoDB 簡介

       1. 概念:MongoDB 是由C++語言編寫的一個基於分散式文件存儲的開源文檔型資料庫系統。

       2. 功能:JSON 文檔模型、動態的數據模式、二級索引強大、查詢功能、自動分片、水平擴展、自動複製、高可用、文本搜索、企業級安全、聚合框架MapReduce、大文件存儲GridFS。

           1. 面向集合文檔的存儲:適合存儲Bson(json的擴展)形式的數據;

           2. 格式自由,數據格式不固定,生產環境下修改結構都可以不影響程式運行;

           3. 強大的查詢語句,面向對象的查詢語言,基本覆蓋sql語言所有能力;

           4. 完整的索引支持,支持查詢計劃;

           5. 使用分片集群提升系統擴展性;

 

       3. 適用場景

           1. 網站數據:Mongo非常適合實時的插入,更新與查詢,並具備網站實時數據存儲所需的複製及高度伸縮性。

           2. 緩存:由於性能很高,Mongo也適合作為信息基礎設施的緩存層。在系統重啟之後,由Mongo搭建的持久化緩存層可以避免下層的數據源 過載。

           3. 在高伸縮性的場景,用於對象及JSON數據的存儲。

           

 

       4. 數據類型

           

 

    三、概念詳解

       1. 資料庫:MongoDB 預設的資料庫為"db",該資料庫存儲在data目錄中。單個實例可以容納多個獨立的資料庫,每一個都有自己的集合和許可權,不同的資料庫也放置在不同的文件中。

       2. 集合:集合就是 MongoDB 文檔組,類似於 RDBMS 的表格。集合存在於資料庫中,集合沒有固定的結構,這意味著你在對集合可以插入不同格式和類型的數據,但通常情況下我們插入集合的數據都會有一定的關聯性。

       3. 文檔:一個鍵值(key-value)對(即BSON)。MongoDB 的文檔不需要設置相同的欄位,並且相同的欄位不需要相同的數據類型,這與關係型資料庫有很大的區別,也是 MongoDB 非常突出的特點。

       

        

 

    四、安裝配置

       1. Windows

           1. 下載(4.2.7版本以上)並直接安裝

              

 

           2. 配置環境變數

               

 

           3. 測試

                 

=

       2. Linux

           

 1  # 解壓到指定目錄
 2  tar -zxvf mongodb-linux-x86_64-rhel70-4.2.7.tgz -C /opt/
 3  
 4  # 配置環境變數
 5  # MONGODB_HOME
 6  export MONGODB_HOME=/opt/mongodb-linux-x86_64-rhel70-4.2.7
 7  export PATH=$PATH:$MONGODB_HOME/bin
 8  
 9  # 測試
10 [root@controller ~]# mongo
11  MongoDB shell version: 4.2.7
12  connecting to: test

 

二:MongoDB CLI 

    一、增刪改

        

 

    二、操作符

        

 

    三、查詢

       1. 基本操作

           

 

       2. 聚合查詢

           

 

       3. 管道操作:MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢後將結果傳遞給下一個管道處理

           

 

    五、管理

        

         

 

    六、索引和高可用

       1. 索引

簡介
作用:索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取數據時必須掃描集合中的每個文件並選取那些符合查詢條件的記錄。索引主要用於排序和檢索。
MongoDB使用 ensureIndex() 方法來創建索引,ensureIndex()方法基本語法格式如下所示:
  db.collection.createIndex(keys, options)
  語法中 Key 值為要創建的索引欄位,1為指定按升序創建索引,如果你想按降序來創建索引指定為-1,也可以指定為hashed(哈希索引)。

索引屬性:
    background:是否後臺構建索引,在生產環境中,如果數據量太大,構建索引可能會消耗很長時間,為了不影響業務,可以加上此參數,後臺運行同時還會為其他讀寫操作讓路,這個建議配置為true開啟,這樣來提高效率。

    unique:是否為唯一索引

索引類型:
    單鍵索引:
        在某一個特定的屬性上建立索引,例如:db.users. createIndex({age:-1});
        1,mongoDB在ID上建立了唯一的單鍵索引,所以經常會使用id來進行查詢;
        2,在索引欄位上進行精確匹配、排序以及範圍查找都會使用此索引;

    複合索引:
        在多個特定的屬性上建立索引,例如:db.users. createIndex({username:1,age:-1,country:1});
        1,複合索引鍵的排序順序,可以確定該索引是否可以支持排序操作;
        2,在索引欄位上進行精確匹配、排序以及範圍查找都會使用此索引,但與索引的順序有關;
        3,為了性能考慮,應刪除存在與第一個鍵相同的單鍵索引

    多鍵索引:
        在數組的屬性上建立索引,例如:db.users. createIndex({favorites.city:1});

    哈希索引:
        不同於傳統的B-樹索引,哈希索引使用hash函數來創建索引。
        1,在索引欄位上進行精確匹配,但不支持範圍查詢,不支持多鍵hash;
        2,Hash索引上的入口是均勻分佈的,在分片集合中非常有用;

優化
1,開啟內置的查詢分析器,記錄讀寫操作效率:
    db.setProfilingLevel(n,{m}),n的取值可選0,1,2;
        0是預設值表示不記錄;
        1表示記錄慢速操作,如果值為1,m必須賦值單位為ms,用於定義慢速查詢時間的閾值;
        2表示記錄所有的讀寫操作;

2,分析慢速查詢
    就是查看執行計劃,使用explain分析慢速查詢。
    explain的入參可選值為:
        "queryPlanner":是預設值,表示僅僅展示執行計劃信息;
        "executionStats":表示展示執行計劃信息同時展示被選中的執行計劃的執行情況信息;
        "allPlansExecution":表示展示執行計劃信息,並展示被選中的執行計劃的執行情況信息,還展示備選的執行計劃的執行情況信息

3,合理建立索引
    建立索引的規則:
        1,索引很有用,但是它也是有成本的——它占記憶體,讓寫入變慢;
        2,mongoDB通常在一次查詢里使用一個索引,所以多個欄位的查詢或者排序需要複合索引才能更加高效;
        3,複合索引的順序非常重要,例如此腳本所示:
        4,在生成環境構建索引往往開銷很大,時間也不可以接受,在數據量龐大之前儘量進行查詢優化和構建索引;
        5,避免昂貴的查詢,使用查詢分析器記錄那些開銷很大的查詢便於問題排查;
        6,通過減少掃描文檔數量來優化查詢,使用explain對開銷大的查詢進行分析並優化;
        7,索引是用來查詢小範圍數據的,不適合使用索引的情況:
            1,每次查詢都需要返回大部分數據的文檔,避免使用索引
            2,寫比讀多

    優化目標:
        1,根據需求建立索引
        2,每個查詢都要使用索引以提高查詢效率, winningPlan. stage 必須為IXSCAN ;
        3,追求totalDocsExamined = nReturned

 

       2. 高可用

1,可複製集
    可複製集是跨多個MongDB伺服器(節點)分佈和維護數據的方法。mongoDB可以把數據從一個節點複製到其他節點併在修改時進行同步,集群中的節點配置為自動同步數據;舊方法叫做主從複製,mongoDB 3.0以後推薦使用可複製集;
    作用:
        1,避免數據丟失,保障數據安全,提高系統安全性;
            (最少3節點,最大50節點)
        2,自動化災備機制,主節點宕機後通過選舉產生新主機;提高系統健壯性;
            (7個選舉節點上限)
        3,讀寫分離,負載均衡,提高系統性能;
        4,生產環境推薦的部署模式;
    原理:
        數據同步:從節點與主節點保持長輪詢;1.從節點查詢本機oplog最新時間戳;2.查詢主節點oplog晚於此時間戳的所有文檔;3.載入這些文檔,並根據log執行寫操作;
        阻塞複製:與writeconcern相關,不需要同步到從節點的策略(如: acknowledged Unacknowledged 、w1),數據同步都是非同步的,其他情況都是同步;
        心跳機制:成員之間會每2s 進行一次心跳檢測(ping操作),發現故障後進行選舉和故障轉移;
        選舉制度:主節點故障後,其餘節點根據優先順序和bully演算法選舉出新的主節點,在選出主節點之前,集群服務是只讀的;
    註意:
        MongoDB複製集里Primary節點是不固定的,所以生產環境千萬不要直連Primary。

2,分片集群
    分片是把大型數據集進行分區成更小的可管理的片,這些數據片分散到不同的mongoDB節點,這些節點組成了分片集群。
    作用:
        1,數據海量增長,需要更大的讀寫吞吐量:存儲分散式
        2,單台伺服器記憶體、cpu等資源是有瓶頸的:負載分散式
    註意:分片集群是個雙刃劍,在提高系統可擴展性和性能的同時,增大了系統的複雜性,所以在實施之前請確定是必須的。
    容易發生的狀況:
        請求分流:通過路由節點將請求分發到對應的分片和塊中;
        數據分流:內部提供平衡器保證數據的均勻分佈,數據平均分散式請求平均分佈的前提;
        塊的拆分:3.4版本塊的最大容量為64M或者10w的數據,當到達這個閾值,觸發塊的拆分,一分為二;
        塊的遷移:為保證數據在分片節點伺服器分片節點伺服器均勻分佈,塊會在節點之間遷移。一般相差8個分塊的時候觸發;
        
    分片註意點:
        熱點 :某些分片鍵會導致所有的讀或者寫請求都操作在單個數據塊或者分片上,導致單個分片伺服器嚴重不堪重負。自增長的分片鍵容易導致寫熱點問題;
        不可分割數據塊:過於粗粒度的分片鍵可能導致許多文檔使用相同的分片鍵,這意味著這些文檔不能被分割為多個數據塊,限制了mongoDB均勻分佈數據的能力;
        查詢障礙:分片鍵與查詢沒有關聯,造成糟糕的查詢性能。 
    建議:
        1,不要使用自增長的欄位作為分片鍵,避免熱點問題;
        2,不能使用粗粒度的分片鍵,避免數據塊無法分割;
        3,不能使用完全隨機的分片鍵值,造成查詢性能低下;
        4,使用與常用查詢相關的欄位作為分片鍵,而且包含唯一欄位(如業務主鍵,id等);
        5,索引對於分區同樣重要,每個分片集合上要有同樣的索引,分片鍵預設成為索引;分片集合只允許在id和分片鍵上創建唯一索引;

 

三:MongoDB API

    一、客戶端連接

 1 public class MongoDBClient {
 2     public static Logger logger = Logger.getLogger(MongoDBClient.class.getName());
 3     protected static MongoClient mongoClient;
 4 
 5     /**
 6      * 封裝MongoDB連接
 7      * 
 8      * @param driver     遠程連接URL
 9      * @param database   資料庫
10      * @param collection 集合
11      * @return
12      */
13     public synchronized static MongoCollection<Document> getMongoClient(String driver, String database,
14             String collection) {
15         if (mongoClient == null) {
16             // 連接到MongoDB客戶端
17             mongoClient = MongoClients.create(driver);
18             if (mongoClient != null) {
19                 logger.info("mongoClient init success!");
20                 // 連接指定資料庫
21                 MongoDatabase db = mongoClient.getDatabase(database);
22                 if (database != null) {
23                     logger.info("正在使用" + database + "資料庫");
24                     // 連接到指定集合
25                     return db.getCollection(collection);
26                 }
27             } else {
28                 logger.info("mongoClient init failed!");
29             }
30         }
31         return null;
32     }
33 }

 

    二、增刪改

 1 public class MongoDBClient {
 2     /**
 3      * 插入文檔
 4      */
 5     @Test
 6     public void insert() {
 7         MongoCollection<Document> collection = getMongoClient("mongodb://admin:000000@localhost:27017",
 8                 "studentmanager", "info");
 9         /**
10          * 插入一條
11          */
12         // 追加插入一條
13         collection.insertOne(new Document("name", "zhangsan").append("age", 18).append("gneder", "男"));
14 
15         // 插入json數據
16         String json = "{" + "'name':'lisi'" + "'age':'20'" + "'gender':'女'" + "}";
17         collection.insertOne(Document.parse(json));
18 
19         /**
20          * 插入多條
21          */
22         List<Document> documents = new ArrayList<Document>();
23         for (int i = 0; i < 4; i++) {
24             documents.add(new Document("i", i));
25         }
26         collection.insertMany(documents);
27     }
28 
29     /**
30      * 修改文檔
31      */
32     @Test
33     public void update() {
34         MongoCollection<Document> collection = getMongoClient("mongodb://admin:000000@localhost:27017",
35                 "studentmanager", "info");
36 
37         // 修改一條
38         collection.updateOne(new Document("name", "zhangsan"), new Document("$set", new Document("age", 20)));
39 
40         // 修改多條
41         collection.updateMany(new Document("i", new Document("$lt", 2)),
42                 new Document("$set", new Document("name", "wangwu").append("age", 10)));
43     }
44 
45     /**
46      * 刪除文檔
47      */
48     @Test
49     public void delete() {
50         MongoCollection<Document> collection = getMongoClient("mongodb://admin:000000@localhost:27017",
51                 "studentmanager", "info");
52 
53         // 刪除一條
54         collection.deleteOne(new Document("name", "zhangsan"));
55 
56         // 刪除多條
57         collection.deleteMany(new Document("i", new Document("$gte", 2)));
58     }
59 }

 

    三、查詢

 1 public class MongoDBClient {
 2     /**
 3      * 查詢所有
 4      */
 5     @Test
 6     public void findAll() {
 7         MongoCollection<Document> collection = getMongoClient("mongodb://admin:000000@localhost:27017",
 8                 "studentmanager", "info");
 9         // 獲取迭代器
10         FindIterable<Document> find = collection.find();
11         // 獲取游標
12         MongoCursor<Document> iterator = find.iterator();
13         // 通過游標遍歷檢索為文檔集合
14         while (iterator.hasNext()) {
15             System.out.println(iterator.next());
16         }
17     }
18 
19     /**
20      * 條件查詢
21      */
22     @Test
23     public void findByConditions() {
24         MongoCollection<Document> collection = getMongoClient("mongodb://admin:000000@localhost:27017",
25                 "studentmanager", "info");
26         // 範圍查詢
27         // where gender = 男
28         collection.find(Filters.eq("gender", "男"));
29         // where age=10,age=18,age=20
30         collection.find(Filters.in("age", 10, 18, 20));
31 
32         // 邏輯查詢
33         // where age >= 16 and age <= 20
34         collection.find(Filters.and(Filters.gte("age", 16), Filters.lte("age", 20)));
35         // where age > 20 or age < 16
36         collection.find(Filters.or(Filters.gt("age", 20), Filters.lt("age", 16)));
37 
38         // 類型查詢
39         collection.find(Filters.type("name", "string"));
40 
41         // 模糊查詢:name中是以zhang開頭的
42         FindIterable<Document> find = collection.find(Filters.regex("name", "zhang*"));
43         MongoCursor<Document> iterator = find.iterator();
44         while (iterator.hasNext()) {
45             Document document = iterator.next();
46             System.out.println(document.get("name"));
47         }
48     }
49 
50     /**
51      * 排序和分頁
52      */
53     @Test
54     public void sortAndLimit() {
55         MongoCollection<Document> collection = getMongoClient("mongodb://admin:000000@localhost:27017",
56                 "studentmanager", "info");
57 
58         /**
59          * 排序
60          */
61         // 升序排序:where gender="男" order by age asc
62         collection.find(Filters.eq("gender", "男")).sort(Sorts.ascending("age"));
63         // 降序排序:where gender="男" order by age desc
64         collection.find(Filters.eq("gender", "男")).sort(Sorts.descending("age"));
65         // 多條件排序:where gender="男" order by age asc and score desc
66         collection.find(Filters.eq("gender", "男"))
67                 .sort(Sorts.orderBy(Sorts.ascending("age"), Sorts.descending("score")));
68 
69         /**
70          * 分頁
71          */
72         FindIterable<Document> skip = collection.find(Filters.gt("age", 16)).limit(3).skip(2);
73         MongoCursor<Document> iterator = skip.iterator();
74         while (iterator.hasNext()) {
75             System.out.println(iterator.next());
76         }
77     }
78 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Autohotkey是一款輕量小眾但高效免費開源的windows熱鍵腳本語言,游戲操縱、滑鼠操作、鍵盤快捷重定義,快捷短語等等,只有你想不到,沒有它做不到,神器中的神器呀,相見恨晚。 ...
  • 1. Kubernetes是什麼 Kubernetes中文版資料 Kubernetes是容器集群管理系統,是一個開源的平臺,可以實現容器集群的自動化部署、自動擴縮容、維護等功能。 通過Kubernetes我們可以: 快速部署應用 快速擴展應用 無縫對接新的應用功能 * 節省資源,優化硬體資源的使用 ...
  • 為什麼要用索引? 一般的應用系統,讀寫比例在10:1左右,插入操作和一般的更新操作很少出現性能問題,在生產環境中,我們遇到最多的,也是最容易出問題的,還是一些複雜的查詢操作,因此對查詢語句的優化顯然是重中之重。說起加速查詢,就不得不提到索引了。 索引是什麼? 索引在MySQL中也叫做“鍵”,是存儲引 ...
  • Redis集群是Redis提供的分散式資料庫方案,集群通過分片來進行數據共用,並提供複製和故障轉移操作。 一個Redis集群通常由多個節點組成,在剛開始的時候每個節點都是相互獨立的,他們處於一個只包含自己的集群當中,我們通過使用CLUSTER MEET命令將節點連接到一起,構成一個包含多節點的集群。 ...
  • 結構化查詢語言(SQL)是第四代編程語言的典型,這種命令式的語言更像一種指令,使用它,你只需要告訴電腦“做什麼”,而不用告訴電腦“怎麼做”。第四代編程語言普遍具有簡單、易學、能更快的投入生產等優點,但也失去了部分第三代編程語言(C,C++,Java等)的靈活性。PL/SQL 在 SQL 的基礎上... ...
  • 2020-06-09 19:31:01 一、疑問 前段時間;QQ群里有人對“這個表(0,4)這行數據我做了update操作,查看索引的page數據,看到索引一直指向(0,4),用ctid='(0,4)'查詢業務表是查不到數據的;然後我做了表的vacuum,reindex甚至drop/create i ...
  • 1. API基本概念 Flink程式可以對分散式集合進行轉換(例如: filtering, mapping, updating state, joining, grouping, defining windows, aggregating) 集合最初是從源創建的(例如,從文件、kafka主題或本地內 ...
  • 參考:1、vmware安裝centos ,ping 百度 成功https://www.cnblogs.com/jpwz/p/10466826.html 2、vmware克隆centos7後網路配置和主機名問題https://blog.csdn.net/mo_ing/article/details/8 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...