MongoDB入門實踐

MongoDB入門實踐

簡單介紹MongoDB,包括MongoDB的使用場景、和MySQL的對比、安裝部署、Java客戶端訪問及總結前端

MongoDB?

咱們遵循需求驅動技術的原則,經過一個場景來引入MongoDB,在現行業務需求下考慮下面三個問題:java

  • 爲何要使用MongoDB?
  • MongoDB是一個什麼樣的產品?
  • 它能作什麼?

Situation(場景)

以公司站點報告業務場景(當前其實已換成hdfs):mysql

業務流程

  • 從Server獲取站點日誌;
  • 日誌分析後入MySQL庫(8~9個字段,日期和多個維度字段和多個指標字段),天天數據量大約50w;
  • 依照維度字段、指標字段、日期(通常是天天)聚合查詢,查詢到的結果集(前1000條)存入Redis供前端展示;
  • 目前天天展現的報告實際是當天凌晨經過離線計算(相對時間較長)獲得的結果。

運行狀態

  • 數月時間運行後,MySQL庫當中的數據量倍增,整個數據庫的查詢效率大大降低;
  • Redis的內存佔用逐漸上升,並大量佔用虛擬內存,致使服務器崩潰。
  • 而且因爲Redis自己並不支持相似關係數據庫的分頁動做,只能存儲少許數據做爲前端展示,而不能一頁一頁展現整個結果集查詢的結果。

Problem(問題)

原有的解決方案(MySQL+Redis)linux

  • MySQL存儲的數據量太大致使查詢效率過低;
  • 把Redis看成存儲使用,致使對虛擬內存佔用過高;
  • Redis自己不支持關係型數據庫的分頁,實際展示數據並不完整。

MongoDB特性spring

  • 大數據量存儲,單實例TB級別
  • 高性能持久化數據:支持內存數據模型(減小IO),支持索引;
  • 高可用性(副本集):自動故障切換(automatic failover),數據備份(data redundancy);
  • 自動擴容:自動分片,副本集保證最終一致性、低延遲高流量。

如此看來,MongoDB太強大了,彷佛一種招招要了MySQL命的感受,不過千萬別這麼想,畢竟術業有專攻!
那如今就讓咱們來看看MongoDB的廬山真面目。sql

先睹爲快

插播一段廣告,這裏引用官方網站上MongoDB的查詢示例比較下MySQL和MongoDB。mongodb

MongoDB & MySQL查詢比較數據庫

  • MySQL查詢(SELECT _id,name,address FROM users WHERE age>18 LIMIT 5)
    sql-select
  • MongoDB查詢(db.users.find( { age: { $gt: 18 } }, { name: 1, address: 1 } ).limit(5))
    mongodb-find

有沒有一種他們倆長的真像的感受,沒錯你答對了,MongoDB被稱做是最像關係型數據庫的NOSQL數據庫。json

How To Use

舒適提示windows

  • MongoDB存在企業版和社區版,企業版是收費版本(咱是窮人,天然不用收費版了)
  • 推薦安裝64位
  • 推薦Linux下安裝
  • Windows版本可用於調試

官方網站

官網
官網ORG

下載

  • 選擇Current,Previous,Development
  • 選擇Windows,Linux,Max OS X,Solaris
  • 選擇下載格式

文檔

  • 選擇下載在線
  • 選擇文檔版本(2.6)
  • 選擇文檔格式

安裝&啓動&關閉

Linux

以Linux ReadHat爲例

安裝

  • 建立文件mongdb.repo,路徑:/etc/yum.repos.d/mongodb.repo
  • 配置mongdb.repo:
    64位:
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1

32位:

name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686/
gpgcheck=0
enabled=1
  • yum安裝完整版: sudo yum install -y mongodb-org

啓動

  • selinux開啓MongoDB tcp端口: semanage port -a -t mongod_port_t -p tcp 27017
  • 關閉SELINUX: SELINUX=disabled
  • 啓動:sudo service mongod start
  • client: 執行mongo命令便可

關閉

  • sudo service mongod stop
  • 進入mongo的窗口:use admin; db.shutdownServer()

Windows 64位

安裝

  • 查看windows版本:wmic os get osarchitecture**
  • windows msi或zip(解壓便可,好比目錄:D:\Program Files\mongodb)
  • 將bin目錄加入到classpath

啓動

  • 解壓目錄下建立兩級目錄:data\db,data\log
  • 啓動server(mongod,mongos(分片集羣客戶端))
    mongod.exe --dbpath "D:\Program Files\mongodb\data"(若是路徑中存在空格,請使用""引用路徑)
  • client(* driver,mongo)
    mongo

關閉

  • Ctrl+C
  • 進入mongo的窗口:use admin; db.shutdownServer()

通常狀況下,對於開發人員,咱們更加關心MongoDB的Driver,和Mysql同樣,它天然是多語言版的,做爲Java開發人員,咱們介紹MongoDB Java Driver。

MongoDB Java Driver

獲取Driver(pom)

<dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>2.13.0</version>
        </dependency>

CRUD

咱們以java代碼方式操做MongoDB,而後用圖形化的工具查看結果.

