分佈式系列十五: MongoDB數據庫

MongoDB 是基於分佈式文件存儲的數據庫. 開發語言是C++. 具備高性能,可擴展的特色. 是NoSql中最像關係數據庫的.javascript

什麼是NoSql

NoSQL 是 Not only SQL 的縮寫. 是對不一樣於傳統的關係數據庫的數據管理系統的統稱. 通常用來存儲超大規模數據, 且數據不須要有具體的模式, 能夠橫向擴展.java

與關係數據庫的對比

  • RDB 存儲結構化數據, 數據結構之間可能存在約束; NoSQL無固定模式,通常採用k-v方式, 無表關聯等約束.
  • RDB 有規範的 SQL 語言; NoSQL無
  • RDB 有嚴格一致性和事務特徵; NoSQL只要求最終一致性, 無事務屬性
  • 比 RDB 具備高性能, 可擴展和可伸縮性

NoSQL 分類

  • 列存儲: HBase ; Cassandra ; HyperTablemysql

    按列查詢性能有優點; 按列存儲方便壓縮正則表達式

  • 文檔存儲: MongoDB, CounchDBredis

    文檔結構存儲, 相似Json, 能夠爲某些字段創建索引. 相似關係數據庫.spring

  • key-value 存儲: MemCache,Redissql

  • 圖存儲: Neo4J
  • 對象存儲:
  • XML數據庫mongodb

CAP 理論

知足 AP.數據庫

MongoDB 與 RDB 的概念對比

關係數據庫 MongoDB 說明
DataBase DataBase 數據庫
Table Collection 數據表/集合
Row Document 數據行/文檔
Column Field 數據列/數據字段
Index Index 索引
Primary Key Object ID 主鍵/MongoDB對象標識

MongoDB 存儲的格式是BSON, 是二進制的Json.數組

MongoDB 的數據類型

略,

MongoDB 集羣

包含: RouteServer(路由 對應的執行文件爲Mongos.exe), ConfigServer(配置) , ReplicaSets (副本集合 對應的執行文件爲mongod.exe), 仲裁Server

集羣模式

  • 主從 master/slave 與mysql主從, 或者redis主從同樣
  • 副本集 master/slave/arbiter(仲裁) 相似redis的sentinel機制
  • 混合模式

步驟

  • 主從配置(主節點掛掉就不可用)

mongo.cfg 文件中

# 主配置
master=true
source=192.1.68.1.111:21897

# 從配置
slave=true
source=192.1.68.1.111:21897
  • 副本集一(仲裁節點單點故障會致使服務不可用)
replset=shard002  #同一集中的配置同樣

執行命令:

cfg={_id:"shard001",members:{{_id:0,host:'192.168.1.111:27897',priority:9},{_id:0,host:'192.168.1.112:27897',priority:1},{_id:0,host:'192.168.1.112:27897',arbiterOnly:true}}}

rs.initiate(cfg);
  • 副本集二

配置與副本集同樣,命令執行以下:

cfg={_id:"shard002",members:{{_id:0,host:'192.168.1.111:27899'},{_id:0,host:'192.168.1.112:27899'},{_id:0,host:'192.168.1.112:27899'}}}

rs.initiate(cfg);
  • 混合使用

    1. 前置: M-S-S 的副本集以及M-S-A的副本集

    2. 新增一個副本集, 爲config服務, 配置中添加節點並添加變量啓動

    configsvr=true
    1. 新增路由服務器(只須要logpath,不須要dbpath), mongos -f ..啓動
    configdb=configrs/192.168.1.111:28102,192.168.1.112:28102,192.168.1.113:28102
    1. 目前有了一組配置服務器, 一組路由服務器, 兩組副本集服務器

      • 關聯路由/shard: sh.addShard("shard001/192.168.1.111:27897") 以及 sh.addShard("shard002/192.168.1.111:27899")

      • 啓用切片: use dbName sh.enableSharding("dbNzame")
      • sh.shardCollections("dbName.collectionName",{"name","hashed"})

      • 分片的服務器須要使用--shardsvr=true 因此須要在數據副本集的cfg中添加shardsvr=true

MongoDB的適用場景和不適用場景

適用於:

  • 實時插入, 更新和查詢.
  • 數據緩存, mongoDB的索引會同步到內存, 數據存儲在磁盤中
  • 大量數據存儲,數據粒度較大, 數量較多
  • 高伸縮性場景
  • 對象或Json存儲

不適用於:

  • 事務性系統, 銀行會計系統等
  • BI 數據, BI數據庫更合適
  • 複雜SQL查詢

安裝

參看官方文檔

  • fork啓動: mongod --dbpath=/opt/mongo/data/ --logpath=/opt/mongo/log/mongo.log --logappend --bind_ip=192.168.1.111 --fork

可使用配置文件將參數配置到 mongo.cfg 相似properties文件的格式. 而後命令 mongod -f mongo.cfg 啓動.

