NoSQL简介

NoSQL简介

MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案

NoSQL=NOT Only SQL
ACID规则:

  1. A(Atomicity)原子性 要么全做完,要么都不做
  2. C(Consistency)一致性 a+b=10;a改变,b一定也要改变
  3. I(Isolation)独立性 事物之间不会互相影响
  4. D(Durability)持久性 修改永久有效
分布式计算的优点:
  • 可靠性
  • 可扩展性
  • 资源共享
  • 灵活性
  • 更快的速度
  • 开放系统
  • 更高的性能
缺点
  • 更少的软件支持
  • 网络设施
  • 安全性
什么是NoSQL

NoSQL,指的是非关系型的数据库,用于超大规模数据的存储

为什么使用NoSQL?

CAP定理(CAP theorem)
三点:

  • 一致性(Consistency):所有节点在同一时间具有相同的数据
  • 可用性(Availability):保证每一个请求不管成功呢或者是失败都有响应
  • 分隔容忍(Partition tolerance):系统中任何信息的丢失或者失败都有响应
CA/CP/AP

CA-单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大
CP-满足一致性,分区容忍性的系统,通常性能不是特别高
AP-满足可用性,分区容忍性的系统,可能对一致性要求要低一些

ACID vs BASE
ACIDBASE
原子性(Atomicity)基本可用(Basically Available)
一致性(Consistency)软状态/柔性事务(Soft state)
隔离性(Isolation)最终一致性(Eventual consistency)
持久性(Durable)
MongDB简介

MongoDB是由C++编写的,是一个基于分布式文件存储的开源数据库系统
在高负载的情况下,添加更多的节点,可以保证服务器性能
MongoDB旨在为WEB应用程序提供可扩展的高性能数据存储解决方案

MongoDB概念解析
MongoDB概念解析
SQL术语/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
inexindex索引
table joins表连接,MongoDB支持
primary keyprimary key主键,MongoDB自动将_id字段设置为主键
RDBMS与MongoDB对应的术语
RDBMSMongoDB
数据库数据库
表格集合
文档
字段
表联合嵌入文档
主键主键(MongoDB提供了Key为_id)
集合命名空间描述
dbname.system列出所有名字空间
dbname.system.indexes列出所有索引
dbname.system.profile包含数据库概要(profile)信息
dbname.system.users列出所有可访问数据库的用户
dbname.local.sources包含复制对端(slave)的服务器信息和状态
MongoDB数据类型
数据类型描述
String字符串,存储数据常用懂得数据类型,在MongoDB中,UTF-8编码的字符串才是合法的
Integer整型数值,用于存储数值,根据你所采用的服务器,可分为32位或64位
Boolean布尔值,用于存储布尔值
Double双精度浮点值,用于存储浮点值
Min/Max keys将一个值与BSON(二进制的JSON)元素的最低值和最高值相对比
Array用于将数组或列表或多个值存储为一个键
Timestamp时间戳,记录文档修改或添加的具体时间
Object用于内嵌文档
Null用于创建空值
Symbol符号,该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言
Date日期时间时间,用UNIX时间格式来存储当前日期或时间,你可以指定自己的日期时间
Object ID对象ID,用于创建文档的ID
Binary Data二进制数据,用于存储二进制数据
Code代码类型,用于在文档中存储JavaScript代码
Regular expression正则表达式类型,用于存储正则表达式
MongoDB连接
连接实例
mongodb://localhost  
mongodb://fred:foobar@localhost
mongodb://fred:foobar@localhost/baz
mongodb:///example.com:27017,example2.com:27017  
mongodb://localhost,localhost:27018,localhost:27019  
mongodb://host1,host2,host3/?connect=direct;slaveOk=true  
mongodb://localhost/?safe=true
mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000
MongoDB创建数据库
use DATABASE_NAME 
use runoob
db
shows dbs
db.runoob.insert({"name":"菜鸟教程"})
MongoDB删除数据库
db.dropDatabase() #删除数据库
show dbs 
use runoob
db.collection.drop()  #删除集合  

MongoDB创建集合
db.createCollection(name,options)
use test
db.createCollection("runoob")
show collections
db.createCollection("mycol",{capped:true,autoIndexId:true,size:6142800,max:10000})  

