1.-----------------What is NoSQL ?2.----------------What is MongoDB?3.----------------MongoDB CRUD Operations4.---------------MongDB Index Research5.---------------MongoDB Sharding Research
What is NoSQL?
NoSQL (NoSQL = Not Only SQL), meaning "not just SQL".Why use NoSQL? In the modern computing system on the network every day will have a huge amount of data. A large part of these data is handled by the relational database management system (RDMBSs) like Oracle,Mysql SqlServer and so on. Through the application practice proved that the relationship model is very suitable for customer server programming, far beyond the expected benefits, today it is the dominant technology in structured data storage ,network and business applications . Today we can easily access and crawl mass data through third-party platforms (eg Google, Facebook, etc.). User's personal information, social networks, geography, user-generated data, and user-operated logs have multiplied. If we want to dig these user data, that SQL database is not suitable for these applications, while the NoSQL database is able to deal with these large data.
MongoDB[1] 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。类似于json的bson组成---二进制形式的json,MongoDB 文档类似于 JSON 对象 。因此可以存储比较复杂的数据类型。字段值可以包含其他文档,数组及文档数组。
在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍我们可以对比sql和mongodb来了解一下,在关系型数据库中数据库下的基本单位是table,而在mongodb中是用collection,一行数据对应的是mongodv中的一个文档,这就是为司马我们称mongodb为面向文档的数据库,我们注意到mongodb中不存在表连接的情况,关系型数据库的典型特征是表之间存在关联关系,mongodb不存在这种表连接语句,那么文档之间的一对一地以对多,多对多的情况mongodb可以通过在字段中嵌套一个或多个文档来实现这种关系,我认为这是一种以空间换时间的做法,比如有两张表用户表和商品表,一个用户对应多个商品,假设想要查询一个用户下的所有商品信息,在关系型数据库的查询中需要链表查询join,我们知道join必然会带来很多磁盘随机度的操作,随机读无法像顺序读那样的局部性好,缓存效果不好,反观Mongodb这种Nosql系统中,可以将一个用户的对应的所有商品信息嵌套存入该用户对应的文档的字段里面去,也就是说这些信息都cunxz也就是说这些信息都存在一个文档中,局部性很好,这样的虽然磁盘冗余了大量的数据,但却大大加快了查询的速度,从当前计算机的发展来看,空间hua空间换时间是很正常的,而计算机最关键的技术高速缓存cache技术就是用空间huansh技术就是用空间换时间的典范。想到这里其实也给了我一些提示,比如很多人在使用Mysql的过程中查询记录过多,比如2000W条数据的时候,数据库性能就开始下降,Nosql给我们的提示就是可以通过宽表冗余一些数据来实现join,这就是一种空间换时间的做法。
如果我们想要理解索引的原理,我们首先要了解一种最基本的数据结构Btree 就是balance tree ,这个图就是多路平衡排序树的一个例子,我们了解到每个节点的存储是按key-valuede形式存放的,一般一个节点的大小不会哦超过一个磁盘块的大小,这很重要,因为这关系到一个非常重要的指标IO次数,2,多路的,它不是二叉树,3,平衡树,数据有序,右侧数据一定会大于等于左侧的数据,并且平衡,有利于数据的快速检索,4,B树我们知道它一般非叶子节点都用来存放索引信息,而真正的数据都存放于叶子结点 恩 为什么数据库利用了Btree? 正常我们创建数据库表的时候,我们会制定主键上去,大家可以想像一下,如果让你去组织数据库的存贮,你会选择哪种数据结构来存储,最长兼得就是线性表了,如果以这样的方式,每一次查询都要把整个数据表都访问一边,IO次数是和记录数几乎正正比,如果有几千万条数据可能要IO 数百万次 这是绝对不行的IO这么关键的资源,时间复杂度大概是O(n),,
一般关系数据库都回使用刚才讲道的Btree,以主见作为索引结点,就是聚集索引 ,真正的数据放在叶结点里面;这样我们再去查询数据时,按Btree 查找,IO次数大概就是数的高度,而且树的度越大,树越扁平,树的高度就越低,时间复杂度基本会变成logn,而这样做的代价只是多出一些空间来存储索引,刚才只是建表,它会自动以主见为索引来组织数据库数据,那么我们平常所说的创建索引有时怎么回事呢?比如在user 表的name 字段上创建索引,那么数据库就会以name为索引结点来创建一个索引表,结点字段值是name,而叶子节点存放的是主见信息,这样就就是多级索引其实,这种方式我们在虚拟内存的设计中很常见,如果通过name为查询条件查询记录。这个过程就是,首先通过name索引表找到对应的ID,然后通过主见索引表找到对应的数据, 索引当然有它自身的缺点,如果在经常更新的字段上创建了索引,一旦该字段数据发生变化,也必须保持该字段的索引表更新,这种消耗是不小的。这也是为什么我们的索引喜欢建在不经常更新的数据上
你们可能会问,为什么没有选择hashtable来当索引,hash结构我们已经很熟悉了,比如文件系统的设计中,更为熟悉的就是java 中的hashmap,用hash 表来设计,其理想状态下的时间复杂度是O(1),为什么没有在数据库中使用呢?
1。最大的缺陷便是,hash只能等值查询,无法支持范围查询,在数据库中这是不允许的,反观Btree 可以很好的实现范围查询,因为Btree是有序的 2。还有就是如果hashtable过载数据,hash冲突的概率会大大增加,性能急速退化,查询一个有冲突的记录,时间复杂度有可能达到O(n),,,,当然如果了解java8的话,最新的hashmap 采用了hash+红黑树二叉排序树方式用二叉树来代替冲突的链表,,这对我们有很大的启示,,,hash结构和树结构,甚至是图,都可以结合使用,取长补短,各位所用
为什么不用二叉排序树? BST 和Btree有很多类似,,有序并且平衡,,但是当数据量比较大时,Btree将更加的扁平,高度更低,查询速度更快
当我们为mongodb插入文档时,如果不指定_id,mongodb会自动生成id字段作为当前文档的唯一标识,和mysql是一样的,也就是说每一个文档都会有自己唯一的id mongodb会利用id来建立Btree主索引,这是默认建立的
单字段索引,比如我们在person文档的age字段上建立索引,语句如下,,和之前所讲的一样,利用age字段为索引结点建立age索引表,叶结点存储主索引的值,查询过程是,通过age找到对应id,再通过id主索引找对对应的文档,,这里的参数可以指定索引的排序,1 为升序 -1为降序,然后我们看复合索引,既是在两个或是两个以上的字段建立联合索引,原理是一样的,联合age和name两个字段组织索引结点生成索引表,叶结点还是指向主索引表,也就是说,不管ji不管jianl不管建立多少索引,查询时最终还是会指向主索引表去查询文档,当然也有例外,比如覆盖索引我们后面会提到