常见的NoSQL数据库(Memcache,Redis,MongoDB)

NoSql的含义

NoSQL ,(Not Only SQL),泛指非关系型数据库, 它是由一次叫“反Sql运动”的社区讨论而诞生的体系。这个运动的发起最早源自于社区网站 LiveJournal的开发团队,它们的初衷是为了用于减少数据库连接数,减轻数据库的工作压力,但发展至今有着其他不同的应用领域,因此NoSQL处于一种所谓百家争鸣的,各执一词的时期。但我们作为NoSql的学习者和应用者,我们不需要关心和纠结这些NoSql的争论,也不需要参与到这些争论当中。

只要不是关系型数据库里面的东西,都可以叫做nosql数据库。

NoSql的共同特点和优势

  • NoSQL 通常是以key-value形式存储的(如:Memcache、Redis、Mongodb)
  • 不支持SQL语句
  • 没有表结构
  • 配置简单
  • 灵活、高效的操作与数据模型(key-value存储,一般叫做hash表)
  • 低廉的学习成本
  • 能很好地作为MySql的中间层(cache is king 有缓存肯定会更好、缓存也会引来问题?数据 一致性的问题)
  • 能很好地支持PHP

NoSql的共同的缺点

  • 没有统一的标准
  • 安全性极差(memcache没有权限系统 )
  • 没有正式的官方支持 (社区维护)(GitHub)
  • 各种产品还不算成熟
  • 权威支持的产品价格很高(如:阿里云)

NoSql的产品分类


Memcache

  • 端口:11211

  • 纯内存存储,是所有NoSQL产品中最简单,速度最快的,但也是功能最弱的

  • 内置分布式算法,开发者不需要自己去实现

    • 使用分布式存储数据
    $mem = new Memcache();
    
    $mem->addServer('127.0.0.1', 11212);
    $mem->addServer('127.0.0.1', 11213);
    $mem->addServer('127.0.0.1', 11214);
    
    # 数据自动分布在3台memcache服务器上,不用开发人员操心
    for($i = 1; $i < 99; $i++){
        $mem->set('key_' . $i, 'value_' . $i, 0, 86400);
    }
    
    echo "ok";
    
    • 获取分布式数据
    $mem = new Memcache();
      
    $mem->addServer('127.0.0.1', 11212);
    $mem->addServer('127.0.0.1', 11213);
    $mem->addServer('127.0.0.1', 11214);
    
    # 开发人员无法得知数据的来源
    $data = $mem->get('key_1');
    var_dump($data);
    
  • 可以设置数据有效期

    Memcache设置缓存的有效期可以使用:

    1. 缓存时间:使用s秒数,但是不能超过86400*30s,也就是30天的秒数
    2. 时间戳:但是该方式只有在Linux下才可以使用,windows下不生效,使用时间戳可以设置大于30天的有效期
  • 使用Telnet协议进行传输,没有加密功能,安全性很差,但在内网上影响不大

  • 最大存储空间只有64M,一旦爆满,Memcache会指定重启,并释放当前所有的内存

  • 存储形式为KV型,单个Value值最大为1M(单个chunk最大为1M)

  • 数据存储在内存中,一旦服务器维护或重启,数据就会丢失

  • 数据零散,无法遍历,管理数据完整性非常一般

  • 存储的数据都是字符串类型

  • 可以配置Session共享(在php.ini中配置session.save_handler = memcache,session.save_path = "tcp://#memcache服务器的IP#:11211")

    ; php.ini
    session.save_handler = memcache
    session.save_path = "tcp://127.0.0.1:11211"
    
  • Memcache的内存分配机制

    ​ 由于Memcache是一个内存缓存系统,就涉及内存申请和释放的问题,不断的申请和释放内存,会导致内存的碎片化。为了解决内存碎片化的问题,Memcache使用了内存预先分配机制

    ​ Memcache将64M的存储空间分割成64份,每一份都是1M的空间,这样的空间称为slab class

    ​ slab class里面的存储数据的单元称为chunk,最小的chunk默认为96B,最大为1M。

    ​ 相邻slab class之间chunk大小的比值是固定的,这个比值被称为增长因子,它可以根据实际的业务做相应的调整。

  • Memcache内部使用了LRU算法

    ​ LRU(Least Recently Used )算法被称为最近最少使用原则

    ​ 当memcache的一个slab里面的chunk不够使用的情况下(存储满了,数据在有效期)当有新的满足chunk的数据过来的情况下,memcache会优先把slab里面最近一段时间内,最不活跃的数据先剔除掉,腾出空间,给新的数据使用。

  • Memcache使用惰性删除机制

    ​ Memcache本身不监控数据是否过期,当下一次重新获取数据的时候,才会去查看数据是否有效,如果有效则返回,否则就清除。

  • Memcache实现高可用

    • sina公司开发的MemcacheDB
    • repcached:全称replication cached,是由日本人发明的memcache的高可用技术,简称复制缓冲区技术。

