redis保存数据的几种类型

    1. 什么是NoSql

为了解决高并发、高可扩展、高可用、大数据存储问题而产生的数据库解决方案,就是NoSql数据库。

NoSQL,泛指非关系型的数据库,NoSQL即Not-Only SQL,它可以作为关系型数据库的良好补充。


    1. Nosql数据库分类
  1. 键值(Key-Value)存储数据库

相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB

典型应用:内容缓存,主要用于处理大量数据的高访问负载。

数据模型:一系列键值对

优势:快速查询

劣势:存储的数据缺少结构化

 

  1. 列存储数据库

相关产品:Cassandra, HBase, Riak

典型应用:分布式的文件系统

数据模型:以列簇式存储,将同一列数据存在一起

优势:查找速度快,可扩展性强,更容易进行分布式扩展

劣势:功能相对局限

  1. 文档型数据库

相关产品:CouchDB、MongoDB

典型应用:Web应用(与Key-Value类似,Value是结构化的)

数据模型:一系列键值对

优势:数据结构要求不严格

劣势:查询性能不高,而且缺乏统一的查询语法

  1. 图形(Graph)数据库

相关数据库:Neo4J、InfoGrid、Infinite Graph

典型应用:社交网络

数据模型:图结构

优势:利用图结构相关算法。

劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。


    1. 什么是Redis

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,

目前为止Redis支持的键值数据类型如下:

字符串类型

散列类型

列表类型

集合类型

有序集合类型


    1. redis历史发展

       2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。

       Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。

       VMware公司从2010年开始赞助Redis的开发, Salvatore Sanfilippo和Pieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis。


    1. redis的应用场景

缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用

分布式集群架构中的session分离

聊天室的在线好友列表。

任务队列。(秒杀、抢购、12306等等)

应用排行榜。

网站访问统计。

数据过期处理(可以精确到毫秒)

-------------------------------------------------------------------------------------------

CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统)是Linux发行版之一,它是来自于Red Hat Enterprise Linux依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定性的服务器以CentOS替代商业版的Red Hat Enterprise Linux使用。两者的不同,在于CentOS并不包含封闭源代码软件。

-------------------------------------------------------------------------------------------

  1. Redis安装配置
    1. Redis下载

官网地址:http://redis.io/

下载地址:http://download.redis.io/releases/redis-3.0.7.tar.gz

    1. Redis安装

Redis是C语言开发,建议在linux上运行,本教程使用Centos6.5作为安装环境。

第一步:在VMware中安装CentOS(参考Linux教程中的安装虚拟机)

第二步:在Linux下安装gcc环境

[root@hadoop ~]#yum install gcc-c++

第三步:将下载的Redis源码包上传到Linux服务器中

第四步:解压缩Redis源码包

[root@hadoop ~]# tar -zxvf redis-3.0.7.tar.gz -C /usr/local/src

第五步:编译redis源码

[root@hadoop src]# cd /usr/local/src/redis-3.0.7/

[root@hadoop redis-3.0.7]# make

第六步:安装redis

[root@hadoop redis-3.0.7]# make install PREFIX=/usr/local/redis-3.0.7

-------------------------------------------------------------------------------------------

    1. Redis启动
      1. 前端启动
  • 启动方式:

直接运行bin/redis-server将以前端模式启动。

[root@hadoop redis-3.0.7]# cd /usr/local/redis-3.0.7/bin

[root@hadoop bin]# ./redis-server

 

  • 启动缺点:

ssh命令窗口关闭则redis-server程序结束,不推荐使用此方法

  • 启动图例:

redis保存数据的几种类型_第1张图片

  • 前端启动的关闭:ctrl+c
      1. 后端启动

第一步:将redis源码包/usr/local/src/redis-3.0.7中的redis.conf配置文件复制到/usr/local/redis-3.0.7/bin/下

[root@hadoop bin]# cd /usr/local/src/redis-3.0.7/(redis-4.0.8/src)

[root@hadoop redis-3.0.7]# cp redis.conf /usr/local/redis-3.0.7/bin

 

第二步:修改/usr/local/redis-3.0.7/bin 下的redis.conf,将daemonize由no改为yes

