1.为什么要使用mongodb数据库或者说他有什么优点? 高性能,高可用,易扩展,丰富的查询语言,面向文档
2.文档 相当于 行,键只能是字符串类型
数据库 -》集合-》文档-》键,值 db col doc 查找数据库某个集合的所有文档 db.col.find()
删除数据库某个集合的所有文档 db.col.remove({})
删除某个文档,name属性值为sandy的文档 db.col.remove({"name":"sandy"})
3.数据库
一个文档
product_id : 1
version: 1.0
测试:
err = collection.Find(bson.M{"product_id": "2"}).All(&versions)
i := len(versions)
结果:
err = nil i=0 All函数找不到符合的
4.两个文档
product_id : 1
version: 1.0
product_id : 1
version: 1.1
测试:
err = collection.Find(bson.M{"product_id": "1"}).One(&versions)
结果:
不会报错,只会返回其中一个文档
5.两个文档
product_id : 1
version: 1.0
product_id : 1
version: 1.1
测试:
err = collection.Find(bson.M{"product_id": "2"}).All(&versions)
结果:
不会报错,数量为0
总结:想知道数据库有没有这个数据,使用Count(),为0的话代表没有这个数,不存在
MongoDB的事务
首先我们需要知道MongoDB是有多种存储引擎的,不同的存储引擎在实现ACID的时候,使用不同的机制。而Mongodb从3.0开始默认使用的是WiredTiger引擎,本文后续所有文字均是针对WiredTiger引擎。
WiredTiger引擎可以针对单个文档来保证ACID特性,但是当需要操作多个文档的时候无法保证ACID,也即无法提供事务支持
Mongodb使用读写锁来来控制并发操作:
当进行读操作的时候会加读锁,这个时候其他读操作可以也获得读锁。但是不能或者写锁。
当进行写操作的时候会加写锁,这个时候不能进行其他的读操作和写操作。
所以按照这个道理,是不会出现同时修改同一个文档(如执行++操作)导致数据出错的情况而且按照这个道理,因为写操作会阻塞读操作,所以是不会出现脏读的
【索引】 数据库索引的本质是空间换时间
上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:
每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。(h表示树的高度 & 出度d表示的是树的度,即树中各个节点的度的最大值)
综上所述,用B-Tree作为索引结构效率是非常高的。
而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。
上文还说过,B+Tree更适合外存索引,原因和内节点出度d有关。从上面分析可以看到,d越大索引的性能越好,而出度的上限取决于节点内key和data的大小:
dmax=floor(pagesize/(keysize+datasize+pointsize))
floor表示向下取整。由于B+Tree内节点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。
B树
一棵m阶的B-Tree有如下特性:
1. 每个节点最多有m个孩子。
2. 除了根节点和叶子节点外,其它每个节点至少有Ceil(m/2)个孩子。
3. 若根节点不是叶子节点,则至少有2个孩子
4. 所有叶子节点都在同一层,且不包含其它关键字信息
5. 每个非终端节点包含n个关键字信息(P0,P1,…Pn, k1,…kn)
6. 关键字的个数n满足:ceil(m/2)-1 <= n <= m-1
7. ki(i=1,…n)为关键字,且关键字升序排序。
8. Pi(i=1,…n)为指向子树根节点的指针。P(i-1)指向的子树的所有节点关键字均小于ki,但都大于k(i-1)
B+树
B+Tree相对于B-Tree有几点不同:
非叶子节点只存储键值信息。
所有叶子节点之间都有一个链指针。
数据记录都存放在叶子节点中