zoukankan      html  css  js  c++  java
  • MongoDB

    MongoDB背景

    MongoDB是一个很有意思的数据库,一个介于关系型数据库和非关系型数据库之间,它是(NoSQL)非关系数据库且功能最丰富,最接近关系的数据库,它的数据就是存放在内存中,对数据的操作大部分在内存中,但MongoDB并不是单纯的内存数据库,MongoDB是由C++编写的,是一个基于分布式文件存储开源数据库系统,它的存在就是能够为WEB应用提供 可扩展、高性能 存储数据解决方案.

    什么是NoSQL?

    NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。它指的是非关系型数据库, 数据库发展史上里程碑的出现,是对于不同的传统的关系型数据库的统称,常见的有Redis,MongoDB,HBase,NoSql,Cloudant...

    它主要用于存储超大规模的数据,比如(新浪,谷歌,Facebook等公司都存储用户收集庞大的数据),这些数据存储不需要固定的模式,无法多余操作就可以横向扩展,现今我们可以通过第三平台(baidu,谷歌等..)可以容易访问和抓取数据,用户的个人信息,社交网络,地理位置,用户生成的数据,操作日志成倍增加,如果需要对这些数据进行挖掘分析,SQL型数据库的机制便不适合这些应用,NoSQL数据库能通过分布式系统分布式计算的优点可以处理这些无比庞大的数据.

    MongoDB的存储方式和持久化

    它以一种直观文档的方式存储数据,就像javascript中的JSON格式,在数据存储的时候它自动为文档增加了序列化的操作,最终存进磁盘的其实是一种BSON的格式;

    既然是内存数据库就牵扯到持久化的问题了,MongoDB的所有数据实际上是存放在硬盘上的,所有操作的数据通过mmap的方式映射到内存中的一个区域,然后MongoDB就这区域进行数据修改,避免了硬盘操作,mmap系统上的内容通过操作系统flush到硬盘上,如果,MongoDB在内存中修改了数据后,mmap数据flush到硬盘之前,系统宕机了,数据就会丢失。

    MongoDB的应用场景

    项目开始初始阶段的时候,数据结构无法确定,这时MongoDB可以考虑优先推荐,相比关系型数据库MySQL,更容易扩展,为代码的扩展带来的极大的方便.但是业务繁多,要求极高的话,它便不适用了,因为它不支持事务,也就是说数据之间的关系复杂话,表关系的一对多,和多对多出现将会难以处理.

    MongoDB的优缺点集锦

    #优点:
    性能优越,快速!在一定量内存级别中MongoDB的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据读写速度非常快;
    
    高扩展  第三方支持丰富(就是在其他NoSQL中也具备优势);
    
    弱一致性 保障用户了访问速度;
    
    文档结构存储方式  更加快捷的获取数据,json的存储格式;
    
    支持大容量存储,内置分布式系统GridFS,Shading
    
    #缺点:
    最大的缺点就是不支持事务!!!
    其次内存占用空间大;
    MongoDB 没有像MySQL成熟的一体化维护,会对后续开发运营造成影响.

    MongoDB安装

    1. 首先下载一个MongoDB 的msi安装包.例如mongodb-win32-x86_64-2008plus-ssl-3.4.18-signed.msi
    2. 一键安装,安装完毕后找到对应bin目录
    3. 整理环境变量,将bin目录路径添加到Path中(C:Program FilesMongoDBServer3.4in;)注意win7需要在bin后面加上 " ;"
    4. 在C盘目录下创建data/db目录
    5. 启动mongodb,打开cmd,mongod启动服务,再打开另外一个cmd窗口连接mongodb服务,输入mongo即可!注意保障这两个窗口开启,当然这是window下的环境!

    MongoDB 语法和使用

    基础用法

    安装不再赘述,但是安装后需要配置好环境变量..

    启动服务端  ---> 执行 mongod 命令

    默认端口 : 27017; (redis:6379;mysq:3306)

    应用连接 MongoDB 数据库 ---> 执行 mongo命令 进行本地数据库连接

    常用操作
    
    show databases  查看当前数据库服务中包含的数据库,磁盘中的数据库
    use db_name   切换当前使用的数据库,如果该名称库不存在,会在内存中创建一个新的数据库.
    db   显示当前使用的数据库,指数据表名
    show tables  查看当前数据库的表名,  磁盘中的数据表
    
    db.表名    在内存中创建数据库表
    db_name.insertOne({})  因此写入数据才能将内存中数据库和数据表永久写入到磁盘中
    
    增加数据: db.users.insert({'id':1,'name':'wva'})   数据库.数据表.指令.({data})
    
    查询数据: db.users.find()   数据库.数据表.指令

    MongoDB存储数据的结构 ---> 俗成大字典.

    MongoDB支持的数据类型

    ObjectId数据类型      自增id-不限定在数据库和数据表中
    
    String    字符串类型
    
    Int   不直接默认Int数字,Int32,Int64,注意:如果不指定Int,存储的就是Double
    
    Double  双精度浮点型  默认数字存储类型,(不存在float类型)
    
    Array  列表数据类型   list = [ ]
    
    Object  字典数据类型  dict = {}
    
    Date ISODate()  时间日期数据类型
    Null   None
    Boolean  ture/false
    Timestamp 时间戳  不过通常为Double存储

     MongoDB -- 增删改查

    (使用了不存在的对象,即创建该对象 use db db.table)

    //官方不推荐写法 3.2 加入新的insert写入方式
     增加一条:db.th.insert({name:1}) 
     增加多条:db.th.insert([{name:1},{name:2},{name:3}]) 
    
    // 官方推荐的写法:
     增加一条:db.task.insertOne({}) // 返回 _id 
     增加多条:db.task.insertMany([{},{},{}]) // 返回 _ids

     查

    1.查询所有符合条件的:  db.task.find({})
    
    2.查询一条符合条件的: db.task.findOne({})
    
    3.带条件查询: db.task.findOne({'age':18})
                    db.task.find({name:'lingling',age:18})   并列条件查询,名字和年龄同时满足

    //更新符合条件的数据,默认为第一条符合条件的数据:db.stu.update({}, {$set:{}})    不推荐
    
    //官方推荐  
    修改器 : $set 强制将某字段的value修改
    更新第一条符合条件的数据:db.task.updateOne({age:18}, {$set:{"name":"xiaokeai"}})
    
    更新所有符合条件的数据 : db.task.updateMany({name:'xiaokeai'}, {$set:{age:18}})   将所有叫小可爱的改成18岁 ..嘿嘿

     // 官方不推荐
    删除符合条件的所有数据:db.task.remove({})
    
    //官方推荐写法:
    删除一条符合条件的: db.task.deleteOne({'name':'shazi'})
    删除多条符合条件的: db.task.deleteMany({'name':'shazi'})
    删除所有数据:  db.task.deleteMany({})

    MongoDB和MySQL比对

       MySQL  MongoDB
    数据表  table  Collections
    数据行  row   Documents
    数据列  字段   Field

     高级查询

    //并列查询
    db.Collection.find({Field:1,Field2:2})
    
    //或查询
    在不同字段查询或条件时使用$or    
    db.Collection.find({$or:[{Field:1},{Field2:3}]})
    db.stu.find({$or:[{age:99},{name:'turtle'}]}) 
    
    在相同字段情况下查询或条件时使用 $in
    db.Collection.find({Field:{$in:[1,2,3,4,5]}})
    db.task.find({age:{$in:[9,18,27,19]}})   
               
    //Array查询
    db.task.find({"hobby":"game"})
    
    //数字比较符查询
     $lt $lte $gt $gte $eq $ne
    
    //子集查询  $all
    db.task.find({list:{$all:[8,6,4,2]}})
           
    //Object对象查询
    db.task.find({'class.name':'person'})
                  

    高级修改

    //强制修改字段   $set
    db.task.updateMany({name:'baby'}, {$set: {"age":10}})
    //引用增加字段  $inc
    db.task.updateMany({}, {$inc: {"age":10}})
    
    //强制删除某个字段 $unset
    db.task.updateMany({}, {$unset: {"age":30}})

    针对Array操作

    //增加操作
    db.task.updateOne({name:"小可爱"},{$push:{"hobby":"memeda"}})                      由此可见 $push == append  效果
    db.task.updateOne({name:"小可爱"},{$pushAll:{"hobby":['swim','walk','read']}})     $pushAll == extend   迭代添加
    
    //删除操作(两种方式)
    db.task.updateOne({name:"小可爱"},{$pull:{"hobby":"read"}})此时$pull == remove 在更新的时候删除一个符合条件的
    db.task.updateOne({name:"金角大王8"},{$pullAll:{"hobby":['swim','walk']}}) $pullAll == 删除每一个元素 $pop() 是删除列表中的第一个 (-1) 或者最后一个 db.stu.updateOne({name:"小可爱"},{$pop:{"hobby":1}}) 删除最后一个 db.task.updateOne({name:"小可爱"},{$pop:{"hobby":-1}}) 删除第一个元素 //更新操作 db.task.updateOne({name:"小可爱","hobby":'game'},{$set:{"hobby.$":"memeda"}}) 将hobby 中 的game修改成 memeda db.task.updateOne({name:"小亲亲","class.name":"python"},{$inc:{"class.$.score":99}}) 添加一个字段score 成绩进去

    针对Object操作

    db.stu.updateOne({name:"小亲亲"},{$unset:{"class.classtype":"yy"}})
            
    db.stu.updateOne({name:"小亲亲"},{$set:{"class.classtype":"hh"}})

    关键字

    $的使用

    $ 用来存储符合条件的元素下标索引
      list = [1,2,3,4] 哪个元素 == 2 它的下标是多少 $就等于这个下标的数字
      list[1] = "x小可爱"
      list[$] = "小可爱"

    limit skip sort的使用

    limit   选取数据量
    db.task.find().limit(10)    选取前10条数据查看
    
    skip   跳过数据量
    db.task.find().skip(10)  跳过前10条查看
    
    sort   根据字段进行排序
    db.task.find().sort(name:1/-1)  进行正序/倒序排列
    
    //分页查看,每页查看3条数据
    db.task.find().sort({'name':1}).skip(0).limit(3) 
    db.task.find().sort({'name':1}).skip(3).limit(3) 
    db.task.find().sort({'name':1}).skip(6).limit(3) 

    pymongo应用

    python后端和MongoDB连接

    import pymongo
    
    conn = pymongo.MongoClient('127.0.0.1',27017)
    
    #use db_name
    MONGO_DB = conn['test']    #创建test库并连接

    pymongo用法

    向数据库增加data
    MONGO_DB.users.insert_one({'name':'keke','age':2})  #写入一条数据
    MONGO_DB.users.insert_many([{'name':'keke'},{'name':'pan'}])  #写入多条数据
    
    res = MONGO_DB.users.insert_one({'name': 'yy', 'age': 38, 'hobby': ['aa', 'bb', 'cc']})
    ress = MONGO_DB.users.insert_many([
        {
            'name': 1,
            'package': [
                {'name': '极光剑', 'act': 99},
                {'name': '墨竹戒指', 'atc': 15},
            ]
        },
        {
            'name': 2,
            'package': [
                {'name': '王者之剑', 'act': 999},
                {'name': '麻痹戒指', 'atc': 15},
            ]
        },
        {
            'name': 3,
            'package': [
                {'name': '双龙魔影剑', 'act': 199},
                {'name': '海克斯戒指', 'atc': 15},
            ]
        }
    ])
    print(ress, dir(ress), ress.inserted_ids)
    """
    <pymongo.results.InsertManyResult object at 0x0000000002ED65C8> 
    ['_InsertManyResult__acknowledged', '_InsertManyResult__inserted_ids', '_WriteResult__acknowledged', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_raise_if_unacknowledged', 'acknowledged', 'inserted_ids']
    [ObjectId('5c9b6b722de0502ce0095985'), ObjectId('5c9b6b722de0502ce0095986'), ObjectId('5c9b6b722de0502ce0095987')]
    """
    
    """查询数据库数据"""
    
    res = MONGO_DB.users.find_one({'age':2},{'_id':0})
    print(res,type(res))   # 注意MongoDB自己序列化,因此取出来的是字典类型
    
    ress = list(MONGO_DB.users.find({},{'_id':0}))  #find({})  #取得除了_id的数据 得到的是一个生成器
    
    for item in ress:
        print(item)
    
    res = list(MONGO_DB.users.find({"$or":[{'name':'pan'},{'age':2}]},{'_id':0}))  #或查询 or
    res = list(MONGO_DB.users.find({'name':{'$in':['pan','keke']}}))  #或查询 in
    print(res)
    
    """修改数据库数据"""
    MONGO_DB.users.update_one({"hobby":"bb","name":"yanlong"},{"$set":{"hobby.$":"xxoo"}})  #修改hobby bb为 xxoo
    MONGO_DB.users.update_one({'name':1},{'$push':{'package':{'name':'屠龙刀','act':1099}}})  #修改 name 1中package属性
    
    '''删除数据库数据'''
    MONGO_DB.users.delete_many({})  #删除所有数据
    MONGO_DB.users.delete_one({"name":3})   #删除该条数据
    MONGO_DB.users.delete_many({"name":"keke"})  #删除所有name = keke的数据
    
    """通过_id取数据 """
    res = MONGO_DB.users.find_one({"name":1})
    res["_id"] = str(res.get("_id"))
    res_json = json.dumps(res)
    print(res_json)
    
    """
    {"_id": "5c9b6b722de0502ce0095985", "name": 1, "package": [{"name": "u7effu7389u5c60u9f99", "act": 999, "p": "u5e26u6709u6bd2u7d20u5c5eu6027"}, {"name": "u9ebbu75f9u6212u6307", "act": 15, "p": "u53efu8ba9u5bf9u65b9u5904u4e8eu9ebbu75f9u72b6u6001"}], "yuanbao": 99}
    """
    from bson import ObjectId  
    
    res = MONGO_DB.users.find_one({"_id":ObjectId("5c9b6b722de0502ce0095985")})
    print(res)  #根据ObjectId查询到指定宇宙唯一id的数据,前提是注意直通先通过bson 才能进行转换
    pymongo用法

    ...

  • 相关阅读:
    【Boost】boost库asio详解5——resolver与endpoint使用说明
    VS路径定义
    C++ Primer 第二章 学习笔记
    C++ Primer 第三章 学习笔记
    C++ dll的隐式与显式调用
    BOOST编译方法
    Real World CTF一日游
    蝉知CMS5.6反射型XSS审计复现
    关于MJ刷新的报Too many arguments to function call, expected 0, have *问题
    XIB做适配(二)
  • 原文地址:https://www.cnblogs.com/CrazySheldon1/p/10599355.html
Copyright © 2011-2022 走看看