MongoDB----基础
MongoDB概念:
1、易用性
MongoDB是由C++编写的,是一个基于分布式文件存储的开源数据库系统,它不是关系型数据库。在高负载的情况下,添加更多的节点,可以保证服务器的性能。
MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库。 不采用关系型主要是为了获得更好得扩展性。当然还有一些其他好处,与关系数据库相比,面向文档的数据库不再有“行“(row) 的概念取而代之的是更为灵活的“文档”(document)模型。通过在文档中嵌入文档和数组,面向文档的方法能够仅使用一条记录 来表现复杂的层级关系,这与现代的面向对象语言的开发者对数据的看法一致。 另外,不再有预定义模式(predefined schema):文档的键(key)和值(value)不再是固定的类型和大小 。由于没有固定的模式,根据需要添加或删除字段变得更容易了。通常由于开发者能够进行快速迭代,所以开发进程得以加快。 而且,实验更容易进行。开发者能尝试大量的数据模型,从中选一个最好的。
2、易扩展性
应用程序数据集的大小正在以不可思议的速度增长。随着可用带宽的增长和存储器价格的下降,即使是一个小规模的应用程序,需要存储的数据量也可能大的惊人,甚至超出 了很多数据库的处理能力。过去非常罕见的T级数据,现在已经是司空见惯了。 由于需要存储的数据量不断增长,开发者面临一个问题:应该如何扩展数据库,分为纵向扩展和横向扩展,纵向扩展是最省力的做法,但缺点是大型机一般都非常贵,而且 当数据量达到机器的物理极限时,花再多的钱也买不到更强的机器了,此时选择横向扩展更为合适,但横向扩展带来的另外一个问题就是需要管理的机器太多。 MongoDB的设计采用横向扩展。面向文档的数据模型使它能很容易地在多台服务器之间进行数据分割。MongoDB能够自动处理跨集群的数据和负载,自动重新分配文档,
以及将用户的请求路由到正确的机器上。这样,开发者能够集中精力编写应用程序,而不需要考虑如何扩展的问题。
如果一个集群需要更大的容量,只需要向集群添加新服务器,MongoDB就会自动将现有的数据向新服务器传送
3、丰富的功能
MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供了一系列不断扩展的独特功能 #1、索引 支持通用二级索引,允许多种快速查询,且提供唯一索引、复合索引、地理空间索引、全文索引 #2、聚合 支持聚合管道,用户能通过简单的片段创建复杂的集合,并通过数据库自动优化 #3、特殊的集合类型 支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话session。类似地,MongoDB也支持固定大小的集合,用于保存近期数据,如日志 #4、文件存储 支持一种非常易用的协议,用于存储大文件和文件元数据。MongoDB并不具备一些在关系型数据库中很普遍的功能, 如链接join和复杂的多行事务。省略 这些的功能是处于架构上的考虑,或者说为了得到更好的扩展性,因为在分布式系统中这两个功能难以高效地实现
4、卓越的性能
MongoDB的一个主要目标是提供卓越的性能,这很大程度上决定了MongoDB的设计。MongoDB把尽可能多的内存用作缓存cache, 视图为每次查询自动选择正确的索引。 总之各方面的设计都旨在保持它的高性能 虽然MongoDB非常强大并试图保留关系型数据库的很多特性,但它并不追求具备关系型数据库的所有功能。 只要有可能,数据库服务器就会将处理逻辑交给客户端 。这种精简方式的设计是MongoDB能够实现如此高性能的原因之一
5、什么样的数据存储到MongoDB
首先一笑较为灵活的数据,比如一个家谱,有的人有哥哥,有的人有妹妹,如果使用mysql那么就需要定义非常多的字段
并且MongoDB存储的数据一般不是核心数据,核心的数据还是需要使用mysql,因为如果需要使用事还是使用mysql(关系型数据库),mongodb能支持事务,但是影响写入性能,不建议使用。
MongoDB基础知识:
1、文档是MongoDB的核心概念。文档就是键值对的一个有序集{'msg':'hello','foo':3}。类似于python中的有序字典。
需要注意的是: #1、文档中的键/值对是有序的。 #2、文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。 #3、MongoDB区分类型和大小写。 #4、MongoDB的文档不能有重复的键。 #5、文档中的值可以是多种不同的数据类型,也可以是一个完整的内嵌文档。文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。 文档键命名规范: #1、键不能含有\0 (空字符)。这个字符用来表示键的结尾。 #2、.和$有特别的意义,只有在特定环境下才能使用。 #3、以下划线"_"开头的键是保留的(不是严格要求的)。
2、集合就是一组文档。如果将MongoDB中的一个文档比喻为关系型数据的一行,那么一个集合就是相当于一张表
#1、集合存在于数据库中,通常情况下为了方便管理,不同格式和类型的数据应该插入到不同的集合,但其实集合没有固定的结构, 这意味着我们完全可以把不同格式和类型的数据统统插入一个集合中。 #2、组织子集合的方式就是使用“.”,分隔不同命名空间的子集合。 比如一个具有博客功能的应用可能包含两个集合,分别是blog.posts和blog.authors,这是为了使组织结构更清晰, 这里的blog集合(这个集合甚至不需要存在)跟它的两个子集合没有任何关系。 在MongoDB中,使用子集合来组织数据非常高效,值得推荐 #3、当第一个文档插入时,集合就会被创建。合法的集合名: 集合名不能是空字符串""。 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。 集合名不能以"system."开头,这是为系统集合保留的前缀。 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。 除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
3、数据库:在MongoDB中,多个文档组成集合,多个集合可以组成数据库
数据库也通过名字来标识。数据库名可以是满足以下条件的任意UTF-8字符串: #1、不能是空字符串("")。 #2、不得含有' '(空格)、.、$、/、\和\0 (空字符)。 #3、应全部小写。 #4、最多64字节。 有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。 #1、admin: 从身份认证的角度讲,这是“root”数据库,如果将一个用户添加到admin数据库,这个用户将自动获得所有数据库的权限。再者,一些特定的服务器端命令也只能从admin数据库运行,如列出所有数据库或关闭服务器 #2、local: 这个数据库永远都不可以复制,且一台服务器上的所有本地集合都可以存储在这个数据库中 #3、config: MongoDB用于分片设置时,分片信息会存储在config数据库
4、强调:把数据库名添加到集合名前,得到集合的完全限定名,即命名空间
例如: 如果要使用cms数据库中的blog.posts集合,这个集合的命名空间就是 cms.blog.posts。命名空间的长度不得超过121个字节,且在实际使用中应该小于100个字节
使用:
安装
http://dl.mongodb.org/dl/win32/x86_64
注意win 7系统需要安装Microsoft Visual C++(去360下载)
测试这个版本没有问题,其他的下载出现了问题:http://downloads.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-v3.4-latest-signed.msi
1、创建目录和文件
D:\MongoDB\datas D:\MongoDB\logs D:\MongoDB\mongo.conf
mongo.conf文件
#数据库路径 dbpath=D:\MongoDB\datas #日志输出文件路径 logpath=D:\MongoDB\logs\mongo.log #手错误日志采用追加模式 logappend=true #启用日志文件,默认启用 journal=true #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为falae quiet=true #端口号默认为27017 port=27017
2、查看服务列表中有没有MongoDB服务,如果有使用下面的命令移除掉
mongod.exe --remove
3、给服务中添加MongoDb服务
mongod.exe --config "d:\MongoDB\Server\3.4\mongo.conf" --install --serviceName "MongoDB"
4、启动服务(可以手动在服务中启动,或者使用命令)
net start MongoDB net stop MongoDB
5、测试
命令执行后,浏览器中输入http://127.0.0.1:27017看到如下界面即说明启动成功
6、使用
双击 mongo.exe,可以像mysql那样进行操作
详细配置参考
#1、安装路径为D:\MongoDB,将D:\MongoDB\bin目录加入环境变量 #2、新建目录与文件 D:\MongoDB\data\db D:\MongoDB\log\mongod.log #3、新建配置文件mongod.cfg,参考:https://docs.mongodb.com/manual/reference/configuration-options/ systemLog: destination: file path: "D:\MongoDBTest\data\log\mongod.log" logAppend: true storage: journal: enabled: true dbPath: "D:\MongoDB\data\db" net: bindIp: 0.0.0.0 port: 27017 setParameter: enableLocalhostAuthBypass: false #4、制作系统服务 mongod --config "D:\MongoDB\mongod.cfg" --bind_ip 0.0.0.0 --install 或者直接在命令行指定配置 mongod --bind_ip 0.0.0.0 --port 27017 --logpath D:\MongoDB\log\mongod.log --logappend --dbpath D:\MongoDB\data\db --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install #5、启动\关闭 net start MongoDB net stop MongoDB #6、登录 mongo 链接:http://www.runoob.com/mongodb/mongodb-window-install.html 当没有账号密码登录的时候,默认就是管理员登录。,因为刚刚做系统服务install的时候没有指定 --auth(没有指定则没有权限认证这一说),(相当于mysql跳过授权表启动一样)
2、账号管理
在admin数据库下创建的用户可以访问其他的数据库
//账号管理:https://docs.mongodb.com/master/tutorial/enable-authentication/ //1、创建有权限的用户 use admin db.createUser( { user: "root", #这个root可以随便写 pwd: "123", roles: [ { role: "root", db: "admin" } ] #权限,role是root说明是管理员, } ) use test db.createUser( { user: "egon", pwd: "123", roles: [ { role: "readWrite", db: "test" }, { role: "read", db: "db1" } ] #针对test库有读写权限,操作自己的库有读写权限,针对db1库读权限,操作其他库有读权限 } ) //2 查看所有的用户 show users //进入不同的数据库查询有不同的users //3 删除用户 db.dropUser("egon") //4 设置mongodb,开启需要密码验证机制 在mongo.cong配置中添加 auth=true 重启MongoDB (因为修改了配置文件,直接重启即可,如果启动不了检查配置文件有没有写错) //5、重新登录:注意使用双引号而非单引号 方式1:mongo --port 27017 -u "root" -p "123" --authenticationDatabase "admin" 方式2:也可以在登录之后用db.auth("账号","密码")登录 mongo use admin db.auth("root","123") #推荐博客:https://www.cnblogs.com/zhoujinyi/p/4610050.html 创建账号密码+开启认证机制
补充
需求:修改egon用户的角色为readWriteAnyDatabase
db.updateUser("egon",{roles:[{role:"readWriteAnyDatabase",db:"admin"}]}) //db:好像只能写admin,我写test,会报错(可能是如果权限是readWriteAnyDateBase,db只能是admin,但是注意还是在test数据库下)
需求:修改密码
use test db.changeUserPassword("egon","123456")
3、命令行shell
#1、mongo 127.0.0.1:27017/config #连接到任何数据库config #2、mongo --nodb #不连接到任何数据库 #3、启动之后,在需要时运行new Mongo(hostname)命令就可以连接到想要的mongod了: > conn=new Mongo('127.0.0.1:27017') connection to 127.0.0.1:27017 > db=conn.getDB('admin') admin #4、help查看帮助 #5、mongo时一个简化的JavaScript shell,是可以执行JavaScript脚本的
5、数据类型
#1、null:用于表示空或不存在的字段 d={'x':null} #2、布尔型:true和false d={'x':true,'y':false} #3、数值 d={'x':3,'y':3.1415926} #4、字符串 d={'x':'egon'} #5、日期 d={'x':new Date()} d.x.getHours() #6、正则表达式 d={'pattern':/^egon.*?nb$/i} 正则写在//内,后面的i代表: i 忽略大小写 m 多行匹配模式 x 忽略非转义的空白字符 s 单行匹配模式 #7、数组 d={'x':[1,'a','v']} #8、内嵌文档 user={'name':'egon','addr':{'country':'China','city':'YT'}} user.addr.country #9、对象id:是一个12字节的ID,是文档的唯一标识,不可变 d={'x':ObjectId()}
6、_id和ObjectId
MongoDB中存储的文档必须有一个"_id"键。这个键的值可以是任意类型,默认是个ObjectId对象。 在一个集合里,每个文档都有唯一的“_id”,确保集合里每个文档都能被唯一标识。 不同集合"_id"的值可以重复,但同一集合内"_id"的值必须唯一 #1、ObjectId ObjectId是"_id"的默认类型。因为设计MongoDb的初衷就是用作分布式数据库,所以能够在分片环境中生成 唯一的标识符非常重要,而常规的做法:在多个服务器上同步自动增加主键既费时又费力,这就是MongoDB采用 ObjectId的原因。 ObjectId采用12字节的存储空间,是一个由24个十六进制数字组成的字符串 0|1|2|3| 4|5|6| 7|8 9|10|11 时间戳 机器 PID 计数器 如果快速创建多个ObjectId,会发现每次只有最后几位有变化。另外,中间的几位数字也会变化(要是在创建过程中停顿几秒)。 这是ObjectId的创建方式导致的,如上图 时间戳单位为秒,与随后5个字节组合起来,提供了秒级的唯一性。这个4个字节隐藏了文档的创建时间,绝大多数驱动程序都会提供 一个方法,用于从ObjectId中获取这些信息。 因为使用的是当前时间,很多用户担心要对服务器进行时钟同步。其实没必要,因为时间戳的实际值并不重要,只要它总是不停增加就好。 接下来3个字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以保证不同主机生成不同的ObjectId,不产生冲突 接下来连个字节确保了在同一台机器上并发的多个进程产生的ObjectId是唯一的 前9个字节确保了同一秒钟不同机器不同进程产生的ObjectId是唯一的。最后3个字节是一个自动增加的 计数器。确保相同进程的同一秒产生的 ObjectId也是不一样的。 #2、自动生成_id 如果插入文档时没有"_id"键,系统会自帮你创建 一个。可以由MongoDb服务器来做这件事。 但通常会在客户端由驱动程序完成。这一做法非常好地体现了MongoDb的哲学:能交给客户端驱动程序来做的事情就不要交给服务器来做。 这种理念背后的原因是:即便是像MongoDB这样扩展性非常好的数据库,扩展应用层也要比扩展数据库层容易的多。将工作交给客户端做就 减轻了数据库扩展的负担。
连接MongoDB
(MongoDB本地登录可以不需要密码)
命令格式
mongodb://[ username:password@]host1[:port1],host2[: port2],...[, hostN[: portN]]][/[database][?options]]
- mongodb:/∥固定前缀username:账号,可不填I
- password:密码,可不填
- host:主机名或p地址,只有host主机名为必填项。
- port:端口,可不填,默认27017
- /database:连接某一个数据库
- ?options:连接参数,key/value对
使用案例
mongodb://1ocalhost 连接本地数据库27017端口 mongodb://root:itcast@localhost 使用用户名root密码为itcast连接本地数据库27017端口 mongodb://1ocalhost,localhost:27018,localhost:27019,连接三台主从服务器,端口为27017、27018、27019
java连接MongoDB
添加依赖
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.11.1</version> </dependency>
测试连接
import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; class Test{ public void testConnection(){ //创建mongodb 客户端 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); //或者采用连接字符串 //MongoClientURI connectionString = new MongoClientURI("mongodb://root:root@localhost:27017"); //MongoClient mongoClient = new MongoClient(connectionString); // 连接数库 MongoDatabase database=mongoClient.getDatabase("test"); // 连接collection MongoCollection<Document> collection = database.getCollection("student"); //查询第一个文档 Document myDoc = collection.find().first(); //得到文件内容 json串 String json = myDoc.toJson(); System.out.println(json); } }
局域网连接不上MongoDB
1、看有没有绑定0.0.0.0
2、电脑防火墙关闭