MongoDB

大数据第四天

1.mongoDB数据库(NoSQL数据库)
	1.1 安装(windows版本)
		a.下载链接  www.mongodb.org
		b.创建一个目录用于存放安装目录,解压安装包
		c.创建一个目录用于存放数据
		d.cd到安装目录 进入bin 执行 mongod.exe --dbpath 数据目录全路径
		e.配置环境变量
		f.启动数据库服务 自己修改mongodb.bat
			mongod --dbpath "d:/mongodb_data"
		g.参考文档配置启动命令选项
		h.客户端连接
			mongo 127.0.0.1:27017(如果不改变端口,默认为27017)/admin(使用管理员登陆)
	1.2 shell基本操作
		1.2.1 对比
				和关系型数据库差异
					对比项		mongodb		mysql
					表			集合		table
					行			文档		行记录
					字段		键key		字段field
					值			值value		值value
					主外键		无			PK,FK
					灵活性		极高		差
					查询		find		sql
		1.2.2 基本操作
				1.创建数据库
					use 数据库名(如果此时什么都不干,离开时这个空数据库会从缓存中删除)
				2.查看所有数据库
					show dbs
				3.给指定的数据库添加集合并添加记录
					db.persons.insert({name:"test"})  //此条命令执行完以后会自动为文档插入id一列
					其中:
						db 表示所使用的数据库
						persons 表示集合
						insert 表示集合操作
						name 表示key
						test 表示value
				4.查看数据库中的所有文档
					show collections
				5.查询指定文档的数据
					a.查询所有
						db.persons.find()
					b.查询一条数据
						db.persons.findOne() //查询一行数据
				6.更新文档数据
					db.persons.update({name:"test"},{$set:{name:"test1"}})  //满足条件多条记录时,只更新第一条
					//第一个{} 表示条件
					//第二个{}  表示需修改的字段
				7.删除文档数据
					db.persons.remove({name:"123"})
					//{} 条件
				8.删除库中的集合	
					db.persons.drop()
				9.删除数据库
					db.dropDatabase()
				10.shell的help
					db.help()  //全局数据库帮助
					db.person.help() //集合相关帮助
				11.API
					http://api.mongodb.org/
				12.命名规范
					1.不能是空字符串
					2.特殊符号不能使用
					3.应全部小写
					4.最多64字节
					5.不能跟现有的数据同名  如admin local
				13.可充当js引擎,可以执行js命令					
	1.3 BSON扩充的数据类型
		1.概述
			BSON:是JSON的扩展,它新增了日期和浮点等JSON不支持的数据类型
	1.4 MongoVUE————可视化工具
		一开始不推荐  后期可查看相关命令
	1.5 文档数据
		1.插入
			a.插入
				db.文档.insert.({key:value})
			b.批量插入
				shell不支持批量插入,只能使用for循环
				for(var i=0 ; i<10 ; i++){
					db.perosns.insert({name:i})
				}
			c.save操作
				save操作和insert操作的区别在于当遇到相同id情况下时:
					save完成保存操作,而insert则报错
		2.删除
			a.删除列表中所有数据
				db.persons.remove()
			b.根据条件删除数据
				db.persons.remove({naem:1})
		3.更新
			a.强硬式文件替换
				db.persons.update({查询器},{修改器})
				//会导致新文档替换旧文档 新文档为修改器里面的内容
			b.主键冲突会报错并停止更新操作
				当更新文档和已有文档ID冲突时则系统报错
			c.insertOrUpdate操作
				查询器查出来的数据则执行更新操作,否则执行替换操作
				db.persons.update({查询器},{修改器},true)
			d.批量更新操作(解决只更新一条数据问题)
				db.persons.update({查询器},{修改器},false,true) //查询器多条记录时均更新
			e.更新器
				$set————用来指定一个键值对,存在则修改,不存在则添加
					{$set:{key:value}}
				$inc————用来指定的键对应的数字类型的数值进行加减操作
					{$inc:{field:1}}  //field这个列的数值+1 如果减1则是-1
				$unset————用来删除指定键
					{$unset:{field:value}}
				$push————如果指定的键是数组则追加数值;如果指定键不存在则创建数组类型的键值对
					{$push:{filed:value}}
				$pushAll————用法和push差不多
					{$pushAll:{field:array}}  //注意后面跟着是数组
				$addToSet————用于添加键,如果存在则不操作
					{$addToSet:{field:value}}
				$pop————从指定数组中删除一个值
					{$pop:{filed:value}} //其中value为1时代表最后一个数值,-1为第一个数值
				$pull————删除一个被指定的数值
					{$pull:{"name":"test"}}
				$pullAll————一次性删除多个指定的数值
					{$pullAll:{"name":["test","test1","test2"]}}
				$————数组定位器
		4.查询
			a.Find
				1.指定返回的键
					db.persons.find({},{})
					//第一个{}指定条件
					//第二个{}指定需要返回的列
					//其中id列默认情况下会返回  _id:0为不返回 name:1为返回那么列
				2.查询条件
					$lt -> <  $lte -> <=
					$gt -> >  $gte -> >=
					$ne -> !=
					$in
					$nin
					$or
					Null
					$elemMatch ————数组查询器
					$where     ————尽量避免使用。性能低
					示例:   22<=age<=27 -> {age:{$gte:22,$lte:27}}
							age != 26  -> {age:{$ne:26}}
							age in(12,13) -> {age:{$in:[12,13]}}  --后接数组
							age>80 or age<40 -> {$or:[{age:{$gt:80}},{age:{$lt:40}}]}
							age is null      -> {age:{$in:[null]}}		
			b.分页和排序
				1.分页
					前几条数据 ————limit()
						db.persons.find().limit(5) --查询前5条数据
					前跨度数据 —————skip()
						db.persons.find().limit(3).skip(5)  --前6~8 共三条 前面5条省略跳过
				2.排序  ————sort()
					db.persons.find().limit(3).sort({name:1}) --前三行数据根据name升序排序   -1为倒序
					db.persons.find().limit(3).sort({name:1,age:-1}) --先升序再倒序
			c.游标和其他知识
				1.游标
					var p = db.persons.find();  --得到游标
					while(p.hasNext()){ --遍历游标
						obj = p.next(); --指向下一条记录
						print(obj)
					}
				2.游标销毁的条件
					1.客户端发来请求销毁
					2.迭代完毕
					3.超过10分钟没用,自动清除
				3.查询快照————针对不变的集合进行游标运动
					高级查询选项:
						$query:doc  doc 为字段 (field:value)
						$orderby:doc
						$maxsan:integer 做多扫描文档个数
						$min:doc	查询开始  
						$max:doc	查询结束
						$hint:doc	使用哪个索引
						$explain:boolean	统计
						$snapshot:boolean   快照 
					
					示例:db.persons.find({$query:{name:"jim"},$snapshot:true},{_id:0})
					
	1.6 常用函数
		a.findAndModify函数————返回集合
		b.runCommand函数————返回更新或者删除的文档
			示例:
				ps = db.runCommand({
				"findAndModify":"persons",
				"query":{name:"test"},
				"update":{"$set":{"age":11}},
				"new":true
				}).value
				
				--"findAndModify"   集合名
				--"query"			查询器
				--"update"			修改器
				--"new"				状态--如果true表示返回结果是更新后的,false为更新前
				--"sort"			排序	
		c.Count函数————计数
			db.persons.find({country:"USA"}).count() --查询美国国籍的人数
		d.Distinct函数————去重
			db.runCommand({distinct:"persons",key"country"}).values --查询persons集合中一共有多少个国家,分别是什么
		e.Group函数————分组
			db.runCommand({
				group:{
				ns:集合名字,
				Key:分组的键对象,
				Initial:初始化累加器,
				$reduce:组分解器,
				Condition:条件,
				Finalize:组完成器
				}
			}) 
			说明:分组首先会按照key进行分区,每组的每个文档全部要执行$reduce的方法,其中参数为:一个是组内本条记录,一个是累加器数据
			示例:
				db.runCommand({
					group:{
					ns:"persons",
					key:{"country":true},
					initial:{m:0},
					$reduce:function(doc,prev){
						if(doc.m > prev.m){
							prev.m = doc.m;
							prev.name = doc.name;
							prev.country = doc.country;
						}
					},
					condition:{m:{$gt:90}}
					}
				})
		f.列出所有函数
			1.shell方式
				db.listCommands()
			2.WEB方式
				http://localhost:28017/_commands  //注意启动时需要加--rest 如: mongod --dbpath 数据目录 --rest
	1.7 索引
		a.索引概述
			1.创建索引的时候注意正序还是倒序
			2.索引的创建在提高查询性能的同时会影响插入性能
			3.符合索引要注意索引的先后顺序
			4.每个键全建立索引不一定就能提高性能
		b.管理索引
			1.创建索引
				db.persons.ensureIndex({id:1},{unique:true})  
					id为索引列  1为升序 -1为倒序 
					unique 为唯一索引
			2.删除索引
				db.runCommand({dropIndexs:"persons",index:"index_name"}) 将persons的index_name索引删除
				db.runCommand({dropIndexs:"persons",index:"*"}) 将persons的所有索引删除
		c.空间索引————二维空间索引,地图时用到,具体找度娘
	1.8 固定集合
		1.特性
			a.固定集合默认是没有索引的,就算是_id也是没有索引的
			b.由于不要分配新的空间,所以插入速度非常快
			c.固定集合的顺序是确定的,所以查询速度非常快
			d.最适合的是应用就是日志管理
		2.操作
			a.创建一个名叫mycoll的固定集合要求大小在100个字节,可以存储10个文档
				db.createColletion("mycoll",{size:100,capped:true,max:10})
			b.把一个普通的集合转换成固定集合
				db.runCommand({convertCapped:"persons",size=10000})
			c.反向排序,默认是插入顺序排序
				db.mycoll.find().sort({$natural:-1})
	1.9 GridFS
		1.简述
			GridFS是mongoDB自带的文件系统,使用二进制的形式存储文件
		2.利用的工具
			mongofile.exe
		3.使用
			a.查看GridFS的所有功能
				cmd -> mongofiles
			b.上传一个文件
				mongofiles -d 数据库名 -l "E:\t.txt" put "a.txt"
			c.集合查看存储文件的信息
				db.fs.chunks.find()
				db.fs.files.find()
			d.集合中所有文件
				mongofiles -d 数据库名 list
	1.10 其他脚本
			1.服务器端运行eval
				db.eval("function(name){return name}","test")
			2.js的存储
				a.在服务上保存js变量供给函数全局调用
					db.system.js.insert({_id:name,value:"test"}) //保存变量name
					db.eval("{return name;}")  //调用变量 注意变量名必须定义。不然报错  
				//其中js相当于关系型数据库中的存储过程,因为value值可以为函数
	1.11 运维管理
			1.启动配置
				--dbpath 指定数据库目录 默认情况下在c:/data/db
				--port   监听端口		默认情况下是27017
				--fork	 用守护进程方式启动mongoDB
				--logpath	指定日志输出目录	默认是控制台
				--config	指定启动项用文件的路径
				--auth		用安全认证方式启动数据库
				示例:
					1.使用config配置文件来启动数据库,将启动端口改为8888
						mongodb.conf文件(安装目录下)
						dbpath=D:/data
						port=8888
						
						--启动命令
						mongod.exe --config ../mongodb.conf
						
						--客户端连接命令
						//如果是在shell下操作  命令是mongo 127.0.0.1:8888
				
					2.停止数据库服务
						a ctrl+c组合键
						b admin数据库命令关闭
							use admin
							db.shutdownServer()
			2.导入/导出
				a 导入数据
					使用mongoimport命令
					参数有
						--db 指定数据库
						--collection 指定集合
						--file 指定文件
						--host 指定主机
						--port 指定端口
					示例:
						mongoimport --db test --collection person --file "D:/t.txt"
				b 导出数据
					使用mongoexport命令
					参数有
						-d 指定数据库
						-c 指定集合
						-o	指定输出文件
						-csv  导出csv格式
						-q		过滤导出
						--type<json|csv|tsv>
						--host 指定主机
						--port 指定端口
					示例:
						1.导出本机
							mongoexport -d persons -c person -o "D:/t.txt"  
						2.导出其他主机
							mongoexport --host hadoop --port 8888
				c 备份/恢复
					1.运行时备份 mongodump
						示例: mongodump --host 127.0.0.1:27017 -d test -o "d:/bak" --会根据数据库新建同名文件夹
					2.运行时恢复 mongorestore
						示例: mongorestore --host 127.0.0.1:27017 -d test -directoryperdb "d:/bak/test"
					3.懒人备份  直接将数据文件拷贝
			3.锁
				a Fsync使用
					数据库结构图:
						读写操作->缓冲池->数据库 (从上到下)
					上锁:将缓冲池的数据全部写进数据库中
							示例: 
								  use admin  --选择需要上锁数据库
								  db.runCommand({fsync:1,lock:1}); --上锁
					解锁:当上锁操作完成后的操作
							示例:db.currentOp()
					数据修复:数据库自我修复的能力
							示例:
								use admin  --选择需要修复数据库
								db.repairDatabase()
			4.用户管理
				在启动时需启动安全检查 --auth
				a 添加用户
					use admin  --选择需要添加用户的数据库
					db.addUser("root","password"); --参数为用户名和密码
				//其中admin数据库中的用户为管理员用户
				b 启用用户
					db.auth("用户名","密码");
				c 删除用户
					db.system.users.remove({user:"root"}); --删除用户名为root的用户
	
	1.12 主从架构
		a 主从复制————一个简单的数据库同步备份的集群技术
			1.1 在数据集群中要明确的知道谁是主服务器,主服务器只有一台
			1.2 从服务器要知道自己的数据源,也就是对于主服务器是谁
			1.3 --master用来确定主服务器
				--slave和-source来控制从服务器
			示例:
				1台主服务器配置文件
					dbpath=数据库目录 
					port=8888	--端口
					bind_ip=127.0.0.1  --绑定IP地址
					master=true		--主服务器标识
				
				1台从服务器配置文件
					dbpath=数据库目录 
					port=7777	--端口 可跟主服务器一样也可不一样,建议不一样
					source=127.0.0.1:8888 --指向主服务器
					slave=true		--从服务器标识
			1.4 主从复制的其他设置项
				--only 指定复制某个数据库,默认为全部数据库   从服务器端设置
				--slavedelay 设置主数据库同步数据的延迟(单位为秒)  从服务器端设置
				--fastsync	以主数据库的节点快照为节点启动从数据库  从服务器端设置
				--autoresync	如果不同步则重新同步数据库  从服务器端设置
				--oplogsize		设置oplog的大小(主节点操作记录存储在local的oplog中)  主服务器端设置
			1.5 动态添加和删除从节点
				添加: db.sources.insert({"host","192.168.1.100:9999"})  --添加一个新的从节点
				删除:  db.sources.remove({"host","192.168.1.100:9999"})  --删除一个从节点
		b 副本集————主从分布式
			假设有个集群,三台服务器,分别是ABC,其中A为主服务器,BC为从服务器
				1 当A活跃时,BC用于备份
				2 当A出现故障时,B变成活跃
				3 当A再恢复后,此时AC变成备份服务器,B为主服务器
				4 插入更新查询操作只能在活跃节点上执行,备份节点只能备份
			示例:
				第一步:修改服务器配置文件
					A服务器配置文件
						dbpath=数据库目录
						port=1111
						bind_ip=127.0.0.1
						replSet=child/127.0.0.1:2222 --设定同伴
					B服务器配置文件
						dbpath=数据库目录
						port=2222
						bind_ip=127.0.0.1
						replSet=child/127.0.0.1:3333 --设定同伴
					C服务器配置文件
						dbpath=数据库目录
						port=3333
						bind_ip=127.0.0.1
						replSet=child/127.0.0.1:1111 --设定同伴
				第二步:初始化副本集(在主服务器上设置)
					use admin
					db.runCommand({
						"replSetInitiate":
						{
							"_id":'child',
							"members":[
								{"_id":1,
								 "host":"127.0.0.1:1111"
								},
								{"_id":2,
								 "host":"127.0.0.1:2222"
								},
								{"_id":3,
								 "host":"127.0.0.1:3333"
								}
							]
						}
					})
				第三步:查看副本集
					rs.status()
			节点参数:
				standard  常规节点  参与投票 可能成为活跃节点
				passive	  副本节点  参与投票 不能成为活跃节点
				arbiter	  仲裁节点	参与投票 不能成为活跃节点
				Priority  权重  0~1000 其中0表示副本节点,1~1000表示常规节点
				arbiterOnly:true  --表示仲裁节点
				
	1.13 分片
			1.使用步骤(一台配置服务器,一台路由器,两台数据库)
				1.1 创建一个配置服务器
					mongod --config 配置服务器.conf
				1.2 创建路由服务器,并连接到配置服务器
					路由器调用mongos命令 
				1.3 添加2个分片数据库
					 8081和8082
				1.4 利用路由器为集群添加分片(允许本地访问)(在路由器服务器执行)
					db.runCommand({addshard:"127.0.0.1:8081",allowLocal:true})
					db.runCommand({addshard:"127.0.0.1:8082",allowLocal:true})
					//其中数据库之前不能使用任何数据库语句
				1.5 打开数据库分片功能(在路由器服务器执行)
					db.runCommand({"enablesharding":"数据库名"})
				1.6 对集合进行分片
					db.runCommand({"shardcollection":"数据库名.集合名","key":{"_id":1}})		
				1.7 查看集群中的所有分片
					db.shards.find()
	1.14 JavaAPI	
			1.导入jar包
			2.建立一个mongo的数据库连接对象
				Mongo mo = new Mongo("127.0.0.1:8888");  默认是127.0.0.1:27017
			3.查询所有的数据库名字
				mo.getDataBaseNames();
			4.创建相关数据库的连接
				DB db = mo.getDB("数据库名");
			5.查询数据库所有的集合名字
				db.getCollectionNames();
			6.创建相关集合连接
				DBCollection c = db.getCollection("集合名");
			7.查询集合所有数据
				DBCursor cur = c.find();
				//遍历指针
				while(cur.hasNext()){
					DBObject o = cur.next();
					System.out.println(NameValue:" + o.get("name"));  //得到name字段值
				}
			8.其他操作
				cur.count();//个数
				JSON.serialize(cur);//转换Json对象
			9.新建集合操作
				db.createCollection("集合名",new DBObject());//如果没有new DBObject()不操作集合退出的話,集合会从缓存中销毁
			10.插入集合数据操作
				DBObject doc = new BasicDBObject();
				doc.put("name","test");
				doc.put("age",12);
				List<String> books = new ArrayList<String>();
				books.add("MongoDB");
				books.add("Java");
				books.add("SQL");
				doc.put("books",books);
				c.insert(doc);  --当传入参数类型是list时则是批量插入
			11.删除操作
				c.remove(new BasicDBObject("_id",new ObjectId(id)))  --根据Id删除 因为集合中的ID是ObjectId类型
			12.更新操作
				c.update(find,update,upsert,multi)
					--find 查询器
					--update 更新器
					--upsert 更新或者插入  true/false
					--multi		是否批量	true/false
			13.分页操作
				c.find().limit(5).skip(3); 每页5条,从第四条开始时(含第四条)
			14.排序操作
				c.find.sort();
			15.关闭对象
				c.close();
				db.close();
				
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			


		

  

posted @ 2015-12-05 20:48  ciade  阅读(456)  评论(0编辑  收藏  举报