命令

  • use DBName; 轉到數據庫, 或者建立
  • db.DocName.insert({name:"docname"}) 插入數據
  • db.DocName.find() 或者 db.DocName.findOne() 查找
  • db.DocName.update({name:"docname"},{$set:{age:18}},true,true) 修改, 第三個參數爲true則在查找不到記錄的條件下新插入一條數據, 並設置屬性列的值, 不影響其餘屬性; 第四個參數true表示批量
  • var p = db.doc.findOne(); db.doc.update(p,{name:"other"}) 會刪除其餘的列值
  • db.doc.remove({age:0}) 刪除
  • db.doc.drop() 刪除集合
  • db.dropDatabase() 刪除庫

  • show collections 查看集合
  • show dbs 查看數據庫
  • db.doc.insert()db.doc.save() 前者不容許鍵值重複, 後者若鍵值重複則插入

  • 更新時候,第二個參數的模式

    • $set:設置
    • $unset:刪除
    • $incr : 增長
    • $push: 數組增長元素
    • $pushAll: 批量增長數組元素
    • $addToSet: 有則不插入, 無則插入
    • $pop : 數組刪除其中的元素, 1爲刪除最後一個, -1爲刪除第一個
    • $pull: 數組刪除指定的值, $pullAll爲批量操做
  • $each 迭代
  • runCommand() 函數, 實現組合操做

  • db.doc.find({條件},{指定鍵}) 查詢模式
  • db.doc.find({age:{$gte:18,$lte:25}},{_id:0,name:1}) 範圍查找,顯式name列

    $lt, $lte,$gt , $gte,$ne, $in , $nin, $or

  • 支持正則表達式, find({name:/li/i})
  • $not
  • $all 和 index ; index 使用.0 .1 這樣的方式表示
  • $size 數組大小
  • $slice 數組切割
  • limit(5) 限制顯式條數
  • skip(10) 跳過條數
  • sort({age:1}) 排序, 1是正序, -1是逆序
  • hasNext() 結合 while 實現遊標 , 注意: 遊標默認10分鐘會銷燬

    var persons = db.person.find();
    while(persons.hasNext()){
        obj = person.next();
        print(obj.name);
    }
  • db.doc.find({$query:{name:"jim"},$snapshot:true}) 快照查詢

    $query , $orderby, $maxscan , $min, $max, $hint , $explain , $snapshot

  • db.map.find({{gis:{$near:[70,180]}},{_id:0,gis:1}).limit(3) 查出離給定左表最近的是哪一個點
  • db.map.find({gis:{$within:{$box:[[50,50],[100,100]}}},{_id:0,gis:i}) 查詢全部在兩個座標爲對角線內的全部點
  • db.map.find({gis:{$with:{$center:[[56,80],50]}}},{_id:0,gis:i}) 找出圓心爲[56,80]半徑50內的全部點

  • count() 查找計數
  • db.runCommand({distinct:"persons",key:"country"}).values persons中有多少個國家, 去重後的值
  • 分組

db.runCommand(
    {
        group:{
            ns:"集合名字",
            key:"分組鍵",
            initial:"初始化累加器",
            $reduce:"分解器"
            condition: "條件",
            finalize:"完成器"
        }
    }
);
  • db.createUser({user:"admin",pwd:"123",roles:[{role:"dbAdmin",db:"dbName"}]})

系統相關的需先使用 use admin 切換到系統庫 好比: 查詢用戶db.system.users.find()

  • db.system.users.remove({use:"admin"}) 刪除用戶
  • db.runCommand({usersInfo:"admin",showPrivileges:true}) 查看用戶權限
  • db.changeUserPassword("admin","123456") 修改密碼
  • db.auth("admin","123456") 啓用用戶
  • rs.slaveOk() 設置容許在二級節點查詢, 從節點上設置

mongodb 客戶端使用

使用mongodb的官方驅動

  • 依賴包
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.10.2</version>
</dependency>
  • 代碼
MongoClient mongo = new MongoClient("127.0.0.1", 27017);
DB db = new DB(mongo, "User");

DBCollection hiveUser = db.getCollection("hiveUser");
DBCursor cursor = hiveUser.find();
for (DBObject c : cursor) {
    System.out.println(c);
}

三方框架

  • 依賴包
<!-- https://mvnrepository.com/artifact/org.mongodb.morphia/morphia -->
<dependency>
    <groupId>org.mongodb.morphia</groupId>
    <artifactId>morphia</artifactId>
    <version>1.3.2</version>
</dependency>
  • 代碼
Morphia morphia = new Morphia();
Datastore ds =morphia.createDatastore(new MongoClient("127.0.0.1", 27017),"hiveUser");
ds.save(new User("Test",3,19,0));
Query<User> query = ds.createQuery(User.class);
List<User> user = query.asList();
System.out.println(user.size());

Spring-data-mongodb

  • 依賴包
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
  • 配置
spring.data.mongodb.uri=mongodb://localhost/hiveUser

具體配置能夠參考 org.springframework.boot.autoconfigure.mongo.MongoProperties

  • 代碼
@Component
public class SpringDataMongoTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    public void print(){
        Set<String> collections = mongoTemplate.getCollectionNames();
        System.out.println(collections);

        //查詢
        Query query = new Query();
        List<User> list = mongoTemplate.find(query,User.class);
    }
}
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Document("hiveUser") //指定collection
public class User {
    private String name;
    private Integer id;
    private Integer age;
    private Integer sex;
}

注意: 操做實體上須要添加 @Document(collection="hiveUser") 才能夠被查詢.

相關文章
相關標籤/搜索