[root@hadoop redis-3.0.7]# cd /usr/local/redis-3.0.7/bin

[root@hadoop bin]# vim redis.conf

redis保存数据的几种类型_第2张图片

第三步:执行命令

[root@hadoop bin]# ./redis-server redis.conf

关闭:

[root@hadoop bin]# ./redis-cli shutdown

  1. Redis客户端
    redis保存数据的几种类型_第3张图片

  • 指定主机和端口

[root@hadoop bin]# ./redis-cli -h 127.0.0.1 -p 6379

-h:redis服务器的ip地址

-p:redis实例的端口号

  • 如果不指定主机和端口也可以

[root@hadoop bin]# ./redis-cli

-------------------------------------------------------------------------------------------

  1. Redis数据类型

Redis中存储数据是通过key-value存储的,对于value的类型有以下几种:

  • 字符串
  • Hash类型
  • List
  • Set
  • SortedSet(zset)

PS:

在redis中的命令语句中,命令是忽略大小写的,而key是不忽略大小写的。

-------------------------------------------------------------------------------------------

    1. String类型
      1. 命令
        1. 赋值

语法:SET key value

127.0.0.1:6379> set test 123

OK

 

        1. 取值

语法:GET key

127.0.0.1:6379> get test

"123“

 

        1. 设置/获取多个键值

语法:

MSET key value [key value …]

MGET key [key …]

 

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3

OK

127.0.0.1:6379> get k1

"v1"

127.0.0.1:6379> mget k1 k3

1) "v1"

2) "v3"

 

        1. 取值并赋值

语法:GETSET key value

127.0.0.1:6379> getset s2 222

"111"

127.0.0.1:6379> get s2

"222"

 

 

        1. 删除

语法:DEL key

127.0.0.1:6379>del test

(integer) 1

 

        1. 数值增减
  1. 递增数字

当存储的字符串是整数时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。

 

语法:INCR key

127.0.0.1:6379> incr num

(integer) 1

127.0.0.1:6379> incr num

(integer) 2

127.0.0.1:6379> incr num

(integer) 3

 

  1. 增加指定的整数

语法:INCRBY key increment

127.0.0.1:6379> incrby num 2

(integer) 5

127.0.0.1:6379> incrby num 2

(integer) 7

127.0.0.1:6379> incrby num 2

(integer) 9

 

  1. 递减数值

语法:DECR key

127.0.0.1:6379>decr num

(integer) 9

127.0.0.1:6379>decr num

(integer) 8

 

  1. 减少指定的整数

语法:DECRBY key decrement

127.0.0.1:6379> decr num

(integer) 6

127.0.0.1:6379> decr num

(integer) 5

127.0.0.1:6379> decrby num 3

(integer) 2

127.0.0.1:6379> decrby num 3

(integer) -1

        1. 向尾部追加值

APPEND的作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于SET key value。返回值是追加后字符串的总长度。

语法:APPEND key value

127.0.0.1:6379> set str hello

OK

127.0.0.1:6379> append str " world!"

(integer) 12

127.0.0.1:6379> get str

"hello world!"

 

        1. 获取字符串长度

STRLEN命令返回键值的长度,如果键不存在则返回0。

语法:STRLEN key

127.0.0.1:6379> strlen str

(integer) 0

127.0.0.1:6379> set str hello

OK

127.0.0.1:6379> strlen str

(integer) 5

 

 

      1. 应用
        1. 自增主键

商品编号、订单号采用string的递增数字特性生成。201703240000001

 

定义商品编号key:productId

192.168.101.3:7003> set productId 201703240000001

items:id

192.168.101.3:7003> INCR productId items:id

(integer) 2017032400000022

-------------------------------------------------------------------------------------------

  1. Hash类型
    1. 使用string的问题

       假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下:

{

   Id : 1,

Username: zhangsan

}

set user { Id : 1,username: zhangsan}

保存、更新:

User对象à json(string) à redis

如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢?如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。

  1. redis hash介绍

       hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:

redis保存数据的几种类型_第4张图片

 

  1. 命令
    1. 赋值

HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。

 

  • 一次只能设置一个字段值