Redis

  • 端口:6379

  • 默认存在0~15共16个数据库

  • 支持缓存数据持久化

  • 支持5种数据类型

    • String(字符串)
    • list(链表)
    • hash(哈希表)
    • set(无序集合)
    • sorted set(有序集合,缩写为zset)
  • 高并发而生

  • Redis使用一致性哈希虚拟节点算法可以实现分布式功能

  • 存储形式为KV型,单个Value值最大可以存储1G的数据,存储总量可以视硬盘大小而定

  • Redis可以开启安全认证

    # redis.conf
    # 由于配置文件中的密码是明文,所以一般会把该配置文件的权限设置为600
    requirepass ##密码##(明文)
    
  • Redis的持久化

    • 快照模式

      默认模式,快照文件为dump.rdb。

      当网站的数据量变大时,该文件也会随之增大,操作效率很低。

    • aof模式(append of file)

      aof文件有点类似MySQL的binlog日志(读写分离)

      aof文件会把用户的操作记录包括查询的过程全部记录,当服务器出现问题的时候,Redis会将数据从内存中保存到aof文件当中,当服务器重新运行时,Redis就会根据aof文件中的操作记录,把数据重新还原到内存当中去,以确保数据的完整性。

      快照模式和aof模式是完全互斥的。

      如果aof的模式一旦启动,那么快照就会失效,Redis就会把所有的数据缓存到内存当中,如果发生重启,停止,关闭服务器等行为,那么aof文件就会把内存中数据同步到硬盘中。

      开启aof模式:

      # redis.conf
      
      appendonly yes
      
      appendfilename "appendonly.aof"
      
      # appendfsync always
      # always 的选项代表Redis的命令每一次只要运行那么就会马上写入aof文件当中,该选项是最没有效率的,然而它却是最具备操作记录完整性的。
      
      appendfsync everysec
      # everysec 的选项是Redis比较折中的选项,代表每一秒中只有有操作那么就会进行操作记录,但是如果在某一秒当中redis发生故障,那么这一秒的数据操作记录将有可能发生丢失的情况,存在一定的风险,然而这个配置的性能比较适中,所以建议使用
      
      # appendfsync no
      # no 该配置的效率完全依赖您当前所在使用的操作系统和计算机的性能,如果操作系统稳定,计算机的性能强大,那么这一项是最有效率的,反而就是最差,所以一般最好不要设置该项
      

