今天安装好了MongoDB在阿里云。看过很多次MongoDB的架构,知道是非关系型的,似乎是使用文档+BJson存储的,这一点和es很像。今天就尝试操作一下MongoDB。
个人看法 MongoDB的语法糖很像JS和Python,解决了一些关系型数据库的痛点,就拿Mysql举例子,假如目前有个一个用户表,刚开始开发的时候只设置了用户名和年龄列,后续功能更新又添加了是否是篮球队 列,这就会导致,之前有很多的数据是没有该列的,添加该列以后,之前的数据对于该列就都是null,这样出现了两个问题,第一个需要修改表结构,第二个需要添加可能对之前数据无用的字段。MongoDB 解决了这个问题,他使用类似于JSON的格式,比如之前有个{name:小明,age:18},后面又要添加小刚,但是他是篮球队的,那就直接加进来{name:小刚,age:19,isbasketballer:true},对之前的小明来说是无感知的,该字段对小明来说是不需要的。不过MongoDB并不是用传统的JSON存储,因为传统JSON只能用来存字符和数字,有些二进制数据不支持(需要base64编码),所以MongoDB采用的是BJON,也就是支持二进制的JSON,BSON=JSON+base64
BSON 集合xx.wt内有文档,如果单个集合有很多文档,磁盘IO顶不住,所以MongoDB创建了数据页,将文档放不同的数据页中。每个页32KB,这样查询某个文档的时候,只要找对应的数据页就好了,再从数据页找文档,有些类似找主键索引。后面就是用到的B+树。
B+树存储 因为每个数据页内有文档,所以可以给每个数据页添加页号,由于每个文档都有对应的id主键,所以可以将id+页号组成一个新的页号,放在上一层,这样查询的时候从上往下查询,只要查询两次就可以找到对应的文档。这点和Mysql的B+树基本一致。上面的id是主键索引,当然也可以用文档的其他属性当索引,也就是辅助索引。但是mysql因为要保证并发写冲突,他的B+树有短暂的内存锁,而MongoDB是写时复制,copy on write,管自己写,原来的旧数据还放那边,后面找机会再合并。
cache内存缓存 因为数据在磁盘,IO比较慢,可以将经常查询的数据页放到cache中,优先查询cache,cache查不到再去磁盘找,也可以设置策略删除一些cache中的冷数据。
差不多了 剩下的Jourmal和分布式集群,目前实习面试估计也问不到,只要知道会有WAL机制像undo log和redo log一样有日志保存cache缓存数据不丢失。
基本操作语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 db.NPC .insertOne ({ name : "新NPC-雷克斯" , age : 33 , level : 24 , life : 920 , message : "我是新来的守卫" , email : "rex_guard@newtown.com" }) db.NPC .insertMany ([ { name : "商人A" , age : 40 , level : 11 }, { name : "法师B" , age : 180 , level : 38 , email : "mage_b@magic.com" } ]) db.NPC .find () db.NPC .find ().pretty () db.NPC .find ({ level : 35 }).pretty () db.NPC .find ({ name : "阿尔温" }).pretty () db.NPC .find ({ level : { $gt : 30 } }).pretty () db.NPC .find ({ age : { $gte : 30 , $lte : 50 } }).pretty () db.NPC .find ({ message : { $exists : true } }).pretty () db.NPC .find ({ email : { $exists : false } }).pretty () db.NPC .find ({}, { name : 1 , level : 1 , _id : 0 }).pretty () db.NPC .find ().sort ({ level : -1 }).limit (3 ).pretty () db.NPC .find ().sort ({ age : 1 }).pretty () db.NPC .replaceOne ( { name : "塔克农夫" }, { name : "塔克农夫" , age : 52 , level : 11 , life : 666 } ) db.NPC .find ({ name : "塔克农夫" }).pretty () db.NPC .updateMany ( { level : { $lt : 20 } }, { $inc : { life : 100 } } ) db.NPC .updateOne ( { name : "格雷探长" }, { $unset : { message : 1 } } ) db.NPC .deleteOne ({ name : "戈布尔矿工" }) db.NPC .deleteMany ({ life : { $exists : false } }) db.NPC .findOne ({ level : { $gte : 30 } })