语法:HSET key field value    

127.0.0.1:6379> hset user username zhangsan

(integer) 1

 

  • 一次可以设置多个字段值

语法:HMSET key field value [field value ...]            

127.0.0.1:6379> hmset user age 20 username lisi

OK

 

  • 当字段不存在时赋值,类似HSET,区别在于如果字段存在,该命令不执行任何操作

语法:HSETNX key field value

127.0.0.1:6379> hsetnx user age 30    如果user中没有age字段则设置age值为30,否则不做任何操作

(integer) 0

 

  • 取值
  • 一次只能获取一个字段值

语法:HGET key field             

127.0.0.1:6379> hget user username

"zhangsan“

 

  • 一次可以获取多个字段值

语法:HMGET key field [field ...]                        

127.0.0.1:6379> hmget user age username

1) "20"

2) "lisi"

 

  • 获取所有字段值

语法:HGETALL key

127.0.0.1:6379> hgetall user

1) "age"

2) "20"

3) "username"

4) "lisi"

 

 

        1. 删除字段

可以删除一个或多个字段,返回值是被删除的字段个数

 

语法:HDEL key field [field ...]

127.0.0.1:6379> hdel user age

(integer) 1

127.0.0.1:6379> hdel user age name

(integer) 0

127.0.0.1:6379> hdel user age username

(integer) 1

 

  1. 增加数字

语法:HINCRBY key field increment

127.0.0.1:6379> hincrby user age 2     将用户的年龄加2

(integer) 22

127.0.0.1:6379> hget user age             获取用户的年龄

"22“

 

  1. 判断字段是否存在

语法:HEXISTS key field

127.0.0.1:6379> hexists user age         查看user中是否有age字段

(integer) 1

127.0.0.1:6379> hexists user name      查看user中是否有name字段

(integer) 0

 

  1. 只获取字段名或字段值

语法:

HKEYS key

HVALS key

127.0.0.1:6379> hmset user age 20 name lisi

OK

127.0.0.1:6379> hkeys user

1) "age"

2) "name"

127.0.0.1:6379> hvals user

1) "20"

2) "lisi"

  1. 获取属性数量

语法:HLEN key

127.0.0.1:6379> hlen user

(integer) 2

 

 

    1. 应用
      1. 存储商品信息
  • 商品字段

【商品id、商品名称、商品描述、商品库存、商品好评】

 

定义商品信息的key

商品1001的信息在Redis中的key为:[items:1001]

 

  • 存储商品信息

192.168.101.3:7003> HMSET items:1001 id 3 name apple price 999.9

OK

 

  • 获取商品信息

192.168.101.3:7003> HGET items:1001 id

"3"

192.168.101.3:7003> HGETALL items:1001

1) "id"

2) "3"

3) "name"

4) "apple"

5) "price"

6) "999.9"

-------------------------------------------------------------------------------------------

    1. List类型
      1. ArrayList与LinkedList的区别

       ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢

       LinkedList使用双向链表方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快。然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快

redis保存数据的几种类型_第5张图片

redis保存数据的几种类型_第6张图片

 

 

 

      1. redis list介绍

       列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段

       列表类型内部是使用双向链表(double linked list)实现的,所以获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。

      1. 命令
        1. 向列表两端增加元素
  • 向列表左边增加元素

语法:LPUSH key value [value ...]

127.0.0.1:6379> lpush list  1 2 3

(integer) 3

 

  • 向列表右边增加元素

语法:RPUSH key value [value ...]

127.0.0.1:6379> rpush  list  a b c

(integer) 3

 

        1. 查看列表

LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。

 

语法:LRANGE key start stop

127.0.0.1:6379> lrange list 0 5

1) "c"

2) "b"

3) "a"

4) "1"

5) "2"

6) "3"

 

        1. 从列表两端弹出元素

LPOP命令从列表左边弹出一个元素,会分两步完成:

第一步是将列表左边的元素从列表中移除

第二步是返回被移除的元素值。

语法:

LPOP key

RPOP key

127.0.0.1:6379> lpop list

"c“

127.0.0.1:6379> rpop list

"3“

 

        1. 获取列表中元素的个数

