mongodb redis与SQL的区别和联系

1、MongoDB

MongoDB存储数据类型为BSON(Binary JSON ).

MongoDB 是一个基于分布式文件存储的数据库。它将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

数据格式示例:

  • 什么是BSON?

  1. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。

  2. mongoDB对JSON串做了一些增加,使其可以支持更多的数据类型,并且将其作为存储结构。

  3. BSON可以做为网络数据交换的一种存储形式,是一种schema-less的存储形式,它的优点是轻量性、高灵活性、可遍历性、高效性,但它的缺点是空间利用率不是很理想

2、和SQL的区别:

SQL术语/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins 表连接,MongoDB不支持
primary keyprimary key主键,MongoDB自动将_id字段设置为主键

 

有说MongoDB慢

  反对:不设其他唯一索引的情况下,只用_id 在普通办公电脑上每秒插入几万,在普通x86服务器上每秒插入十几万,你好意思说这个性能低?比mysql强出一个数量级。

      赞同:检索是真的慢,和sql数据库不同,越复杂的条件搜索MangoDB越吃亏,CPU和IO的双重压力。面对那些直接把SQL查询改写成MangoDB的用法,别转了,你不会收获任何性能提升。

      你不行:说你不行还是真的不行,MongoDB领导了NoSQL运动,NoSQL请注意,我们最主要反对的就是SQL的方法论,按SQL方法使用MangoDB你只能收获失望。再想想MongoDB的设计思想:文档化。_id 就是文件名,MongoDB是个文件系统。全文检索?别闹了,用文件名找文件,一个文件名对应一个文件,你绝对不会失望。

那么MongoDB究竟应该怎么用呢?

有一个简单的事实如下:只有一个默认的_id 索引,此时插入性能为1,你再加一个索引,插入性能约1/2,再加一个约1/3 ,以此类推......

如果这个事实对你是很震撼的,那说明你还没有忘记SQL,接着忘。

MongoDB的索引对插入性能有着不可忽略的拖后腿效应,所以,我们应该使用且仅使用 _id 作为插入key,作为查询key,作为所有的那个key。

直接忘记搜索这件事

把MongoDB当做你的硬盘,给他文件名去操作文件.这就是Key-Value数据库的做法,你稍加设计就能这么用。

那么其实你所有的操作可以简化为两个指令,逻辑上 就是一个字典

你给他_id,往字典里插一个数据,或者拿一个数据。

Save({_id:xxx,.....})

FindOne({_id:xxx})

要想高性能,善用那个_id,把你原来准备当主键的那个玩意,hash成_id.

把你原来准备的查询条件,什么?查询,拿_id来,别的全砍掉。

这不是数据表

记住,这不是数据表,一个_id对应的东西不是一行数据,而是一个文件。

文件存储和表存储有什么不同呢?

我举个例子,比如我们要存储用户列表和每个用户的道具列表。

数据表的做法是建一张用户表,一张道具表,道具表里有个字段表示他属于哪个用户。

然后,你就离不开万恶的查询了。

然后如果一个用户有100条道具,100万用户意味着道具表有一亿条记录。

这时候就开始考验你的小数据库了,但这都是过去式了,这一亿的道具,用MongoDB,根本不是个事儿

因为MongoDB的方法是当做文件存,只设计一个用户集合,每个用户的信息是一个文件,然后这100个道具就分开存在每个用户的文件里。

然后来比较一下,我们取得用户的记录,然后从中拿出100个道具,NoSQL方法。

查一亿的表,找出属于某个用户的记录。

熟快熟慢?

然后你可能回想,SQL方法,我也可以搞个道具字段,把用户的100个道具用某种协议打包,然后操作啊,一样可以取得巨大的优化呀。

没错,你的想法很好,你正在用NOSQL的方式用SQL。

文件存储的精华之处

如果问题止于此处,MongoDB就毫无优势可言了,如果这个方法在SQL数据库上也是如此容易使用,那还费劲搞MongoDB干什么?

我们再折腾一点,如果每个道具还要存100条转手记录,你还是可以打包,但你这个打包字段已经1M了。

于是每次存取这个打包字段都是一个系统工程了,还要负担1M的流量。

MongoDB这边呢?我们可以直接对文件的一部分进行读写,比如我只返回一个用户的第二个道具的信息,和返回第二个道具的第1~30条转手记录。

这,是一种怎样的差距啊。

你想要一张美女的照片,你朋友有,但是他只有一个压缩包,他那里没有解包工具,于是他把整个包传给了你。他想问你要一张照片,但是他没有压缩工具,为了存档需要,他让你再压进包里传给他。

这个朋友就是你的用户表的一行,如果换成真实世界的事件是多么的不可思议,这就是在一个字段里打包数据的问题。

MongoDB的一条记录就是一个脑筋更正常的朋友,你要他一张照片,他从包里找出来给你。你给他一张照片,他分门别类的放置到他的包里去。

用文件的思维去访问,MongoDB是一个更好的朋友。

审视一下你项目中的大部分的数据需求,是不是都可以用这种方式去组织呢?

如果是,加入NOSQL吧,我们的口号是:很暴力不SQL