MongoDB

  • 端口:27017

  • 文档型数据库

  • 存储的是经过特殊处理的json数据,也叫Bson(json二进制化后的数据)

  • MongoDB内部使用js解释引擎来实现数据的分析,在插入的时候,将数据转换成二进制的Bson来存储;在查询的时候,将数据Bson转换成json对象返回

  • 存在数据库的概念

    # 查看当前所有数据库
    > show dbs;
    
    # 选择数据库
    > use test;
    
    # 查看当前库下所有的数据表
    > show tables;
    > show conllections;
    
    # 创建数据库
    # MongoDB的数据库是隐式创建,当该数据库下有数据之后,它就会被自动创建了
    
    # 删除当前数据库
    > db.dropDatabase();
    
  • Collection(集合) → 相当于MySQL中的表

    # 创建表
    # 显式创建
    > db.createConllection('collectionName');
    # 隐式创建
    > db.collectionName.insert(/*json数据*/);
    
    # 删除表
    > db.collectionName.drop();
    
    ####### 查找
    # 查找所有
    > db.collectionName.find();
    
    # 将取出的数据以优雅的格式显式,链式调用
    > db.collectionName.find().pretty();
    
    # 按条件查找和展示
    > db.collectionName.find({/*查询条件*/}, {/*要展示的字段*/});
    # 例如:select age, name from stu where age > 18;
    > db.stu.find({'age':{$gt:18}}, {'_id':0, 'age':1, 'name':1});
    
    # 只查询一条
    # 例如:select age, name from stu where age > 18 limit 1;
    > db.stu.findOne({'age':{$gt:18}}, {'_id':0, 'age':1, 'name':1});
    
  • Document(文档) → 相当于MySQL表中的记录

    ####### 增加
    > db.collectionName.insert(/*json数据*/);
    # 增加单条记录
    > db.collectionName.insert({'name':'rico', 'age':19, 'gender':male});
    # 增加多条记录
    > db.collectionName.insert([
        {'name':'rico', 'age':19, 'gender':male},
        {'name':'nacy', 'age':22, 'gender':female, 'birthday':'1993/01/05'},
        {'name':'zaks', 'age':30, 'gender':male, 'className':'php88'}
    ]);
    
    ####### 删除
    > db.collectionName.remove(/*查询表达式*/, /*选项*/);
    # 例如:delete from stu where age < 10;
    > db.stu.remove({'name':{$gt:10}});
    # 例如:delete from stu where age < 10 limit 1;
    > db.stu.remove({'name':{$gt:10}}, {justOne:true});
    
    ####### 修改
    > db.collectionName.update(/*查询表达式*/, /*新值*/);
    # 例如:update stu set name='coco' where _id=3;
    > db.stu.update({'_id':3}, {'name':'coco'}); # 注意:这里修改之后,文档中只有'_id'和'name'了
    # 如果只是想修改某列,则可以使用$set
    > db.stu.update({'_id':3}, {$set:{'name':'coco'}}); 
    
    ####### 分页
    # 例如:select * from stu limit 5, 3;
    > db.stu.find().limit(3).skip(5);
    
    ####### 排序
    # 例如:select * from stu order by age;
    > db.stu.find().sort({'age':1});
    # 例如:select * from stu order by age desc;
    > db.stu.find().sort({'age':-1});
    
  • 怎么关闭 mongoDB?千万不要 kill -9 pid,可以 kill -2 pid 或 db.shutdownServer()

  • mongodb的权限验证机制

    http://blog.csdn.net/lk10207160511/article/details/50281883


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,936评论 2 27
  • 转载地址:http://gnucto.blog.51cto.com/3391516/998509 Redis与Me...
    Ddaidai阅读 21,437评论 0 82
  • 文章已经放到github上 ,如果对您有帮助 请给个star[https://github.com/qqxuanl...
    尼尔君阅读 2,279评论 0 22
  • 一、在任务管理器中查看进程占用比较高的".exe"结尾的文件 二、使用杀毒件扫描 三、问相关技术人员有关线索,比如...
    骑公路的晨阅读 502评论 0 0
  • 烦闷劳累多日,决定出去透透气。因时间有限又毫无规划,便决定去楠溪江。驱车前往,不料迷了路,经友人推荐,撞入林坑古村...
    离影疏落阅读 325评论 0 2