简述网站开发的基本流程,六安网站建设培训,厦门市城市建设档案馆网站,帝国cms 做的博客网站mongodb基本常用命令#xff08;只要掌握所有实验内容就没问题#xff09;
上机必考#xff0c;笔试试卷可能考#xff1a;
1.1 数据库的操作
1.1.1 选择和创建数据库 #xff08;1#xff09;use dbname 如果数据库不存在则自动创建#xff0c;例如#xff0c;以下…mongodb基本常用命令只要掌握所有实验内容就没问题
上机必考笔试试卷可能考
1.1 数据库的操作
1.1.1 选择和创建数据库 1use dbname 如果数据库不存在则自动创建例如以下语句创建spitdb数据库: 2show dbs 或者 show databases #查看有权限查看的所有的数据库命令 3db #查看当前正在使用的数据库命令 show dbs 结果如下: 有默认的三个库选填 admin从权限的角度来看这是root数据库。要是将一个用户添加到这个数据库这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行比如列出所有的数据库或者关闭服务器。 local: 这个数据永远不会被复制可以用来存储限于本地单台服务器的任意集合 config: 当Mongo用于分片设置时config数据库在内部使用用于保存分片的相关信息。 创建数据库 use 数据库名—创建数据库名 说明如果没有数据库则创建如果有则替换数据库。 当我们创建好数据库好后使用show dbs发现无创建的数据库原因跟mongodb的存储机制有关系当我们创建数据库时存放到内存中没有进行持久化存储所以看不到如果要看到需要创建数据库中的集合。 数据库命名的规则不能是关键字特色字符64字节
1.1.2 数据库的删除 db.dropDatabase() 1.2 集合操作 1.2.1 集合显式创建 db.createCollection(name) #创建集合 show collections /show tables查询集合 1.2.2 集合的隐式创建 当向一个集合中插入一个文档的时候如果集合不存在则会自动创建集合。 详见下面文档的插入章节。 通常我们使用隐式创建文档即可 db.集合名.insert({id:1,name:forlan});
【注意集合的命名规范】选择 不能是空字符串 不能含有 \0字符空字符)这个字符表示集合名的结尾 不能以 system.开头这是为系统集合保留的前缀 不能含有保留字符。另外千万不要在名字里出现$
5.在test01数据库中隐式创建集合 集合名 键值对 stu1 Id:202201090,name:李四,depart:大数据 scho1 name:复旦大学,address:上海 dog1 breed:牧羊犬color:白色 1.2.3查看集合 show tables 或 show collections db.collections.stats()
1.2.3 集合的删除 db.集合.drop()
返回true表示删除成功 1.3 文档的CRUD 文档document的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。 BSON是一种二进制序列化文档格式它基于 JSON 并进行了扩展以支持更多的数据类型。 mongo _id的生成规则 时间戳机器码PID计数器选择 1.3.1 文档的插入 语法 db.collection.insert()单文档插入 db.collection.insertMany()多文档插入 db.collection.insert()单、多文档插入 变量插入文档 db.collection.insertMany(变量) 1单个文档插入 使用insert() 方法向集合中插入文档 document document or array 要插入到集合中的文档或文档数组。(json格式 writeConcern document 选择的性能和可靠性级别(了解) ordered boolean 可选。如果为真则按顺序插入数组中的文档如果其中一个文档出现错误MongoDB将返回而不处理数组中的其余文档。如果为假则执行无序插入如果其中一个文档出现错误则继续处理数组中的主文档。在版本2.6中默认为true 示例: 代码 db.ac1.insert( {“atcid”:“0001”,“content”:“进入倒春寒优点冷”,“userid”:“1001”,“name”:“rose”} ) 插入ac1的集合如果该集合不存在则创建它 //结果如下 //查询集合 db.ac1.find()
查看表中的哪些集合 show collections
2多个文档的插入 db.collection.insertMany( [ {k1:v1,k2:v2}, {k1:v1,k2:v2} ] ) 集合 文档值 data1 “_id”:“1”,“articleid”:“100001”,“content”:“我们不应该把清晨浪费在手机上健康很重要一杯温水幸福你我他。” “userid”:“1002”,“nickname”:“相忘于江湖”,“createdatetime”:new Date(“2019-08-05T22:08:15.522Z”),“likenum”:NumberInt(1000),“state”:“1” “_id”:“2”,“articleid”:“100001”,“content”:“我夏天空腹喝凉开水冬天喝温开水”,“userid”:“1005”,“nickname”:“伊人憔悴”,“createdatetime”:new Date(“2019-08-05T23:58:51.485Z”),“likenum”:NumberInt(888),“state”:“1” “_id”:“3”,“articleid”:“100001”,“content”:“我一直喝凉开水冬天夏天都喝。”,“userid”:“1004”,“nickname”:“杰克船长”,“createdatetime”:new Date(“2019-08-06T01:05:06.321Z”),“likenum”:NumberInt(666),“state”:“1”
db.data1.insertMany([ {“_id”:“1”,“articleid”:“100001”,“content”:“我们不应该把清晨浪费在手机上健康很重要一杯温水幸福你我他。”,“userid”:“1002”,“nickname”:“相忘于江湖”,“createdatetime”:new Date(“2019-08-05T22:08:15.522Z”),“likenum”:NumberInt(1000),“state”:“1”}, {“_id”:“2”,“articleid”:“100001”,“content”:“我夏天空腹喝凉开水冬天喝温开水”,“userid”:“1005”,“nickname”:“伊人憔悴”,“createdatetime”:new Date(“2019-08-05T23:58:51.485Z”),“likenum”:NumberInt(888),“state”:“1”}, {“_id”:“3”,“articleid”:“100001”,“content”:“我一直喝凉开水冬天夏天都喝。”,“userid”:“1004”,“nickname”:“杰克船长”,“createdatetime”:new Date(“2019-08-06T01:05:06.321Z”),“likenum”:NumberInt(666),“state”:“1”}, {“_id”:“4”,“articleid”:“100001”,“content”:“专家说不能空腹吃饭影响健康。”,“userid”:“1003”,“nickname”:“凯撒”,“createdatetime”:new Date(“2019-08-06T08:18:35.288Z”),“likenum”:NumberInt(2000),“state”:“1”}, {“_id”:“5”,“articleid”:“100001”,“content”:“研究表明刚烧开的水千万不能喝因为烫嘴。”,“userid”:“1003”,“nickname”:“凯撒”,“createdatetime”:new Date(“2019-08-06T11:01:02.521Z”),“likenum”:NumberInt(3000),“state”:“1”} ])
3单、多个文档的插入
db.collection.insert([{k1:v1,k2:v2}…]) 【课堂练习】5分钟 1.单行插入文本 集合名 数据 city cityname重庆,population3213万 School name:厦门大学area9700多亩 2.多个文档的插入 集合名 数据 city “_id”:“1”,“cityname”:“重庆”,“population”:3213 “_id”:“2”,“cityname”:“上海”,“population”:2475 “_id”:“3”,“cityname”:“北京”,“population”:2184 “_id”:“4”,“cityname”:“成都”,“population”:2126 “_id”:“5”,“cityname”:“广州”,“population”:1873 “_id”:“6”,“cityname”:“深圳”,“population”:1756 “_id”:“7”,“cityname”:“武汉”,“population”:1373 “_id”:“8”,“cityname”:“天津”,“population”:1363 “_id”:“9”,“cityname”:“西安”,“population”:1299 School 占地校园排行榜 “_id”:“1”,“schoolname”:“台湾大学”,“area”:“3.4万公顷(340平方公里)” “_id”:“2”,“schoolname”:“东北林业大学”,“area”:“校园占地136公顷” “_id”:“3”,“schoolname”:“中国民用航空飞行学院”,“area”:“占地面积19000余亩” “_id”:“4”,“schoolname”:“江西农业大学”,“area”:“总占地面积1.6万亩” “_id”:“5”,“schoolname”:“中山大学”,“area”:“总面积达9.15平方公里” “_id”:“6”,“schoolname”:“浙江大学”,“area”:“占地面积7931901平方米” “_id”:“7”,“schoolname”:“吉林大学”,“area”:“校园占地面积735.79万平方米” “_id”:“8”,“schoolname”:“沈阳农业大学”,“area”:“占地面积10246亩” “_id”:“9”,“schoolname”:“厦门大学”,“area”:“学校占地9700多亩” “_id”:“10”,“schoolname”:“南京农业大学”,“area”:“总面积9000多亩”
4使用变量插入文档 准备文档文件如1.txt citydata([ {“_id”:“1”,“cityname”:“重庆”,“population”:3213}, {“_id”:“2”,“cityname”:“上海”,“population”:2475}, {“_id”:“3”,“cityname”:“北京”,“population”:2184}, {“_id”:“4”,“cityname”:“成都”,“population”:2126}, {“_id”:“5”,“cityname”:“广州”,“population”:1873}, {“_id”:“6”,“cityname”:“深圳”,“population”:1756}, {“_id”:“7”,“cityname”:“武汉”,“population”:1373}, {“_id”:“8”,“cityname”:“天津”,“population”:1363}, {“_id”:“9”,“cityname”:“西安”,“population”:1299} ]) doc([ {“_id”:“1”,“schoolname”:“台湾大学”,“area”:“3.4万公顷(340平方公里)”}, {“_id”:“2”,“schoolname”:“东北林业大学”,“area”:“校园占地136公顷”}, {“_id”:“3”,“schoolname”:“中国民用航空飞行学院”,“area”:“占地面积19000余亩”}, ]) ca([{“_id”:“4”,“schoolname”:“江西农业大学”,“area”:“总占地面积1.6万亩”}, {“_id”:“5”,“schoolname”:“中山大学”,“area”:“总面积达9.15平方公里”}, {“_id”:“6”,“schoolname”:“浙江大学”,“area”:“占地面积7931901平方米”}, {“_id”:“7”,“schoolname”:“吉林大学”,“area”:“校园占地面积735.79万平方米”}, {“_id”:“8”,“schoolname”:“沈阳农业大学”,“area”:“占地面积10246亩”}, {“_id”:“9”,“schoolname”:“厦门大学”,“area”:“学校占地9700多亩”}, {“_id”:“10”,“schoolname”:“南京农业大学”,“area”:“总面积9000多亩”} ]) db.school.insertMany(doc) 1.3.2 文档的查询 1.3.2 文档的基本查询 db.comment.find() 或 db.comment.find({}) 1查询集合的所有文档 db.comment.find()
2查询集合第一条文档 findOne()
这里你会发现每条文档会有一个叫_id的字段这个相当于我们原来关系数据库中表的主键当你在插入文档记录时没有指定该字段MongoDB会自动创建其类型是ObjectID类型。选择 如果我们在插入文档记录时指定该字段也可以其类型可以是ObjectID类型也可以是MongoDB支持的任意类型 3按条件的查询 如果我想按一定条件来查询比如我想查询userid为1003的记录怎么办很简单只 要在find()中添加参数即可参数也是json格式如下 db.comment.find({userid:‘1003’})
如果你只需要返回符合条件的第一条数据我们可以使用findOne命令来实现语法和find一样。如查询用户编号是1003的记录但只最多返回符合条件的第一条记录
4投影查询 db.comment.find({userid:“1003”},{userid:1,nickname:1}) 如果要查询结果返回部分字段则需要使用投影查询不显示所有字段只显示指定的字段。如查询结果只显示 _id、userid、nickname : db.comment.find({userid:“1003”},{userid:1,nickname:1})
B投影查询 db.collections.find({},{“name”:1}) //“_id”始终会被获取 db.collections.find({},{“name”:1,”_id”:0})//”_id”不会被获取
注在_id字段为0的时候其他字段可以写1 在_id字段为1的时候其他字段必须写1 如果是除了_id字段以外的其他字段必须同为1或者同为0
5比较查询
db.user.find({age:{$lt:30}}) //等同于 select * from user where age30;
实例创建集合 集合名 数据 city “_id”:“1”,“cityname”:“重庆”,“population”:3213 “_id”:“2”,“cityname”:“上海”,“population”:2475 “_id”:“3”,“cityname”:“北京”,“population”:2184 “_id”:“4”,“cityname”:“成都”,“population”:2126 “_id”:“5”,“cityname”:“广州”,“population”:1873 “_id”:“6”,“cityname”:“深圳”,“population”:1756 “_id”:“7”,“cityname”:“武汉”,“population”:1373 “_id”:“8”,“cityname”:“天津”,“population”:1363 “_id”:“9”,“cityname”:“西安”,“population”:1299 ci([ {“_id”:“1”,“cityname”:“重庆”,“population”:3213}, {“_id”:“2”,“cityname”:“上海”,“population”:2475}, {“_id”:“3”,“cityname”:“北京”,“population”:2184}, {“_id”:“4”,“cityname”:“成都”,“population”:2126}, {“_id”:“5”,“cityname”:“广州”,“population”:1873}, {“_id”:“6”,“cityname”:“深圳”,“population”:1756}, {“_id”:“7”,“cityname”:“武汉”,“population”:1373}, {“_id”:“8”,“cityname”:“天津”,“population”:1363}, {“_id”:“9”,“cityname”:“西安”,“population”:1299} ])
①查询人口数大于3000万的城市
②查询人口数大于2000万的城市
③查询人数小于2000万的城市
④查询人口数在1500-2000万的城市
或者 6逻辑查询 and查询 db.user.find( {$and: [ {age:20,sex:0} ] } ); // 等同于 select * from user where age20 and sex0
或者缺省$and db.user.find({age:20,sex:0}) 选择填空
7or查询 db.user.find({ $ or:[ {age:{$lt:24}}, {sex:1} ]}); //等同于 select * from user where age24 or sex1
查mongo
查询school中吉林大学和台湾大学的信息
8 in 和nin 查询 db.user.find({age:{$in:[18,19,20]}}) //等同于 select * from user where age in (18,19,20)
查询台湾大学吉林大学厦门大学
查询北京 南京 珠海的城市信息
9为空查询 db.user.find({name:{$exists:1}});不为空查询
db.school.find({area:{$exists:0}})查询为空的数据
10查询排序 db.collectins.find().sort({“age”:-1}) 注-1为逆序1为顺序 按人口数量的升序排序 db.citys.find().sort({population:1})
按人口的降序排序
12分页查询 使用函数limit()和skip()来实现分页查询 db.collections.find().limit().skip() //跳过多少行查询多少行 ①如查询前三条数据 limit(3) db.citys.find().limit(3)
②查询从第3条到第6条的数据 skip(2).limit(4) db.citys.find().limit(4).skip(2)
③查询人口数最多排名第3名的城市
db.citys.find().limit(1).skip(2).sort({population:-1}) 查询人口数从高到低排名第3名-第8名的城市 db.city2.find().limit(6).skip(2).sort({population:-1}) 13正则匹配 正则表达式用于模式匹配基本上是用于在文档中搜索字符串中的模式。它是一种将模式与字符序列匹配的通用方法。$regex运算符用作正则表达式用于在字符串中查找模式。 集合的数据为
①某文档包含某字段的模糊查询{ $regex:/xxx/ } 使用 sql 的写法select * from member where name like ‘%XXX%’ 在mongodb中db.member.find({“name”:{ KaTeX parse error: Expected EOF, got } at position 13: regex:/XXX/ }̲}) 实例查询城市名有京的城…regex:/^xxx/} 查询“上”开头的城市 db.citys.find({cityname:{$regex:/^上/}})
③查询以某字段为结尾的文档 { r e g e x : / X X X regex:/XXX regex:/XXX/} db.member.find({“name”:{ r e g e x : / X X X regex:/XXX regex:/XXX/}}) 查询城市名最后一个字为“海”的城市 db.citys.find( { cityname: { r e g e x : / 海 regex: /海 regex:/海/ } } )
④查询忽略大小写 {$regex:/XXX/i} 查询含有a的数据 db.citys.find( { cityname: { $regex: /a/i } } )
1.3.3 文档的更新 基本语法 db.collection.update(query, update, options) //或 db.collection.update( , , { upsert: , multi: , writeConcern: , collation: , arrayFilters: [ , … ], hint: document|string // Available starting in MongoDB 4.2 } ) 1局部修改 s e t / / 为了解决这个问题我们需要使用修改器 set //为了解决这个问题我们需要使用修改器 set//为了解决这个问题我们需要使用修改器set来实现 db.comment.update({_id:“2”},{$set:{likenum:NumberInt(889)}})
2批量的修改{multi:true} //更新所有用户为 1003 的用户的昵称为 凯撒大帝 //默认只修改第一条数据 db.comment.update({userid:“1003”},{KaTeX parse error: Expected EOF, got } at position 21: …nickname:凯撒2}}̲) //修改所有符合条件的数据…set:{nickname:“凯撒大帝”}},{multi:true}) 实例修改所有石家庄城市为廊坊 db.citys.update({ cityname: “石家庄” }, { $set: { cityname: “廊坊” } }, { multi: true } )
实例将城市名中包含 a 不区分大小写,修改为你好 db.citys.update({ cityname: { $regex: /a/i } }, { $set: { cityname: “你好” } }, { multi: true })
3列值增长的修改 i n c 增加运算 inc 增加运算 inc增加运算mul(乘法运算) //如果我们想实现对某列值在原有值的基础上进行增加或减少可以使用 KaTeX parse error: Expected }, got EOF at end of input: …ate({_id:3},{inc:{likenum:NumberInt(1)}}) 如修改北京人口在之前的数据上增加 500万
实例重庆人口增加一倍$mul
实例重庆人口减少3000万
4修改健名{KaTeX parse error: Expected EOF, got } at position 23: …{cityname:”重庆”}}̲ 实例修改万州中cityna…rename:{cityname:“citynames”}})
(5删除某个健名KaTeX parse error: Expected }, got EOF at end of input: …me:舟山}, ... {unset:{add:“”} … )
db.citys.update( {cityname:“舟山”}, {$unset:{add:“”}} )
(6)采用 $ min$max,修改当前值为给定的最小值或者最大值 如修改重庆人口为给定的最小值 db.citys.update({ cityname: “重庆” }, { $min: { population: 1000 } } )
db.citys.update({ cityname: “重庆” }, { KaTeX parse error: Expected EOF, got } at position 27: …lation: 4000 } }̲ ) 7ISODate()…set:{time:ISODate(“2021-01-01 10:10:10”)}})
1.3.4 文档的删除 1全部删除文档 db.comment.remove({}) 2删除集合 db.集合名.drop() 删除整个集合这个方法的效率更高 3删除_id1的记录 db.comment.remove({_id:“1”}) 如删除万州的城市 db.citys.remove({cityname:“万州”})
后面的应该不是上机考的内容闭卷笔试选择、手写命令、和简答题
2.1MongoDB索引 MongoDB是基于集合建立索引的索引的目的是提高查询效率。 如果没有建立索引当MongoDB读取数据时候是要扫描集合中的所有文档这种扫描的效率分层的低尤其在处理大数据时查询可能需要几十秒到几分钟时间这种效率对互联网的应用来说是示范可怕的。 2.1.1索引的分类 按照索引包含的字段数量可以分为单键索引和组合索引或复合索引。 按照索引字段的类型可以分为主键索引和非主键索引。 按照索引节点与物理记录的对应方式来分可以分为聚簇索引和非聚簇索引其 中聚簇索引是指索引节点上直接包含了数据记录而后者则仅仅包含一个指向数据记 录的指针。 2.1.2索引分类 按照索引包含的字段数量可以分为单键索引和组合索引或复合索引。 按照索引字段的类型可以分为主键索引和非主键索引。 按照索引节点与物理记录的对应方式来分可以分为聚簇索引和非聚簇索引其中聚簇索引是指索引节点上直接包含了数据记录而后者则仅仅包含一个指向数据记 录的指针。 2.1.3索引设计原则 1、每个查询原则上都需要创建对应索引 2、单个索引设计应考虑满足尽量多的查询 3、索引字段选择及顺序需要考虑查询覆盖率及选择性 4、对于更新及其频繁的字段上创建索引需慎重 5、对于数组索引需要慎重考虑未来元素个数 6、对于超长字符串类型字段上慎用索引 7、并发更新较高的单个集合上不宜创建过多索引 2.1.4索引操作 1默认自动创建_id建立唯一索引 避免重复插入_id值相同的文档 2单一健索引 db.集合名.createIndex({key:}) db.books.createIndex({name:-1}) key为健名,n为1或者-1 代表升序和降序 实例集合数据 中国古典十大名曲 集合名 文档 books {name:“高山流水”,content:“中国古琴曲属于中国十大古曲之一。传说先秦的琴师伯牙一次在荒山野地弹琴樵夫钟子期竟能领会这是描绘峨峨兮若泰山和洋洋兮若江河。伯牙惊道善哉子之心而与吾心同。钟子期死后伯牙痛失知音摔琴绝弦终生不弹故有高山流水之曲。”}
{name:”梅花三弄”,content:”《梅花三弄 [8] [11]》又名《梅花引》《梅花曲》《玉妃引》根据《太音补遗》和《蕉庵琴谱》所载相传原本是晋朝桓伊所作的一首笛曲后来改编为古琴曲。”}
{name:”汉宫秋月”,content:”《汉宫秋月》现流传的演奏形式有二胡曲、琵琶曲、筝曲、江南丝竹等。主要表达的是古代宫女哀怨悲愁的情绪及一种无可奈何、寂寥清冷的生命意境。”}
{name:”阳春白雪”,content:”《阳春白雪》 [2-3]是古典名曲为中国著名十大古曲之一。表现的是冬去春来大地复苏万物欣欣向荣的初春美景。”}
{name:”渔樵问答”,content:”《渔樵问答》是一首中国古琴名曲为中国十大古曲之一。此曲在历代传谱中有30多种版本有的还附有歌词。”}
{name:”广陵散”,content:”又名《广陵止息》。它是中国古代一首大型琴曲中国音乐史上非常著名的古琴曲著名十大古琴曲之一。”}
{name:”平沙落雁”,content:”又名《雁落平沙》是一首中国古琴名曲有多种流派传谱其意在借大雁之远志写逸士之心胸。”}
{name:”十面埋伏”,content:”乐曲整体可分为三部分由十三段带有小标题的段落构成分别是列营、吹打、点将、排阵、走队、埋伏、鸡鸣山小战、九里山大战、项王败阵、乌江自刎、众军奏凯、诸将争功和得胜回营。该曲以公元前202年刘邦与项羽垓下之战的史实为内容用标题音乐的形式描绘了激烈的战争场面虽为史实却也不乏丰富的感情色彩”} db([{name:“高山流水”,content:“中国古琴曲属于中国十大古曲之一。传说先秦的 琴师伯牙一次在荒山野地弹琴樵夫钟子期竟能领会这是描绘峨峨兮若泰山和洋洋兮若江河。 伯牙惊道善哉子之心而与吾心同。钟子期死后伯牙痛失知音摔琴绝弦终生不弹故 有高山流水之曲。”},{name:“梅花三弄”,content:“名梅花引、梅花曲、玉妃引根据太音补遗和蕉庵琴谱所载相传原本是晋朝桓伊所作的一首笛曲后来改编为古琴曲”}, {name:“阳春白雪”,content:“阳春白雪》 [2-3]是古典名曲为中国著名十大古曲之一。表现的是冬去春来大地复苏万物欣欣向荣的初春美景。”}])
案例2学生信息表 集合 文档记录 Student {_id:”20090101”,name:”王庆”,depart:”计算机科学与技术”} {_id:”20090102”,name:”周三”,depart:”计算机科学与技术”} {_id:”20090101”,name:”刘明明”,depart:”计算机科学与技术”} {_id:”20090101”,name:”王青云”,depart:”计算机科学与技术”}
3唯一索引 db.book.createIndex({name:1},{unique:true}) Name的值时唯一的测试 4复合索引 db.book.createIndex({key:n,key:n}) 5文本索引 db.book.createIndex({name:text}) 建立文档索引 6查看索引 #查看索引信息 db.books.getIndexes() #查看索引键 db.books.getIndexKeys() 7查看索引占用空间 db.collection.totalIndexSize([is_detail]) 8删除索引 #删除集合指定索引 db.col.dropIndex(“索引名称”) [备注]删除索引索引名要与查询的索引名一样
#删除集合所有索引 不能删除主键索引 db.col.dropIndexes() 9地理空间索引 在移动互联网时代基于地理位置的检索LBS功能几乎是所有应用系统的标配。 MongoDB为地理空间检索提供了非常方便的功能。 地理空间索引2dsphereindex就是 专门用于实现位置检索的一种特殊索引。 实例创建集合 db.res.insert({ restaurantId: 0, restaurantName: “兰州牛肉面”, location: { type: “Point”, coordinates: [73.97, 40.77] } }) 创建一个2dsphere索引 db.restaurant.createIndex({location : “2dsphere”})
MongoDB搭建集群 一、认识MongDB的复制集
二、运用MongoDB复制集搭建主从架构集群
1.创建数据目录
2.参考配置Mongod.conf文件 【注意事项】前面是4个空格
3.分别启动3个MOngoDB的节点 启动 MongoDB 进程 mongod -f D:\mongodb\data\db1\mongod.conf mongod -f D:\mongodb\data\db2\mongod.conf mongod -f D:\mongodb\data\db3\mongod.conf 如图所示
【注意】以上命令需要在3个不同的窗口执行执行后不可关闭窗口否则进程将直接结束。 4.配置复制集 1进入MongoDb主节点mongo shell Mongosh --port28017 2创建复制集 rs.initiate({ _id: “rs0”, members: [ {_id: 0,host: “localhost:28017”}, {_id: 1,host: “localhost:28018”}, {_id: 2,host: “localhost:28019”} ] }) 3观察节点信息发生变化 rs.status() —集群的基本信息 主节点
3测试集群 A.主节点测试登录 #连接primary节点 mongo --host 127.0.0.1 --port28017 db.users.insert({“name”:“liyong”,“age”:11}); db.users.find(); 可以看到集群搭建成功以后连接
测试主节点读数据 b.users.find(); #在从节点进行查询数据 我们可以看到这也一个错误需要执行rs.slaveOk();
rs.slaveOk(); #执行此命令以后我们就可以进行查询数据了
B.从节点测试 secondary节点 mongo --host 127.0.0.1 --port28018 插入文档返回失败从节点不能写入数据 db.users.insert({“name”:“liyong”,“age”:11});
插入数据的时候提示我们了不是主节点这也验证了前面提到的再从节点是只读的主节点可读可写 C.测试从节点读取数据 默认的情况下从节点是没有读写的权限的 设置允许从节点读数据 rs.secondaryOk() 然后从节点就可以写数据 测试关闭primary节点演示主节点重新选取 三、MongoDB分片搭建集群 5mongodb分片集群的使用 A.连接路由服务器 Mongosh --port27017 sh.status() ##查看分片集群的状态关注shards和databases分组
B、分片集群添加数据角色数据角色为副本集的方式 sh.addShard(“rs10/127.0.0.1:29020,127.0.0.1:29021,127.0.0.1:29022”) sh.addShard(“rs11/127.0.0.1:29023,127.0.0.1:29024,127.0.0.1:29025”) C.查看分片集群信息 sh.status()
1.分片集群介绍 高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的CPU耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘IO上。 为了解决这些问题,有两个基本的方法: 垂直扩展和水平扩展。 垂直扩展增加更多的CPU和存储资源来扩展容量。 水平扩展:将数据集分布在多个服务器上。水平扩展即分片。 2.MongoDB分片集群简介 (1)分片介绍 分片是指将数据拆分并分散存放在不同机器上的过程有时也用分区来表示这个概念。将数据分散到不同的机器上不需要功能强大的计算机就可以存储更多的数据处理更大的负载。MongoDB支持自动分片可以使数据库架构对应用程序不可见简化系统管理。对应用程序而言就如同始终在使用一个单机的MongoDB服务器一样。 2MongoDB分片
分片集群组件介绍 构建一个MongoDB的分片集群需要三个重要组件分别是分片服务器Shard Server、配置服务器Config Server、路由服务器Router Server。 Shard Server 每个分片服务器都是一个mongod数据库实例用于存储实际的数据块整个数据库集合分成多个存储在不同的分片服务器中。在实际生产中一个Shard Server可以由多台机器组成一个副本集来承担防止因主节点单点故障导致整个系统崩溃。 Config Server 这是独立的一个mongod进程存储所有数据库元信息路由、分片的配置。mongos本身没有物理存储分片服务器和数据路由信息只是缓存在内存里配置服务器则实际存储这些数据。 mongos第一次启动或者关掉重启就会从config server加载配置信息以后如果配置服务器信息变化会通知到所有的mongos更新自己的状态这样mongos就能继续准确路由。在生产环境通常设置多个config server因为它存储了分片路由的元数据防止单点数据丢失 Router Server 这是独立的一个mongod进程Router Server在集群中可作为路由使用客户端由此 接入让整个集群看起来像是一个单一的数据库提供客户端应用程序和分片集群之间的接口。 Router Server本身不保存数据启动时从Config Server加载集群信息到缓存中并将客户端的请求路由给每个Shard Server在各Shard Server返回结果后进行聚合并返回给客户端。 在实际生产环境中副本集和分片是结合起来使用的可满足实际应用场景中高可用性和高可扩展性的需求。
3.MongoDB分片集群的部署通常涉及以下几个步骤 1配置分片shard服务器 2配置配置服务器config servers 3设置mongos路由实例 4启动集群 5分片数据
4.MongoDB分片集群部署实战演练 1分片集群的搭建说明 使用同一份mongodb二进制文件即mongod.conf 修改对应的配置就能实现分片集群的搭建 Config Server使用28017、28018、28019三个端口来搭建3台–也是采用复制集这种搭建 Router Server使用27017、27018两个端口来搭建2台—也是采用复制集这种搭建
Shard Server 使用29020、29021、29022290232902429025六个端口来搭建三个一组模拟两个分片两个数据的集群每个分片采用3个节点搭建复制集集群 2Config Server搭建 【备注】假设Config server3台数据库的数据目录为
A.配置mongod.conf mongodb配置角色的搭建配置文件路径/usr/local/mongodb/28017/mongod.conf 文件内容参考如下文件
mongod.conf
c:\data\db1\mongod.conf
systemLog: destination: file path: D:\mongodb\fenpian\config1\mongod.log #日志文件路径 logAppend: true storage: dbPath: D:\mongodb\fenpian\config1 # 数据目录 net: bindIp: 0.0.0.0 port: 28017 # 端口 replication: replSetName: rs1
##配置分片角色 sharding: clusterRole: configsvr
B.启动mongodb configsvr实例 mongod.exe -f D:\mongodb\fenpian\config1\mongod.conf mongod.exe -f D:\mongodb\fenpian\config2\mongod.conf mongod.exe -f D:\mongodb\fenpian\config3\mongod.conf
C.Windows操作系统下 侦听端口 使用PowerShell 打开PowerShell可以在开始菜单中搜索“PowerShell”。 输入命令 Get-NetTCPConnection然后按回车。 这将显示所有TCP连接的详细信息包括状态为“Listen”的端口。
D.分片集群的配置角色副本集搭建 1进入MongoDb主节点mongo shell mongosh --port28017 2创建复制集 ca{_id:“rs1”, configsvr: true, members:[{_id:0,host:“127.0.0.1:28017”},{_id:1,host:“127.0.0.1:28018”},{_id:2,host:“127.0.0.1:28019”}] } cmd【备注】_id的值与配置文件 “replSetName: rs1” 是一样的 rs.initiate(ca) 3#查看副本集状态 rs.status()
3Shard Server搭建 A.数据角色分片集群的数据角色里存储着真正的数据所以数据角色一定得使用副本集 29020、29021、29022一个集群数据角色rs10 29023、29024、29025一个集群数据角色rs11 设计分片服务器
备注线上生产环境一个集群中应至少启用三个mongodb实例
B.在配置文件中设置角色为 shardsvr
注意有两个分片集群其中复制集的名字分别设置为rs10 和rs11
C.Shard Server启动所有实例
mongod.exe -f D:\mongodb\fenpian\shard-29020\mongod.conf mongod.exe -f D:\mongodb\fenpian\shard-29021\mongod.conf mongod.exe -f D:\mongodb\fenpian\shard-29022\mongod.conf mongod.exe -f D:\mongodb\fenpian\shard-29023\mongod.conf mongod.exe -f D:\mongodb\fenpian\shard-29024\mongod.conf mongod.exe -f D:\mongodb\fenpian\shard-29025\mongod.conf
D.数据角色的副本集搭建 ①数据角色rs10 1进入MongoDb主节点mongo shell mongosh --port29020 2创建复制集 config{_id:“rs10”, members:[{_id:0,host:“127.0.0.1:29020”},{_id:1,host:“127.0.0.1:29021”},{_id:2,host:“127.0.0.1:29022”}]}
rs.initiate(config) (3)查看分片集群装填 rs.status()
②数据角色rs11 1进入MongoDb主节点mongo shell mongosh --port29023 2创建复制集 config{_id:“rs11”, members:[{_id:0,host:“127.0.0.1:29023”},{_id:1,host:“127.0.0.1:29024”},{_id:2,host:“127.0.0.1:29025”}]} rs.initiate(config) (3)查看分片集群装填 rs.status()
(4Router Server搭建 mongodb中的router角色只负责提供一个入口不存储任何的数据。 A.配置mongodb.conf Router配置文件路径27017/mongodb.conf 【注意事项】#不需要配置副本集名称 Router最重要的配置是 1指定configsvr的地址使用副本集idip端口的方式指定 2配置多个Router任何一个都能正常的获取数据 3##不参与数据存储所以不需要配置存储数据的目录 配置文件 systemLog: destination: file path: D:\mongodb\fenpian\27017\mongod.log #日志文件路径 logAppend: true ##不参与数据存储所以不需要配置存储数据的目录 #storage:
dbPath: D:\mongodb\fenpian\27017 # 数据目录
net: bindIp: 0.0.0.0 port: 27018 # 端口 #replication:
replSetName: rs1
##配置分片角色 #配置configsvr副本集和IP端口 sharding: configDB: rs1/127.0.0.1:28017,127.0.0.1:28018,127.0.0.1:28019
B、启动mongodb Routersvr实例 mongos -f D:\mongodb\fenpian\27017\mongod.conf mongos -f D:\mongodb\fenpian\27018\mongod.conf 5mongodb分片集群的使用 A.连接路由服务器 Mongosh --port27017 sh.status() ##查看分片集群的状态关注shards和databases分组
B、分片集群添加数据角色数据角色为副本集的方式 sh.addShard(“rs10/127.0.0.1:29020,127.0.0.1:29021,127.0.0.1:29022”) sh.addShard(“rs12/127.0.0.1:29023,127.0.0.1:29024,127.0.0.1:29025”) C.查看分片集群信息 sh.status()
(6)测试分片集群 A.实际操作演练 默认添加数据是没有使用分片存储的操作都是在路由服务器中如 #插入500条数据做实验 use data1 for (i1; i500; i){db.users.insert({name:‘test’ i, id:i})} sh.status() ##查看分片集状态可以看到500条数据全部插入到了其中一个rs11副本集群中并没有分片
B.配置hash分片存储 针对某个数据库的某个集合使用hash分片存储这样就能实现同一个集合分配两个数据角色 【备注】当某个数据库要开启分片存放数据时这个数据库必须要创建索引
(1)设置data1数据库中users集合的索引 use data1 db.users.createIndex({id:1})
(2)切换到admin数据库中对 data1中集合users设置分片存储数据 use admim db.runCommand({ enablesharding : “data1”}) #使用此命令开启data1数据库的分片存储 db.runCommand({ shardcollection : “data1.users”, key : {id:“hashed”}}) ##根据data1数据库中users集合的默认_id字段开启hash分片存储 3测试数据2插入数据校验数据被均匀分配到两个数据库中 use data1 for (i1; i800; i){db.users.insert({name:‘test’ i, id:i})} 4查看分片集群的状态 sh.status()
5路由服务器进入到data1数据库中 查看users集合有多少数据 db.users.count() #有多少条数据
(7)进入分片服务器rs10 mongosh --port29020 show dbs use data1 show tables db.users.count()
(8)进入分片服务器rs11
以上步骤就实现了MongoDB的分片集群的搭建