开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:NoSQL2】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/76/detail/15773
NoSQL2
1.NoSQL数据库的引入
关系型数据库还没有关系存在,很难在存在关系的多个表之间做出一个合理的分割。让他们在不同的服务器上存储的时候。在做基于关系的这种操作。
比如说要找到一个学生他选的课程,或者一门课程选课的所有学生的信息。它不需要做两台机器上的这种分布的。这种drawing操作。也很难做实现。看起来可以把数据库给他存到两台机器上,但他的操作就显得比较费时间且性能不高,所以这是我们说的问题。那更重要的是一些半结构化或者非结构化的数据该怎么让表里头所有的数据都有一些列所以它结构化非常好。
但一些半结构化,比如说像刚才谈到的像哈利波特这样的小说文本该怎么存,如果把整个当成一个字段存进一条记录里显然也不合适,尽管关行数据支持像globe这样的,也就是大对象,但是把它存进关数据库里当大对象,它是存在这一个地方是一个大对象,在表示哈利波特。本身对它也没有更好的存储方法。如果这个大对象真是像刚才说的哈利波特小说,如果没有10TB的话。显然把它存入观营生库是非常的适合。
所以我们得出来的结论是:关系型数据库对于这种大数据存储,它是有一定的障碍,它适合存这种结构化数据,也就是说所有的数据都有一个标准的schema。预定应的schema就是那个数据库的结构。
那半节化数据什么意思呢?即他的这个schema不严格。那、也就是说有的数据有这几类有的数据可能有另外几类,反正他们不太一样。在种情况下就不太适合用关型数据库。
非结构化数据没有任何内部的结构,比如说长段视频或者是一个音频它就不存在任何内部结构了,这种这两个数据就不适合观性数据库存储。
大数据、大文本或者是图片或者是视频音频。这一类的数据或者是大量的数据是没有严格的数据格式的约定的,即半结构化和非结构化数据占多数。而这两个数据又偏偏不是关型数据库。
关于型数据库,它不胜任这种大数据的存储和处理,于是出现了NoSQL数据库。
2.NoSQL其他类型的学习资料
Bigtable : ADistributed Storage System for Structured Data
-ACM Transactions on computer Systems ,2008,26:1-26.
-http://staticgooglgusercontent.com/external content / untrusted dlcp / research . google . com / zh - CN // archive / bigtable -0sdi06.pdf
Dynamo : amazon ’ s highly available key - value store
- Symposium on Operating Systems Principles ,2007:205-220.
http://web.archive.org/web/20120129154946/http://s3.amazonaws.com/AIIT hingsDistributed / sosp / amazon - dynamo -sosp2007.pdf
Cassandra
-http://cassandra.apache.orgL
MemcacheDB
-http://memcachedb.orgL Apache
CouchDB
-http://couchdb.apache.org/
MongoDB
-http://www.mongodb.orgL
Bigtable是一个稀疏的、分布式的、持久的多维排序映射。映射由行键、列键和时间戳索引;映射中的每个值都是一个未解释的字节数组,
我们就可以看到这个表里面所有的数据。他们的猎。他们每一行所拥有的恋会有一些差异,列族可以动态添加列族,里面的列也可以动态添加。每一行所有的数据,也许极端情况下都没有完全相等的这种完全相同的列。它的列可以不一样。
Bigtable集群存储许多表,如下图所示:
-每个表由一组平板组成,每个平板包含与行范围相关的所有数据。
-最初,每张桌子只包含一个平板,随着表的增长,它会自动拆分为多个平板,默认情况下每个平板电脑的大小约为100-200 MB。
这个表有一个特征:是表里面的列可以动态的去增加。
它的列分成列族,在表示一个列的时候让它的列族冒号加上它的列名来文完整的表示这一个列.比如说这个表里面前一半可以说就是表示person的。那这个列族就是person。那么里面就会有什么person这一部分。可能是在表示他的课程选课了, 还有course的学分等等。后面的表是他的成绩,那就包括比如数学、语文等等。那前面这个冒号前面就叫列族,后面表就叫真正列的名字。表示我们根据实际需要增加一个列组。每一行所有的数据也许极端情况下,大家都没有完全相等的这种完全相同的列。它的列配不一样。其次表的上部叫它一行的每一个字段的都可以存储一个版本号。这个版本号是用时间出来表示尽管它不存在表和表之间的关联,但是它看起来就比较立体。
把这张表的内容随便切割,切完以后就可以在不同的机器上面。比如有三台机器上放于是我们看到任何一张表都被切成了若干块儿,每一块儿就叫一个tablet。如果这个系统里面的表数量非常多。大每一个表分的块儿非常多,那这个表本身有可能会非常大
3. MongoDB
MongoDB(来自“humongous”)是一个开源文档数据库,也是领先的NoSQL数据库。用C++MongoDB编写的功能:
-面向文档的存储
-完整索引支持
-复制和高可用性
-自动切分
-查询
-快速就地更新
-映射/减少
-GridFS
-商业支持
mongo db是一个面向文档的数据库。它不是一个关系型数据库。就像big table一样它只有表和表的这种概念,它没有表和表之间的关联。所以它容易scaling out。因为它比较容易scaling out,会在一个集群里去存储数据,mongo db是自动的。根据集群里面的服务器的数量以及要存储的数据会自动的在这个集群里把所有的数据平衡。
举例说明:
现在有两台机器。一台用了这么多的空间存数据。当你想加一台新机器上来的时候它会自动的把它变样,即这两台机器各会迁移一部分数据过来给另一台,他他能做到一个根据数据的量去做均衡的这样一个动作可以保证所有的机器,它们上面存储的数据量是大体相当,这样的话机器的性能就比较好。
MongoDB的概念:
Mongo DB是一个面向文档的数据库,而不是关系数据库,这使得扩展更加容易。它可以跨ACLusterDistribution文档自动平衡数据和负载。它支持MapRequeeá和其他聚合工具,并支持通用的二级索引。MongoDB可以通过itself进行一些管理,如果主服务器停机。
Mongo DB是基于文档的文档,文档就是在Mongo DB里面存储的数据的基本单位。文档合起来就是一个collection。Document就相当于一行。数专营数据库里的一行。而若干的document组成一个collection。这个collection就相当于关型数据库里面的表。但是他会告诉这些行,也就是这些documen不是说一定要有相同的schema,它可以有不同的schema。那也就是说他们。不是说具有像官行数据库的表的行一样,那具有相同的列。它们可以内部包含的内容,就是document。在同一个collection里面包含的document它们互相之间的存储的数据可以是有差异的。
文档是MongoDB的基本数据单元一个集合一个表,同一集合中的文档可以有不同的形状或类型每个文档都有一个特殊的关键文档的集合可以被认为”_id”的无模式等价物,它在整个文档中是唯一的Mongo DB将集合分组到数据库中,每个数据库都有自己的权限并存储在单独的磁盘中。
Document:文档大致相当于关系数据库中的一行,其中包含一个或多个键值对{“greeting”:“Helo,world!”}
大多数文档将比这个简单的文档更复杂,并且通常包含多个键/值对:{“问候语”:“你好,世界!”,“foo”:3}
文档中的键/值对是有序的-早期文档与以下文档不同:{“foo”:3。“问候语:”Helo,world!}
文档中的值不仅仅是“blob”。它们可以是几种不同的数据类型之一。
key不能包含字符集\0/(空字符)。这个和$字符有一些特殊的属性,只能在某些情况下使用-以\uu开头的键应被视为保留键;虽然这并没有严格执行。
-MongoDB区分类型和大小写,注意下面三种不同表达方式:
-{“foo”:3}
-{“foo”:“3”}
-{“foo”:3}
下面是一个完整的document,它这匹配里面包含的内容,我们看到有两个建制队,其中又是内嵌了一个。collection就是一组document。它就组织成了一个表。要注意的是,上面MongoDB区分类型大小写敏感和拼写敏感,也就是说底下三个都不一样:一个是一个小写的for,它是数字类型,所以它是它是类型敏感,第二个尽管也是小写了但是它是个字串的。第三个是大写的,所以它们三个互相之间都有差异。然后document里面可以包含若干个键值队,一个document里面包含若干个键值队,但是建不能重复。
{
" name ":" John Doe ",
" address ":{
" street ":"123 Park Street ",
" city ”:" Anytown ",
state ":" NY "
}
实际上用colletion的目的就是为了要去加快的处理的速度。collection把数据分成不同的组,让以后的搜索都在一个比较小的区域内去执行。搜索的范围变小。在同一个collection上我们还可以去做索引。这样的话就会进一步加快。
collection的命名基本上符合jason的惯例,在collection里面和table都不一。他的collection是可以嵌套的。在逻辑上的定义是把这些数据去做了一个群组。它跟table又不一样的是他的collection甚至可以嵌套,再去细分,又包含了一些词在table里。
除了按集合对文档进行分组外,MongoDB还将集合分组到数据库中:
数据库有自己的权限,每个数据库都存储在磁盘上的单独文件中。一个好的经验法则是将单个应用程序的所有数据存储在同一个数据库中还有几个保留的数据库名称,您可以直接访问这些名称,但具有特殊的语义。如下所示:
-管理:就身份验证而言,这是“根”数据库。
-本地:此数据库将永远不会被复制,并且可以用于存储任何应该是单个服务器本地的集合:
-配置:当Mongo在分片设置中使用时,配置数据库在内部用于存储有关分片的信息。
Mongo运行:有两种可能,其中在 Windows上比较简单
(1)Mac OS
- brew install mongodb-community@4.2
To run MongoDB as a macOS service , issue the folowing : brew services start mongodb-community@4.2
- To run MongoDB manually as a background process , issue the following :- mongod -- config / us Г/ local / etc / mongod . conf -- fork
(2) Windows
- Download MongoDB community Edition - Run the MongoDB instaler
- Follow the MongoDB community Edition installation wizard
启动运行会出现下面的信息:证明数据跑起来了。
、
注意:要创建个目录否则的话会出错的。运行起来之后。Mongo DB有个控制台,如下图所示:
创建:
这个控制台是一个客户端的一个控制台,一个针对JavaScript操作的一个将控制台。数据跑起来之后我们看到提示,这个其实是一个针对jason操作的一个将控制函。这个shell你就可以去输入一些命令,如果他给了你一些命令,你就可使用它。
举一个官网上可找到的例子:
(来自Mongo DB客户端,可下载)
代码解析:
这是在往数据库里面插入东西,即我们所说的插入的时候是=它的语法是什么?“users”是你要插入的collection,db我们刚才看到了一打db他出现“test”。当你想换一个数据库也需要跟关键数据库,比如“is”后面跟上这个数据库的名字再切换过去。然后你所有的操作都是对当前那个“users”这个库来。那db.user则是说明在当前的库里面有一条users的一个collection。然后我们要去用insert One表示要插入一条document。那这个document就是一个JSON对象,命令行里写完后出现下面几行内容,即命令执行完之后返回来的内容。
控制台打开以后会出现上图这个页面,启动了后台,在数据跑起来之后最后输出子进程城成功启动,父进程退出。
控制台打开以后启动一个Mongo DB客户端的后台。在这里跑就在这里看到了最后输出说成功启动。把数据拷过去在里边去执行就能得到一些想要的东西。
查找:
查找的时候仍然是在collection里查找。查找有一定的语法:你可以指定你查找的那个key是什么,括号里面是它的条件。条件里面用的是这表示要大于就是great。
18指年龄大于18岁的人,我要取他的name和address,我只取前五条出来,这样的执行的时候就会发现按照这个条件执行的就会把它列出来,当然我们在库里面写的只插入了这一个人,所以如果“find”的话,不加任何条件,就表示要找所有的出来,只找到了这个人,这个人就是刚才刚插进去。如果说年龄大于18岁。或者是年龄大于18岁,然后把他的name和取出来。那就可以看到取这个人的name。
Update也是和find同样方法这是查询条件说大于大于18岁的所有的document里面把Status给update,这个“set”表示是设置的意思。这一整条代码表示你是什么,要做什么样一个行动。这里表示我把大于18岁的所有的人,即document里面包含并且大于18岁的把它的status对应的值给它改成reject。那就是说刚才我们插入的status是finding。那他确实大约18岁。
怎么通过java代码去操作?
首先需要建立一个数据库的连接,这和关系型数据库是一样的。下载Mongo DB客户端之后创建一个colltion。创建的时候如果你不加默认任何值它默认的值就这个。数据库在本地在端口。如过之前改动过就把这多个给它放到一个数组里。整个作为colltion的客户就知道了其实是Mongo DB。他们构成了一个集群。数据库在本地在这个端口,其java代码如下:
MongoClient mongoClient = new MongoClient0:
// or MongoClient mongoClient = new MongoClient (" localhost ");
// or MongoClient mongoClient = new MongoClient (" Iocalhost ",27017);
// or ,to connect to a replica set , supply a seed list of members
MongoClient mongoClient = new MongoClient ( Arrays . asList (
new ServerAddress (" localhost ",27017),
new ServerAddress (" localhost ",27018),
new ServerAddress (" localhost ",27019));
DB db = mongoClient . getDB (" mydb ");
可能在访问这个数据库时候,会让输入用户名和密码。有text数据库要求我输入用户名和密码:
Authentication ( Optional )
MongoClient mongoClient = new MongoClient0; DB db = mongoClient . getDB (" test ");
boolean auth = db . authenticate ( myUserName , myPassword );
拿到了这个db的这个对象之后
Set < String > cols = db .getColectionNames
();
For(String s:colla)
{
System.out.println(s);
}
获取colletion:
BCollectionColl ; db . getColection (" testColection ");
获取colletion之后输入 mongo DB的一些设置,如下代码所示:
mongoClient . setWriteConcern ( WriteConcern . JOURNALED );
获取colletion之后增加document:
BasicDBObject doc = new BasicDBObject ("name "," MongoDB ").
append (" type "," database "). append (" count ",1).
append (" info ", new BasicD В Object [" x ",203]. append ( y ",102));
col . insert ( doc );
要去创建一个document对象。我们看到的这个键值对添加了“name”,“tape”“count”三个,第四个“info”的值也是一个嵌套,这样插入之后数据就在这个test collection里面。你就成功的插入。
底下是搜索,搜索就是你要创建一个查询条件,它也是一个。Basic DB Object。其代码如下:
Getting A Single Document with AQuery /
BasicDBObject query = new BasicDBObject ("",71);
cursor = coll . find [ query );
try {
while [ cursorhasNextO ){
System . outprintin (cursornext0);
} finaly {
cursorclose ();
}
它是个集合类,看它里面有没有内容。如果有就把它取出来,输出一下你就知道符合这个查询条件的是哪一个。比如他的值是71,对应值为71的document全拿出来。搜索就是你要创建一个查询条件,创建搜索。
用Spring访问Mongo DB:
db . createUser [
user :" test ",
pwd :" test ",
roles :[{ role :" readWrite ", db :" test "}1
> db . auth (" test "," test ")
//1表示验证通过0表示验证失败
如果用Spring来访问。我们可以先在那个里面做一些初始的动作,第一个就是要去在“test”里创建user,写内容进去,我们要用 db . auth (" test "," test ")来验证一下你这个插入对不对,即对数据库的操作对不对。