语法:LLEN key

127.0.0.1:6379> llen list

(integer) 4

 

        1. 获得/设置指定索引的元素值
  • 获得指定索引的元素值

语法:LINDEX key index

127.0.0.1:6379> lindex list  2

"1"

 

  • 设置指定索引的元素值

语法:LSET key index value

127.0.0.1:6379> lset list 2 2

OK

127.0.0.1:6379> lrange list 0 -1 //查询所有

1) "6"

2) "5"

3) "2"

4) "2"

 

        1. 向列表中插入元素

该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。

 

语法:LINSERT key BEFORE|AFTER pivot value

127.0.0.1:6379> lrange list 0 -1

1) "3"

2) "2"

3) "1"

127.0.0.1:6379> linsert list after 3 4

(integer) 4

127.0.0.1:6379> lrange list 0 -1

1) "3"

2) "4"

3) "2"

4) "1"

 

        1. 将元素从一个列表转移到另一个列表中

语法:RPOPLPUSH source destination

127.0.0.1:6379> rpoplpush list newlist

"1"

127.0.0.1:6379> lrange newlist 0 -1

1) "1"

127.0.0.1:6379> lrange list 0 -1

1) "3"

2) "4"

3) "2"

 

      1. 应用
        1. 商品评论列表

思路:

在Redis中创建商品评论列表

用户发布商品评论,将评论信息转成json存储到list中。

用户在页面查询评论列表,从redis中取出json数据展示到页面。

 

定义商品评论列表key:

商品编号为1001的商品评论key【items:comment:1001】

192.168.101.3:7001> LPUSH items:comment:1001 '{"id":1,"name":"商品不错,很好!!","date":1430295077289}'

-------------------------------------------------------------------------------------------

    1. Set类型
      1. redis set介绍

集合中的数据是不重复且没有顺序

       集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在

Redis还提供了多个集合之间的交集、并集、差集的运算。

      1. 命令
        1. 增加/删除元素

语法:SADD key member [member ...]/增加

127.0.0.1:6379> sadd key1 a b c

(integer) 3

127.0.0.1:6379> sadd key1 a

(integer) 0

 

语法:SREM key member [member ...]/删除

127.0.0.1:6379> srem set c d

(integer) 1

 

        1. 获得集合中的所有元素

语法:SMEMBERS key

127.0.0.1:6379> smembers key1

1) "b"

2) "a”

 

        1. 判断元素是否在集合中

语法:SISMEMBER key member

127.0.0.1:6379> sismember set a

(integer) 1

127.0.0.1:6379> sismember set h

(integer) 0

 

      1. 运算命令

 

        1. 集合的差集运算A-B

属于A并且不属于B的元素构成的集合。redis保存数据的几种类型_第7张图片

语法:SDIFF key [key ...]

127.0.0.1:6379> sadd setA 1 2 3

(integer) 3

127.0.0.1:6379> sadd setB 2 3 4

(integer) 3

127.0.0.1:6379> sdiff setA setB

1) "1"

127.0.0.1:6379> sdiff setB setA

1) "4"

 

        1. 集合的交集运算A ∩ B

属于A且属于B的元素构成的集合。redis保存数据的几种类型_第8张图片

语法:SINTER key [key ...]

127.0.0.1:6379> sinter setA setB

1) "2"

2) "3"

 

        1. 集合的并集运算A ∪B

属于A或者属于B的元素构成的集合redis保存数据的几种类型_第9张图片

 

语法:SUNION key [key ...]

127.0.0.1:6379> sunion setA setB

1) "1"

2) "2"

3) "3"

4) "4"

 

      1. 其它命令
        1. 获得集合中元素的个数

语法:SCARD key

127.0.0.1:6379> smembers setA

1) "1"

2) "2"

3) "3"

127.0.0.1:6379> scard setA

(integer) 3

 

  1. 从集合中弹出一个元素

注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出

语法:SPOP key

127.0.0.1:6379> spop setA

"1“

-------------------------------------------------------------------------------------------

    1. SortedSet类型zset
      1. redis sorted set介绍

       在集合类型的基础上,有序集合类型为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。

 

