当前位置: 首页 > 科技观察

MongoDB,这篇文章足够入门!

时间:2023-03-12 20:29:39 科技观察

1。简介在介绍MongoDB之前,先介绍一下业务开发中遇到的痛点,让大家对它有一个更清晰的认识!最近在使用数据库存储数据的时候发现了这样一个坑。比如监听消息队列中的消息,原来的做法是将监听到的消息的json数据存储到数据库中,这样异常的消息数据就可以追溯。消息内容使用text类型存储,一开始因为数据内容很短,没什么问题,但是随着业务的扩大,接收到的消息内容越来越长,最后发现text字段数据库中的类型不能很好地支持查询,所以在这个时候,开始考虑使用更合适的数据库来存储这种消息数据!经过一番讨论,大家一致认为MongoDB是这类json消息数据存储的最佳选择!据官方介绍,MongoDB是介于关系型数据库和非关系型数据库之间的产物。它是非关系型数据库中功能最多、与关系型数据库最相似的高性能NoSQL数据库。MongoDB将数据存储为文档,数据结构由键值对(key=>value)组成。其中的文档类似于JSON对象。字段值可以包含其他文档、数组、文档数组,数据结构支持非常灵活!确实,在使用过程中,正如介绍的那样,数据存储和查询的性能都非常快,非常符合我们的需求!话不多说,一起来看看这个数据库应该怎么用吧!2.环境配置在学习之前,我们需要先搭建环境。MongoDB的安装也很简单!2.1.Windows平台如果你在Windows平台上,MongoDB提供了预编译的二进制文件,可用于32位和64位系统。安装基本上是傻瓜式操作。登录MongoDB官网下载安装包,然后一步步操作!2.2.Linux平台生产环境基本上是Linux平台。为了和制作保持一致,小编使用的服务器是CentOS7,安装过程比较简单!创建资源文件:sudovim/etc/yum.repos.d/mongodb-org-4.0.repo编辑内容如下:[mongodb-org-4.0]name=MongoDBRepositorybaseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/gpgcheck=1enabled=1gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc运行以下命令安装mongodb:sudoyuminstall-ymongodb-org安装完成后,配置mongod.conf允许远程连接#编辑mongod.confvim/etc/mongod.conf#将net:bindIp:127.0.0.1改为0.0.0.0net:bindIp:0.0.0.0最后启动服务:#启动服务systemctlstartmongod#其他服务#关闭服务systemctlstopmongod#重启服务systemctlrestartmongod#启动systemctlenablemongod至此,环境配置完成!3.数据库操作MongoDB的数据操作是开发者最频繁的部分。当你第一次使用它的时候,你会发现它和我们传统使用的sql脚本命令完全不同,但又是相似的。下面我们一起来看看起来学习更多!3.1.进入MongoDB进入MongoDB服务非常简单,输入以下命令即可进入!以mongo为例,在CentOS中输入命令后,进入的服务界面如下:3.2.创建数据库MongoDB创建数据库的语法格式如下:useDATABASE_NAME如果数据库不存在,则创建数据库,否则切换到指定的数据库,输入以下命令查询数据库列表:#Querydatabaselistshowdbs#命令输出结果:adminconfiglocal可以看到MongoDB中当前有3个数据库!输入以下命令切换到admin数据库:useadmin输入db命令查询当前数据库:db3.3。创建用户默认情况下没有用户,无法操作数据库,所以我们需要创建一个用户。同时给他分配权限!3.3.1.创建管理员用户创建一个用户,密码为admin,并赋予该用户userAdminAnyDatabase角色,指定数据库为admin!#创建admin用户db.createUser({user:"admin",pwd:"admin",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})其中字段含义如下:user:用户名;pwd:用户密码;roles:指定用户的角色,可以使用空数组为新用户设置一个空角色。角色中的角色:指定角色。dbinroles:指定的数据库,比如上面的角色userAdminAnyDatabase,只有admin数据库才有。MongoDB中的角色代表一个用户是否有访问数据库或操作数据库的权限。了解这一点非常重要!MongoDB角色定义如下:3.3.2。创建一个没有访问限制的超级用户如果你想创建一个没有访问限制的超级用户,只需分配root角色即可!#创建超级用户db.createUser({user:"root",pwd:"root",roles:["root"]})3.3.3.创建业务数据库普通用户如果要创建业务数据库普通用户,比如只能访问test_db数据库,只负责新增、查看、修改和删除数据。#创建或切换数据库为test_dbusetest_db#创建一个test用户,并且只有test_db的访问权限,只有表的读写权限db.createUser({user:"test",pwd:"test",roles:[{角色:“readWrite”,db:“test_db”}]})3.3.4。验证用户是否可以正常登录对于刚刚创建的用户,我们如何验证它是否可以正常登录呢?命令也很简单!如果db.auth("test","test")返回1,则认证正常!3.3.5.查询当前数据库用户信息查询创建的用户,命令也很简单!#查看创建的用户showusers3.3.6,修改用户密码有时候,我们会忘记密码,可以通过以下方式修改!#修改用户密码db.changeUserPassword("username","xxxxx")3.3.7.删除用户如果某个用户需要去激活,可以通过以下方式删除#切换指定数据库usetest_db#删除用户db.dropUser('test')3.3.8.删除数据库如果一个数据库需要停用,可以通过以下方式删除(只有超级管理员才有权限删除)#切换指定数据库使用test_db#删除数据库db.dropDatabase()3.4、创建MongoDB没有的集合表的概念,对应的定义叫做:集合。我们在关系型数据库中看到的表数据,在MongoDB中定义为:document。MongoDB也被很多人称为文档数据库!在关系数据库中,表数据是逐行存储的,但在MongoDB中,情况可能并非如此。如果你存储的json很复杂,嵌套很深,那么MongoDB存储的行数可能会很深。有时候类似于我们在页面上看到的父子表结构!3.4.1.创建集合使用MongoDB中的createCollection()方法创建集合。语法格式:db.createCollection(name,options)参数说明:name:要创建的集合名称options:可选参数,指定与内存大小和索引相关的选项例如,在test_db数据库中创建一个tb_user集合:#Switch到test_db数据库使用test_db#创建tb_user集合db.createCollection("tb_user")#Outputresult{"ok":1}如果想查看已有的集合,可以使用showcollections命令!showcollections以下是带有几个关键参数的createCollection()的用法。下面命令表示:创建固定集合tb_user,整个集合空间大小为6142800KB,最大文档数为10000:db.createCollection("tb_user",{capped:true,autoIndexId:true,size:6142800,max:10000})在MongoDB中,通常不需要手动创建集合。当您插入文档时,MongoDB会自动创建集合!#插入一条文档数据到集合tb_userdb.tb_user.insert({"name":"张三"})#查询集合showcollections#输出结果tb_user3.4.2,删除一个集合使用drop()方法来删除MongoDB中的一个集合。语法格式:db.collection.drop()例如删除test_db数据库中的tb_user集合:#切换到test_db数据库usetest_db#创建tb_user集合db.tb_user.drop()#输出结果true3.4创建一个document创建一个文档,类似于我们在关系型数据库中向数据库中插入数据的方式,操作也非常简单!3.4.1.插入文档MongoDB使用insert()或save()方法将文档插入到集合中。语法如下:db.COLLECTION_NAME.insert(document)ordb.COLLECTION_NAME.save(document)save():如果_id主键存在则更新数据,不存在则插入数据。insert():如果插入数据的主键已经存在,则抛出异常,提示主键重复,不保存当前数据。比如在test_db数据库的tb_user集合中,插入一条数据:db.tb_user.insert({name:"张三",age:18,gender:"男",tags:['宅男','技术控制','严重脱发']})如果集合在数据库中不存在,MongoDB会自动创建集合并插入文档。查看插入的文档,命令如下:#查询tb_user集合中的数据db.tb_user.find()#Outputresult{"_id":ObjectId("6022310f6b5e964b0a5916e6"),"name":"张三","age":18,"gender":"Male","tags":["宅男","技控","严重脱发"]}当然也可以使用save()命令插入,如果不指定_id字段的save()方法类似于insert()方法。如果指定了_id字段,则该_id的数据将被更新。比如更新张三的年龄为30岁!db.tb_user.save({_id:ObjectId("6022310f6b5e964b0a5916e6"),name:"张三",age:30,gender:"男",tags:['宅男','技控','严重脱发']})查看文档:db.tb_user.find()#outputresult{"_id":ObjectId("6022310f6b5e964b0a5916e6"),"name":"张三","age":30,"gender":"男","tags":["宅男","技控","严重脱发"]}3.4.2.更新文档MongoDB提供了update()和save()方法来更新集合中的文档。语法格式如下:db.collection.update(,,{upsert:,multi:,writeConcern:})query:更新的查询条件,类似where后面的sql更新查询。update:更新对象和一些更新操作符(如inc...)等,也可以理解为sql中设置后的upsertinsertobjNew,true为insert,默认为false,不插入multi:可选,mongodb默认为false,只更新找到的第一条记录,如果该参数为true,则根据条件找到的多条记录全部更新。writeConcern:可选,抛出异常的级别。比如更新张三的年龄为22岁!db.tb_user.update({'name':'张三'},{$set:{'age':22}})查询更新后的数据:db.tb_user.find()#outputresult{"_id":ObjectId("602235216b5e964b0a5916e8"),"name":"张三","age":22,"gender":"男","tags":["宅男","技控","严重脱发"]}上面的语句只会修改第一个找到的文档。如果要修改多个相同的文档,需要将multi参数设置为true。db.tb_user.update({'name':'张三'},{$set:{'age':22}},{multi:true})3.4.3、删除文档MongoDB中的remove()函数从集合中移除数据的语法如下:db.collection.remove(,{justOne:,writeConcern:})query:(可选)被删除文档的条件。justOne:(可选)如果设置为true或1,则只删除一个文档,如果不设置,或使用默认值false,则删除所有符合条件的文档。writeConcern:(可选)抛出异常的级别。例如删除名字为张三的用户:db.tb_user.remove({'name':'张三'})查询数据是否删除:db.col.find()#结果为空3.4.4、查询文档MongoDB使用find()方法查询文档。语法格式如下:db.collection.find(query,projection)query:可选,使用查询操作符指定查询条件projection:可选,使用投影操作符指定返回的key。查询时,返回文档中的所有键值,省略该参数即可(默认省略)。如果你需要以一种易于阅读的方式读取数据,你可以使用pretty()方法。语法如下:db.col.find().pretty()首先,我们插入几条数据,插入结果如下:比如查询一个性别为男性的用户信息:#单条件查询,类似在sql语句db.tb_user.find({"gender":"male"})中查询gender='male'性别为男性,姓名为张三用户:#多条件查询,类似gender='Male'andname='李四'insqlstatementdb.tb_user.find({"gender":"Male","name":"李四"})查询性别为男或姓名为张三的用户:#多条件查询,类似于sql语句中的gender='male'orname='李四'db.tb_user.find({$or:[{"gender":"Male"},{"name":"Lisi"}]})查询性别为男或姓名为张三且年龄大于30的用户:#多条件查询,类似sql语句中的age>30and(gender='男'orname='李四')db.tb_user.find({"age":{$gt:30},$or:[{"gender":"Male"},{"name":"李四"}]})3.4.5。分页查询文档如果需要分页查询集合数据,可以使用limit()和skip()函数,其中limit()表示读取几条数据,skip()表示从几条数据开始从。#从集合中第三行数据开始,读取2条数据返回db.tb_user.find({}).limit(2).skip(3)3.4.6,文档排序同关系型数据库,MongoDB可以使用sort()方法进行排序,通过参数指定排序字段,使用1和-1指定排序方式,其中1为升序,-1为降序。比如查询tb_user文档,按照年龄升序排序!db.tb_user.find({}).sort({"age":1})3.5。创建索引索引通常可以大大提高查询效率。如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件,并选择那些符合查询条件的记录。扫描整个集合的查询效率很低,尤其是在处理大量数据时,查询可能需要几十秒甚至几分钟,这对网站的性能是非常致命的。3.5.1.创建索引MongoDB使用createIndex()方法创建索引。语法如下:db.collection.createIndex(keys,options)语法中Key值为你要创建的索引字段,1表示按升序创建索引,如果要创建索引按降序,指定-1!例如,在tb_user文档中创建一个关于age的索引!db.tb_user.createIndex({"age":1})创建索引是一项耗时的操作。我们也可以通过参数配置在后台创建索引。db.tb_user.createIndex({"age":1},{background:true})通过在创建索引时添加选项background:true允许创建工作在后台执行!3.5.2.查看索引MongoDB提供了getIndexes()方法来查看索引。比如查询tb_user集合中的索引:db.tb_user.getIndexes()3.5.3、删除不再需要的索引,我们可以删除。删除索引时,可以删除集合中的某个索引,也可以删除所有索引。语法格式:db.COLLECTION_NAME.dropIndex("INDEX-NAME")比如删除集合tb_usercollection中的年龄索引:#queryindexdb.tb_user.getIndexes()#outputresult[{"v":2,"key":{"_id":1},"name":"_id_","ns":"test_db.tb_user"},{"v":2,"key":{"age":1},"name":"age_1","ns":"test_db.tb_user"}]删除对应的age_1索引!db.tb_user.dropIndex("age_1")4.Client对于任何数据库,如果没有可视化界面操作,在开发时可以说是极为不便。下面推荐一个我经常使用的客户端。Robo3T(免费,轻量级),可以访问官网获取Studio3T(综合,付费),访问官网地址获取第二个,整体体验优于Robo3T,两者的功能都是比较齐全!使用时可以根据个人喜好选择!第五,迈出重要一步。网上发现很多mongodb被黑,这让大家把目光转向了mongodb的权限控制。其实mongodb本身就有一套完整的RBAC权限控制体系。这次hack基本上是没有按照mongodb的生产环境部署手册做的结果。我们平时玩mongodb,习惯了不设置用户名和密码。当我们的数据库放在公网上的时候,因为我们没有设置用户名和密码,任何人都可以随便访问,而且因为我们没有开启授权访问,任何登录mongodb服务器的用户都拥有最高权限!一些居心叵测的人发现后可以复制我们的数据,删除我们的数据库,勒索赎金!再次提醒所有同学,不要把所有的技能都学了,大门还开着,抱怨我们的防御塔怎么一直被毁!以上面CentOS7安装为例,修改/etc/mongod.conf,在security部分添加如下配置,并开启授权访问!security:authorization:enabled修改完成后,重启mongodb服务:#RestartservicesystemctlrestartmongodVI.小结本文主要围绕MongoDB的使用,从环境配置、数据库使用,到客户端工具选择,做一个简单的介绍。