Mongodb操作使用说明
一、数据库的种类
早期比较流行的数据库模型有三种,分别为层次式数据库、网络式数据库和关系型数据库。而在当今的互联网中,最常用的数据库模型主要是两种,即关系型数据库(MySQL 互联网市场 ,Oracle 传统企业)和非关系型数据库(Redis,mongb)。
(一)关系数据库的特点
关系型数据库中的表都是存储一些格式化的数据结构,每个元组字段的组成都一样,即使不是每个元组都需要所有的字段,但数据库会为每个元组分配所有的字段,这样的结构可以便于表与表之间进行连接等操作,但从另一个角度来说它也是关系型数据库性能瓶颈的一个因素。而非关系型数据库以键值对存储,它的结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,这样就不会局限于固定的结构,可以减少一些时间和空间的开销
(二)NOSQL非关系型数据库的主要特点
非关系型数据库以键值对存储,它的结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,这样就不会局限于固定的结构;nosql数据库简单易部署,基本都是开源软件;nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,查询速度快;nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式。缺点是对事务的支持能力较弱。
nosql典型产品memcached (纯内存),redis(持久化缓存),mongodb(文档的数据库),
下面对三种非关系数据库做一定介绍。
1.Redis
优点
1.支持多种数据结构,如 string(字符串)、 list(双向链表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基数估算)
2.支持持久化操作,可以进行aof及rdb数据持久化到磁盘,从而进行数据备份或数据恢复等操作,较好的防止数据丢失的手段。
3.支持通过Replication进行数据复制,通过master-slave机制,可以实时进行数据的同步复制,支持多级复制和增量复制,master-slave机制是Redis进行HA的重要手段。
4.单线程请求,所有命令串行执行,并发情况下不需要考虑数据一致性问题。
5.支持pub/sub消息订阅机制,可以用来进行消息订阅与通知。
6.支持简单的事务需求,但业界使用场景很少,并不成熟。
缺点
1.Redis只能使用单线程,性能受限于CPU性能,故单实例CPU最高才可能达到5-6wQPS每秒(取决于数据结构,数据大小以及服务器硬件性能,日常环境中QPS高峰大约在1-2w左右)。
2.支持简单的事务需求,但业界使用场景很少,并不成熟,既是优点也是缺点。
3.Redis在string类型上会消耗较多内存,可以使用dict(hash表)压缩存储以降低内存耗用。
2.Memcache
优点
1.Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key、value的字节大小以及服务器硬件性能,日常环境中QPS高峰大约在4-6w左右)。适用于最大程度扛量。
2.支持直接配置为session handle。
缺点
1只支持简单的key/value数据结构,不像Redis可以支持丰富的数据类型。
2.无法进行持久化,数据不能备份,只能用于缓存使用,且重启后数据全部丢失。
3.无法进行数据同步,不能将MC中的数据迁移到其他MC实例中。
4.Memcached内存分配采用Slab Allocation机制管理内存,value大小分布差异较大时会造成内存利用率降低,并引发低利用率时依然出现踢出等问题。需要用户注重value设计。
3.MongoDB
优点
1.更高的写负载,MongoDB拥有更高的插入速度。
2.处理很大的规模的单表,当数据表太大的时候可以很容易的分割表。
3.高可用性,设置M-S不仅方便而且很快,MongoDB还可以快速、安全及自动化的实现节点(数据中心)故障转移。
4.快速的查询,MongoDB支持二维空间索引,比如管道,因此可以快速及精确的从指定位置获取数据。MongoDB在启动后会将数据库中的数据以文件映射的方式加载到内存中。如果内存资源相当丰富的话,这将极大地提高数据库的查询速度。
5.非结构化数据的爆发增长,增加列在有些情况下可能锁定整个数据库,或者增加负载从而导致性能下降,由于MongoDB的弱数据结构模式,添加1个新字段不会对旧表格有任何影响,整个过程会非常快速。
缺点
1.不支持事务。
2.MongoDB占用空间过大 。
3.MongoDB没有成熟的维护工具。
4.Redis、Memcache和MongoDB的区别
(1)性能
三者的性能都比较高,总的来讲:Memcache和Redis差不多,要高于MongoDB。
(2)便利性
memcache数据结构单一。
redis丰富一些,数据操作方面,redis更好一些,较少的网络IO次数。
mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。
(3)存储空间
redis在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key value设置过期时间(类似memcache)。
memcache可以修改最大可用内存,采用LRU算法。
mongoDB适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起。
(4)可用性
redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡。
Memcache本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。
mongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制。
(5)可靠性
redis支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响。
memcache不支持,通常用在做缓存,提升性能。
MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性。
(6)一致性
Memcache 在并发场景下,用cas保证一致性。
redis事务支持比较弱,只能保证事务中的每个操作连续执行。
mongoDB不支持事务
(7)数据分析
mongoDB内置了数据分析的功能(mapreduce),其他两者不支持。
(8)应用场景
redis:数据量较小的更性能操作和运算上。
memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)。
MongoDB:主要解决海量数据的访问效率问题
结合我们IFinder项目数据量大,单表容量大,需要查询速度快和插入速度快等特点,我们选用MongoDB。
5.MongoDB的安装:
- 进入到/usr/local/source目录:
cd /usr/local/source - 运行如下命令: tar -zxvf mongodb-linux-i686-3.2.13-rc0.gz -C /usr/local/mongoDB
3. 创建数据库文件夹
cd /usr/local/mongodb
mkdir data
4. 创建日志文件夹
cd /usr/local/mongodb
mkdir logs
5 创建配置文件夹etc
cd /usr/local/mongodb
mkdir etc
6 创建配置文件mongodb.conf
cd /usr/local/mongodb/etc
vim mongodb.conf
配置内容:
dbpath = /usr/local/mongodb/data
logpath = /usr/local/mongodb/logs/mongodb.log
logappend = true
bind_ip = 0.0.0.0
port = 27017
auth = false - mongodb安装好后第一次进入是不需要密码的,也没有任何用户,通过shell命令可直接进入,cd到mongodb目录下的bin文件夹,执行命令./mongo即可,如下所示:
./mongod --config /usr/local/mongodb/etc/mongodb.conf
8.添加管理用户(mongoDB 没有无敌用户root,只有能管理用户的用户 userAdminAnyDatabase)
利用mongo命令连接mongoDB服务器端:
创建用户
use admin
switched to db admin
db.createUser( {user: “pfnieadmin”,pwd: “123456”,roles: [ { role: “userAdminAnyDatabase”, db: “admin” } ]});
注:添加完用户后可以使用show users或db.system.users.find()查看已有用户.
9、添加完管理用户后,关闭MongoDB,并使用权限方式再次开启MongoDB,这里注意不要使用kill直接去杀掉mongodb进程,(如果这样做了,请去data/db目录下删除mongo.lock文件),可以使用db.shutdownServer()关闭.
10、使用权限方式启动MongoDB
在配置文件中添加:auth=true , 然后启动,进入mongo shell,使用admin数据库并进行验证,如果不验证,是做不了任何操作的。
use admin
db.auth(“pfnieadmin”,“123456”) #认证,返回1表示成功
6.出现的问题
安装完成后,使用python程序连接数据库,会出现ServerSlectionTimoutError:10.62.24.115:27017 timedout
解决方案:永久开放27017端口
7.MongoDB的操作使用技巧
(1)简单查找(库(test),表(data))
查找文档:db.data.find({‘a’: ‘b’})
删除文档:db.data.remove({‘a’: ‘b’})
查找找到某一天的数据:
db.data.find({‘日期’ : “20190311”)})
删除某一天的数据:
db.data.remove({‘日期’ : “20190311”})
小于100的数据:
db.data.find({‘干扰大小’: {KaTeX parse error: Expected 'EOF', got '}' at position 8: lt :100}̲}) 小于等于:lte
大于:
g
t
大
于
等
于
:
gt 大于等于:
gt大于等于:gte
不等于:KaTeX parse error: Expected '}', got 'EOF' at end of input: ….find({“干扰大小”:{gte:100"), $lte: 150)}}).count()
or
db.col.find(
{
o
{key1: value1}, {key2:value2}
]
})
json中的嵌套对象查询,采用“点”的方式(适用于多层字典),且可以避免使用值:
db.data.find({“a.b”: {KaTeX parse error: Expected 'EOF', got '}' at position 13: exists: true}̲}) 某个字段存在,且小于10…exists: 1, $lte: 100}}).count()
(2)更新(库(test),表(data))
db.data.update({‘市’: ‘怀化市’}, {KaTeX parse error: Expected 'EOF', got '}' at position 21: …{'特殊干扰': “a类型”}}̲ ,false, true) …exists: true}}, {KaTeX parse error: Expected 'EOF', got '}' at position 16: inc: {'a.b': 2}}̲) 数组修改器--push :
db.data.update({“name” : “toyota”},{KaTeX parse error: Expected '}', got 'EOF' at end of input: push:{"title":{each:[“a”, “c”]}}})(title的键值必须为列表,
e
a
c
h
表
示
分
开
插
入
,
不
然
会
作
为
列
表
整
体
插
入
)
去
重
插
入
−
−
each表示分开插入,不然会作为列表整体插入) 去重插入--
each表示分开插入,不然会作为列表整体插入)去重插入−−addToSet:
db.data.update({“name” : “toyota”},{KaTeX parse error: Expected '}', got 'EOF' at end of input: push:{"title":{addToSet:[“a”, “c”]}}})
字段改名:
db.post.update({$rename:{url:‘site’}})
(3)删除(库(test),表(data))
删除数据库:db.dropDatabase();
删除表:db.data.drop()
删除某个key:
db.data.update({“日期” : “20190311”},{"$unset":{‘特殊干扰’}})(删除keydata)set和unset的区别(set可以更新键值,若没有相应的键,则增加),unset则是删除键名。
(4)DB和表的拷贝
复制数据库:
db.copyDatabase(fromdb,todb,fromehost,username,password)
重命名数据库:
db.copyDatabase(fromdb,todb)
重命名集合:
db.getcollection(“data”).renameCollection(“data_temp”)
复制表到另一个服务器上的数据库:db.runCommand({clonecollection:“test.solution”,frome:”ip:port”,copyIndexes:true})
同一个服务器上不同数据库之间表的拷贝:
Db.solutions.find().forEach(function(d)){db.getSiblingDB(“test”).[“solutions”].insert(d)}
开启jupyter端口
firewall-cmd --add-port=27017/tcp
jupyter notebook --no-browser --port 8088 --ip=10.62.24.115
Vim /root/.jupyter/jupyter_notebook_config.py
c.NotebookApp.ip=’*’
c.NotebookApp.password = u’sha:ce…刚才复制的那个密文’
c.NotebookApp.open_browser = False
c.NotebookApp.port =8888 #可自行指定一个端口, 访问时使用该端口