MongoDB删除集合
db.collection.drop()
MongoDB插入文档
db.COLLECTION_NAME.insert(document)
db.COLLECTION_NAME.save(document)
db.collection.insertOne(
   <document>,
  {
      writeConcern: <document>
  }
) #用于向集合插入一个新文档  
db.collection.insertMany(
  [ <document 1>,<document 2>,...],
  {
      writeConcern:<document>,
      ordered:<boolean>
  }
)   #插入多个值
db.col.find()
MongoDB更新文档
db.collection.update(
    <query>,
    <update>,
    {
        upsert:<boolean>,
        multi:<boolean>,
        writeConcern:<document>
    }
)  
db.col.update({'title':''})
MongoDB删除文档
db.collection.remove(
    <query>,
    <justOne>
)
db.collection.remove(
   <query>,
   {
       justOne:<boolean>,
       writeConcern:<document>
   }
)
db.col.insert({title:'MongoDB 教程',
               description:'MongoDB是一个Nosql数据库',
               by:'菜鸟教程',
               url:'http://www.runoob.com',
               tags:['mongodb','database','Nosql'],
               likes:100
    
})
db.col.find()
db.col.remove({'title':'MongoDB教程'})
#官方推荐  
db.inventory.deleteMany({})
db.inventory.deleteMany({status:"A"})
db.inventory.deleteOne({status:"D"})
#remove()方法并不会真正释放空间
db.repairDatabase()
db.runCommand({repairDatabas:1})
MongoDB查询文档
db.collection.find(query,projection)  
db.col.find().pretty()
#通过by和title键来查询菜鸟教程中MongoDB教程的数据  
db.col.find({"by":"菜鸟教程","title":"MongoDBj教程")}.pretty()
# MongoDB or条件语句使用关键字$or,语法如下:
db.col.find({
    $or:[
       {key1:value1},{key2:value2}
    ]
}).pretty()
db.col.find({"likes":{$gt:50},$or:[{"by":"菜鸟教程"},{"title":"MongoDB教程"}]}).pretty()
MongoDB(>)大于操作符 - $gt
db.col.find({like:{$gt:100})
select * from col where like > 100;
db.col.find({likes:{$gte:100}})
select * from col where likes >=100;
db.col.find({like:{$lt:150}})
select * from col where likes < 150;
db.col.find(likes:{$lt:200,$gt:100})
#模糊查询  
db.col.find({title:/教/})
db.col.find({title:/^教/})
db.col.find({title:/教$/})
MongoDB limit与skip方法
#读取指定数量的数据
db.COLLECTION_NAME.find().limit(NUMBER)
db.col.find({},{"title":1,_id:0}).limit(2)
#跳过指定数量的数据
db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
MongoDB 排序
db.COLLECTION_NAME.find().sort({KEY:1})
db.col.find({},{"title":1,_id:0}).sort({"likes":-1})

MongoDB 索引

MongoDB使用createIndex()方法来创建索引

db.collection.createIndex(keys,options)  
db.col.createIndex("title":1,"description":-1)  
db.values.createIndex({open:1,close:1},{backgroud:true})  
db.col.getIndexs()  #集合索引大小  
db.col.totalIndexes() #集合索引大小
db.col.dropIndexes()   #删除集合所有索引  
db.col.dropIndex("索引名称")  
db.article.aggregate(
    {
        $project:{
            _id:0,
            title:1,
            author:1
        }
    }
);
db.article.aggregate(
    {
        $project:{
            _id:0,
            title:1,
            author:1
        }
    }
);
db.article.aggregate(
   {
       $skip:5
   }
);

MongoDB 聚合
  • 什么是复制?
  • 保障数据的安全性
  • 数据高可用性
  • 灾难恢复
  • 无需停机维护(如备份、重建索引、压缩)
  • 分布式读取数据

MongoDB复制原理
mongodb复制至少需要两个节点,其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从,一主多从

  • 副本集特征:
  • N个节点的集群
  • 任何节点可作为主节点
  • 自动故障转移
  • 自动恢复

MongoDB副班集设置

mongod --port 20717 --dbpath "D:\set up\mongodb\data" --replSet rs0  
MongoDB 分片

在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求

为什么使用分片
  • 复制所有的读入操作到主节点
  • 延迟的敏感数据会在主节点查询
  • 单个副本集限制在12个节点
  • 当请求量巨大时会出现内存不足
  • 本地磁盘不足
  • 垂直扩展价格昂贵
    三个组件
    shard:用于存储实际的数据块
    Config server:mongod实例,存储整个ClusterMetadata,其中包括chunk信息
    Query Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库
MongoDB 备份与恢复
#备份
mongodb -h dbhost -d dbhome -0 dbdirectory  
#恢复
mongorestore -h <hostname><:port> -d dbname <path>
MongoDB 监控
#mongostat是mongodb自带的状态监测工具
/set up/mongodb/bin>mongostat
#mongotop也是mongodb下的一个内置工具
/set up/mongodb/bin>mongotop
MongoDB java
#驱动 mongo-java-driver-3.2.2.jar  
#连接数据库 (无密码)
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
       // 连接到 mongodb 服务
         MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
       
         // 连接到数据库
         MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
       System.out.println("Connect to database successfully");
        
      }catch(Exception e){
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
     }
   }
}
#有密码登录数据库
import java.util.ArrayList;  
import java.util.List;  
import com.mongodb.MongoClient;  
import com.mongodb.MongoCredential;  
import com.mongodb.ServerAddress;  
import com.mongodb.client.MongoDatabase;  
  