insert

  • 插入文檔記錄:{"name" : "someone" , "age" : 18 , "gender" : 1 , "address" : { "country" : "china" , "city" : "shanghai"}}
@Test
    public void insert() throws Exception {
        // 新建客戶端.
        MongoClient client = new MongoClient("127.0.0.1", 27017);
        // 獲取DB.
        DB db = client.getDB("testDB");
        // 獲取文檔集.
        DBCollection collection = db.getCollection("demo");
        // 一行記錄.
        // json: {"name" : "someone" , "age" : 18 , "gender" : 1 , "address" : { "country" : "china" , "city" : "shanghai"}}
        BasicDBObject user = new BasicDBObject("name", "someone")
                .append("age", 18)
                .append("gender", 1)
                .append("address", new BasicDBObject("country", "china").append("city", "shanghai"));

        System.out.println(collection.insert(user));
        // 關閉客戶端
        client.close();
    }

insert-demo

query

  • 查詢 條件:{ "name" : "someone"}的結果集
@Test
    public void query() throws Exception {
        // 新建客戶端.
        MongoClient client = new MongoClient("127.0.0.1", 27017);
        // 獲取DB.
        DB db = client.getDB("testDB");
        // 獲取文檔集.
        DBCollection collection = db.getCollection("demo");
        // 條件: { "name" : "someone"}
        BasicDBObject match = new BasicDBObject("name", "someone");
        // 執行查詢並打印結果集列表.
        System.out.println(collection.find(match).toArray());
        // 關閉客戶端
        client.close();
    }

insert-demo

update

  • 更新 條件: {"name" : "someone"} set: {"age": 28}
@Test
    public void update() throws Exception {
        // 新建客戶端.
        MongoClient client = new MongoClient("127.0.0.1", 27017);
        // 獲取DB.
        DB db = client.getDB("testDB");
        // 獲取文檔集.
        DBCollection collection = db.getCollection("demo");
        // 條件.
        // json: {"name" : "someone"}
        BasicDBObject match = new BasicDBObject("name", "someone");

        // set:{"age": 28}
        BasicDBObject updatedValue = new BasicDBObject();
        updatedValue.put("age", 28);
        DBObject updateSetValue = new BasicDBObject("$set", updatedValue);

        // 執行更新並打印.
        //update api: DBObject q, DBObject o, boolean upsert, boolean multi.
        //upsert:若爲true,沒有找到匹配的記錄時會執行新增一條記錄,false則不作任何處理.
        //multi:若爲false,表示只更新查詢到的一條記錄,true則表示更新全部匹配記錄.
        System.out.println(collection.update(match, updateSetValue, false, true));
        // 關閉客戶端
        client.close();
    }

update-demo

delete

  • 刪除 條件:{"name" : "someone"}
@Test
    public void delete() throws Exception {
        // 新建客戶端.
        MongoClient client = new MongoClient("127.0.0.1", 27017);
        // 獲取DB.
        DB db = client.getDB("testDB");
        // 獲取文檔集.
        DBCollection collection = db.getCollection("demo");
        // 條件.
        // json: {"name" : "someone"}
        BasicDBObject match = new BasicDBObject("name", "someone");
        // 刪除匹配記錄.
        System.out.println(collection.remove(match));
        // 關閉客戶端
        client.close();
    }

delete-demo

經常使用Api

經常使用類

  • MongoClient 客戶端鏈接抽象
  • DB 文檔庫
  • DBCollection 文檔集
  • DBObject 文檔對象基類
  • BasicDBObject 基礎文檔對象
  • BasicDBList 基礎文檔列表對象

經常使用方法

  • DBCollection: find(),update(),insert(),remove(), MongoDB大部分操做數據有關的Api都是基於此類.
  • MongoClient: getDB(), close()
  • DB: getCollection()
  • DBObject: put()
  • BasicDBObject: append()
  • BasicDBList: add()

第三方封裝(Third Party Frameworks and Libraries)

基於MongoDB的driver,有不少第三方封裝的包,好比:

  • Spring MongoDB
    spring-mongodb
  • Jongo
    JONGO

大多數框架都支持以POJO的方式開發基於MongoDB的應用!

MongoDB & MySQL

Indicator MongoDB MySQL
大數據支持 較強 通常
ACID 部分支持 所有
SQL特性 非結構化,支持部分SQL語言特性 徹底支持SQL語言規範,標準化,交互性強
擴展 自動擴展 有必定的硬件成本,須要第三方程序
應用靈活性 通常

MongoDB與MySQL是互補的關係
MongoDB沒有全面的ACID支持,所以不能將有事務場景的業務底層存儲從MySQL改成NOSQL

MongoDB最佳實踐(不全)

  • 版本更新
  • 採用Replicaton Sets(副本集)部署
  • 採用64位系統部署
  • 默認開啓journaling日誌
  • 謹慎分片sharding
  • 不要當作Sql數據庫使用
  • 明確數據須要的一致性和可靠性
  • 按照真實業務場景全面測試
  • 採用固定的Schema設計(某個DBCollection下的文檔結構一致)
  • 採用索引(和其它關係型數據使用索引的意義是一致的)

QA

相關文章
相關標籤/搜索