在某些方面有序集合和列表类型有些相似。

1、二者都是有序的。

2、二者都可以获得某一范围的元素。

但是,二者有着很大区别:

1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。

2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快

3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)

4、有序集合要比列表类型更耗内存。

 

      1. 命令
        1. 增加元素

       向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。

 

语法:ZADD key score member [score member ...]

127.0.0.1:6379> zadd scoreboard 80 zhangsan 89 lisi 94 wangwu

(integer) 3

127.0.0.1:6379> zadd scoreboard 97 lisi

(integer) 0

 

        1. 获取元素的分数

语法:ZSCORE key member

127.0.0.1:6379> zscore scoreboard lisi

"97"

 

        1. 删除元素

移除有序集key中的一个或多个成员,不存在的成员将被忽略。

当key存在但不是有序集类型时,返回一个错误。

 

语法:ZREM key member [member ...]

127.0.0.1:6379> zrem scoreboard lisi

(integer) 1

 

 

        1. 获得排名在某个范围的元素列表

获得排名在某个范围的元素列表

  • 按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

 

语法:ZRANGE key start stop [WITHSCORES]                

127.0.0.1:6379> zrange scoreboard 0 2

1) "zhangsan"

2) "wangwu"

3) "lisi“

 

  • 按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

 

语法:ZREVRANGE key start stop [WITHSCORES]         

127.0.0.1:6379> zrevrange scoreboard 0 2

1) " lisi "

2) "wangwu"

3) “zhangsan”

 

如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数

127.0.0.1:6379> zrange scoreboard 0 1 WITHSCORES

1) "zhangsan"

2) "80"

3) "wangwu"

4) "94"

 

        1. 获得指定分数范围的元素

语法:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

127.0.0.1:6379> ZRANGEBYSCORE scoreboard 90 97 WITHSCORES

1) "wangwu"

2) "94"

3) "lisi"

4) "97"

127.0.0.1:6379> ZRANGEBYSCORE scoreboard 70 100 limit 1 2

1) "wangwu"

2) "lisi"

 

        1. 增加某个元素的分数

返回值是更改后的分数

 

语法:ZINCRBY  key increment【要增加的分数】 member

127.0.0.1:6379> ZINCRBY scoreboard 4 lisi

"101“

 

 

        1. 获得集合中元素的数量

语法:ZCARD key

127.0.0.1:6379> ZCARD scoreboard

(integer) 3

 

        1. 获得指定分数范围内的元素个数

语法:ZCOUNT key min max

127.0.0.1:6379> ZCOUNT scoreboard 80 90

(integer) 1

 

        1. 按照排名范围删除元素

语法:ZREMRANGEBYRANK key start stop

127.0.0.1:6379> ZREMRANGEBYRANK scoreboard 0 1

(integer) 2

127.0.0.1:6379> ZRANGE scoreboard 0 -1

1) "lisi"

        1. 按照分数范围删除元素

语法:ZREMRANGEBYSCORE key min max

127.0.0.1:6379> zadd scoreboard 84 zhangsan     

(integer) 1

127.0.0.1:6379> ZREMRANGEBYSCORE scoreboard 80 100

(integer) 1

 

        1. 获取元素的排名
  • 从小到大

语法:ZRANK key member

127.0.0.1:6379> ZRANK scoreboard lisi

(integer) 0

 

  • 从大到小

语法:ZREVRANK key member

127.0.0.1:6379> ZREVRANK scoreboard zhangsan

(integer) 1

 

      1. 应用
        1. 商品销售排行榜

需求:根据商品销售量对商品进行排行显示

思路:定义商品销售排行榜(sorted set集合),Key为items:sellsort,分数为商品销售量。

 

写入商品销售量

  • 商品编号1001的销量是9,商品编号1002的销量是10

192.168.101.3:7007> ZADD items:sellsort 9 1001 10 1002

 

  • 商品编号1001的销量加1

192.168.101.3:7001> ZINCRBY items:sellsort 1 1001

 

  • 商品销量前10名:

192.168.101.3:7001> ZRANGE items:sellsort 0 9 withscores

你可能感兴趣的:(redis保存数据的几种类型)