public class MongoDBJDBC {  
    public static void main(String[] args){  
        try {  
            //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址  
            //ServerAddress()两个参数分别为 服务器地址 和 端口  
            ServerAddress serverAddress = new ServerAddress("localhost",27017);  
            List<ServerAddress> addrs = new ArrayList<ServerAddress>();  
            addrs.add(serverAddress);  
              
            //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码  
            MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());  
            List<MongoCredential> credentials = new ArrayList<MongoCredential>();  
            credentials.add(credential);  
              
            //通过连接认证获取MongoDB连接  
            MongoClient mongoClient = new MongoClient(addrs,credentials);  
              
            //连接到数据库  
            MongoDatabase mongoDatabase = mongoClient.getDatabase("databaseName");  
            System.out.println("Connect to database successfully");  
        } catch (Exception e) {  
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );  
        }  
    }  
} 

#创建集合
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
      // 连接到 mongodb 服务
      MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
         
       
      // 连接到数据库
      MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
      System.out.println("Connect to database successfully");
      mongoDatabase.createCollection("test");
      System.out.println("集合创建成功");
        
      }catch(Exception e){
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
     }
   }
}

#获取集合
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
       // 连接到 mongodb 服务
         MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
       
         // 连接到数据库
         MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
       System.out.println("Connect to database successfully");
      
       MongoCollection<Document> collection = mongoDatabase.getCollection("test");
       System.out.println("集合 test 选择成功");
      }catch(Exception e){
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
     }
   }
}

#插入文档
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
         // 连接到 mongodb 服务
         MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
         
         // 连接到数据库
         MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
         System.out.println("Connect to database successfully");
         
         MongoCollection<Document> collection = mongoDatabase.getCollection("test");
         System.out.println("集合 test 选择成功");
         //插入文档  
         /** 
         * 1. 创建文档 org.bson.Document 参数为key-value的格式 
         * 2. 创建文档集合List<Document> 
         * 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List<Document>) 插入单个文档可以用 mongoCollection.insertOne(Document) 
         * */
         Document document = new Document("title", "MongoDB").  
         append("description", "database").  
         append("likes", 100).  
         append("by", "Fly");  
         List<Document> documents = new ArrayList<Document>();  
         documents.add(document);  
         collection.insertMany(documents);  
         System.out.println("文档插入成功");  
      }catch(Exception e){
         System.err.println( e.getClass().getName() + ": " + e.getMessage() );
      }
   }
}

#检索所有文档
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
         // 连接到 mongodb 服务
         MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
         
         // 连接到数据库
         MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
         System.out.println("Connect to database successfully");
         
         MongoCollection<Document> collection = mongoDatabase.getCollection("test");
         System.out.println("集合 test 选择成功");
         
         //检索所有文档  
         /** 
         * 1. 获取迭代器FindIterable<Document> 
         * 2. 获取游标MongoCursor<Document> 
         * 3. 通过游标遍历检索出的文档集合 
         * */  
         FindIterable<Document> findIterable = collection.find();  
         MongoCursor<Document> mongoCursor = findIterable.iterator();  
         while(mongoCursor.hasNext()){  
            System.out.println(mongoCursor.next());  
         }  
      
      }catch(Exception e){
         System.err.println( e.getClass().getName() + ": " + e.getMessage() );
      }
   }
}