还有什么好处 

1.不用逻辑关心的水平切分

  无需多言,对MongoDB而言,这是运维人员的工作了

2.不用对齐的数据结构

  不用对齐意味着你不用为以前表结构变化的迁移烦恼,有些文件里有一个部分,有些没有,这对MongoDB而言,很正常。

 

 

2、redis

redis 是支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,mysql 是关系型数据库。

mysql:数据放在磁盘

redis:数据放在内存 redis适合放一些频繁使用,比较热的数据,因为是放在内存中,读写速度都非常快,一般会应用在下面一些场景:排行榜、计数器、消息队列推送

 

Redis 是什么?

    通常而言目前的数据库分类有几种,包括 SQL/NSQL,,关系数据库,键值数据库等等,Redis本质上也是一种键值数据库的,但它在保持键值数据库简单快捷特点的同时,又吸收了部分关系数据库的优点。从而使它的位置处于关系数据库和键值数据库之间。Redis不仅能保存Strings类型的数据,还能保存Lists类型(有序)和Sets类型(无序)的数据,而且还能完成排序(SORT) 等高级功能,在实现INCR,SETNX等功能的时候,保证了其操作的原子性,除此以外,还支持主从复制等功能。

  更为详细的描述请参考如下:

        http://code.google.com/p/redis/wiki/index

2 Redis用来做什么?

        通常局限点来说,Redis也以消息队列的形式存在,作为内嵌的List存在,满足实时的高并发需求。而通常在一个电商类型的数据处理过程之中,有关商品,热销,推荐排序的队列,通常存放在Redis之中,期间也包扩Storm对于Redis列表的读取和更新。


3 Redis的优点

性能极高 – Redis能支持超过 100K+ 每秒的读写频率。

丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

4 Redis的缺点

是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

    总结: Redis受限于特定的场景,专注于特定的领域之下,速度相当之快,目前还未找到能替代使用产品。

在使用缓存的时候,redis比memcached具有更多的优势,并且支持更多的数据类型。
Redis不是什么?同样从两个方面来做下对比: 
1. 不是sql server、mySQL等关系型数据库,主要原因是: 
     . redis目前还只能作为小数据量存储(全部数据能够加载在内存中) ,海量数据存储方面并不是redis所擅长的领域 
     . 设计、实现方法很不一样.关系型数据库通过表来存储数据,通过SQL来查询数据。而Redis通上述五种数据结构来存储数据,通过命令 来查询数据 
2.   不是Memcached等缓存系统,主要原因有以下几个: 
     .网络IO模型方面:Memcached是多线程,分为监听线程、worker线程,引入锁,带来了性能损耗。Redis使用单线程的IO复用模型,将速度优势发挥到最大,也提供了较简单的计算功能 
     .内存管理方面:Memcached使用预分配的内存池的方式,带来一定程度的空间浪费 并且在内存仍然有很大空间时,新的数据也可能会被剔除,而Redis使用现场申请内存的方式来存储数据,不会剔除任何非临时数据 Redis更适合作为存储而不是cache 
     .数据的一致性方面:Memcached提供了cas命令来保证.而Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断 
     . 存储方式方面:Memcached只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能

   一句话小结一下:Redis是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。

 

Redis有什么用?只有了解了它有哪些特性,我们在用的时候才能扬长避短,为我们所用: 
1. 速度快:使用标准C写,所有数据都在内存中完成,读写速度分别达到10万/20万 
2. 持久化:对数据的更新采用Copy-on-write技术,可以异步地保存到磁盘上,主要有两种策略,一是根据时间,更新次数的快照(save 300 10 )二是基于语句追加方式(Append-only file,aof) 
3. 自动操作:对不同数据类型的操作都是自动的,很安全 
4. 快速的主--从复制,官方提供了一个数据,Slave在21秒即完成了对Amazon网站10G key set的复制。 
5. Sharding技术: 很容易将数据分布到多个Redis实例中,数据库的扩展是个永恒的话题,在关系型数据库中,主要是以添加硬件、以分区为主要技术形式的纵向扩展解决了很多的应用场景,但随着web2.0、移动互联网、云计算等应用的兴起,这种扩展模式已经不太适合了,所以近年来,像采用主从配置、数据库复制形式的,Sharding这种技术把负载分布到多个特理节点上去的横向扩展方式用处越来越多。

 

这里对Redis数据库做下小结: 
1. 提高了DB的可扩展性,只需要将新加的数据放到新加的服务器上就可以了 
2. 提高了DB的可用性,只影响到需要访问的shard服务器上的数据的用户 
3. 提高了DB的可维护性,对系统的升级和配置可以按shard一个个来搞,对服务产生的影响较小 
4. 小的数据库存的查询压力小,查询更快,性能更好

 

最后,把我使用过程中的一些 经验与教训,做个小结: 
1. 要进行Master-slave配置,出现服务故障时可以支持切换。 
2. 在master侧禁用数据持久化,只需在slave上配置数据持久化。 
3. 物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难! 
4. 当Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了,就开始做swap,内存碎片大 
5. 当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间. 
6. redis与DB同步写的问题,先写DB,后写redis,因为写内存基本上没有问题

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值