#更新文档
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
         // 连接到 mongodb 服务
         MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
         
         // 连接到数据库
         MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
         System.out.println("Connect to database successfully");
         
         MongoCollection<Document> collection = mongoDatabase.getCollection("test");
         System.out.println("集合 test 选择成功");
         
         //更新文档   将文档中likes=100的文档修改为likes=200   
         collection.updateMany(Filters.eq("likes", 100), new Document("$set",new Document("likes",200)));  
         //检索查看结果  
         FindIterable<Document> findIterable = collection.find();  
         MongoCursor<Document> mongoCursor = findIterable.iterator();  
         while(mongoCursor.hasNext()){  
            System.out.println(mongoCursor.next());  
         }  
      
      }catch(Exception e){
         System.err.println( e.getClass().getName() + ": " + e.getMessage() );
      }
   }
}

#删除第一个文档
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;

public class MongoDBJDBC{
   public static void main( String args[] ){
      try{   
         // 连接到 mongodb 服务
         MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

         // 连接到数据库
         MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");  
         System.out.println("Connect to database successfully");

         MongoCollection<Document> collection = mongoDatabase.getCollection("test");
         System.out.println("集合 test 选择成功");

         //删除符合条件的第一个文档  
         collection.deleteOne(Filters.eq("likes", 200));  
         //删除所有符合条件的文档  
         collection.deleteMany (Filters.eq("likes", 200));  
         //检索查看结果  
         FindIterable<Document> findIterable = collection.find();  
         MongoCursor<Document> mongoCursor = findIterable.iterator();  
         while(mongoCursor.hasNext()){  
           System.out.println(mongoCursor.next());  
         }  
           
      }catch(Exception e){
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
     }
   }
}

高级教程

MongoDB 关系

MongoDB的关系表示多个文档之间的逻辑上的相互联系
1对1 1对多 多对多 多对1

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "Tom Hanks",
   "contact": "987654321",
   "dob": "01-01-1991"
}

{
   "_id":ObjectId("52ffc4a5d85242602e000000"),
   "building": "22 A, Indiana Apt",
   "pincode": 123456,
   "city": "Los Angeles",
   "state": "California"
} 

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address": [
      {
         "building": "22 A, Indiana Apt",
         "pincode": 123456,
         "city": "Los Angeles",
         "state": "California"
      },
      {
         "building": "170 A, Acropolis Apt",
         "pincode": 456789,
         "city": "Chicago",
         "state": "Illinois"
      }]
} 

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}
MongoDB 覆盖索引查询

MongoDB引用有两种:

  • 手动引用(Manual References)
  • DBRefs
DBRef的形式:
{ $ref : , $id : , $db :  }

{
   "_id":ObjectId("53402597d852426020000002"),
   "address": {
   "$ref": "address_home",
   "$id": ObjectId("534009e4d852427820000002"),
   "$db": "runoob"},
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin"
}

{
   "_id" : ObjectId("534009e4d852427820000002"),
   "building" : "22 A, Indiana Apt",
   "pincode" : 123456,
   "city" : "Los Angeles",
   "state" : "California"
}
MongoDB 查询分析

MongoDB查询分析常用函数:explain()和hint()

>db.users.ensureIndex({gender:1,user_name:1})
>db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})

MongoDB 原子操作

mongodb不支持事务

db.books.findAndModify ( {
   query: {
            _id: 123456789,
            available: { $gt: 0 }
          },
   update: {
             $inc: { available: -1 },
             $push: { checkout: { by: "abc", date: new Date() } }
           }
} )

#原子操作常用命令
{$set : {field : value }}
#unset 删除
{$unset : { field : 1}}
#inc对文档的某个值为数字型的健进行增减
{$inc : { field : value }}
{ $push : {field : value } }
{ $pushAll : {field : value_array}}
{$pull : {field : _value } }
{ $pop : { field : 1 } }
{ $rename : { old_field_name : new_field_name } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值