Redis不同数据类型命令使用及应用场景

目录

1.1 Redis数据类型

1.2 string类型

1.3 list类型

1.3.1  ArrayList与LinkedList的区别

1.4 hash类型

 hash应用

1.5 set类型

1.6 sortedset类型

sortedset应用

1.7 redis对于key的应用

1.8 服务器命令


1.1 Redis数据类型

Redis数据类型:Redis使用key/value格式存储数据,其中key的类型永远是string,而value的类型非常丰富;

常用的数据类型:

 string:存储字符串(最基础的数据类型,二进制的文件(图片、视频)512M)

 list:是一个集合,可以在头部或者尾部操作数据

 hash(Map):采用键值对存储

 set:无序不可重复的集合

 SortedSet:使用score来排序的集合

 HyperLogLog结构(redis2.8.9版本之后才有,用来做基数统计的算法。)

 

1.2 string类型

最为基础的数据存储类型。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。

redis中没有使用C语言的字符串表示,而是自定义一个数据结构叫SDS(simple dynamic string)即简单动态字符串。

打开下载的redis源码包,找到src下的sds.h文件查看sds源码:

struct sdshdr {

//字符串长度

unsignedint len;

//buf数组中未使用的字节数量

unsignedint free;

//用于保存字符串

char buf[];

};

c语言对字符串的存储是使用字符数组,遇到'\0'字符则认为字符串结束,

redis的字符串可以存储任何类型的数据,因为任何类型数据都可以表示成二进制,sds结构中的char buf[]就是存储了二进制数据。

redis的字符串是二进制安全的,什么是二进制安全?简单理解就是存入什么数据取出的还是什么数据。

redis中的sds不像c语言处理字符串那样遇到'\0'字符则认证字符串结束,

它不会对存储进去的二进制数据进行处理,存入什么数据取出还是什么数据。

 

命令

描述

例子

Set

赋值

SET key value

Get

获取值

GET key

APPEND

追加字符串

APPEND key value

DECR

减少值

DECR key

INCR

增加值

INCR key

DECRBY

设置减少数值的步长

DECRBY key decrement

INCRBY

设置增加数值的步长

INCRBY key increment

GETSET

先获取值再赋值

GETSET key value

STRLEN

返回key的长度

STRLEN key

SETEX

设置key在服务器中存在的时间

SETEX key seconds value

SETNX

Key不存在设置值,否则不做操作

SETNX key value

SETRANGE

字符串替换

SETRANGE key start "value"

GETRANGE

截取字符串

GETRANGE key start end

SETBIT

设置二进制的值

SETBIT key offset value

GETBIT

获取二进制的值

GETBIT key offset

MGET

返回多个key的值

MGET key [key ...]

MSET

设置多个key、value

MSET key value [key value ...]

MSETNX

Key不存在设置多个key、value值,否则不做操作

MSETNX key value  [key value ...]

String应用:

kv缓存

普通的set和get,做简单的kv缓存

自增主键

自增主键

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

定义商品编号key:items:id

192.168.101.3:7003> INCR items:id

(integer)2

192.168.101.3:7003> INCR items:id

(integer)3

1.3 list类型

List类型是按照插入顺序排序的字符串链表。可以在链表的两头插入或删除元素,List中可以包含的最大元素数量是4294967295。

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

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

ArrayList与LinkedList的区别

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

        Redis不同数据类型命令使用及应用场景

        Redis不同数据类型命令使用及应用场景

        命令

        描述

        例子

        LPUSH

        在list头部添加多个值

        LPUSH key value [value ...]

        LPUSHX

        Key存在则添加值,否则不做操作

        LPUSHX key value

        LRANGE

        遍历list中key数据(从0开始)

        LRANGE key start stop

        LPOP

        从头部弹出key中的值

        LPOP key

        LLEN

        返回key的长度

        LLEN key

        LREM

        删除前面几个值等于某值得元素

        LREM key count value

        LSET

        给下标赋值

        LSET key index value

        LINDEX

        返回下标中的值

        LINDEX key index

        LTRIM

        截取list中的值

        LTRIM key start stop

        LINSERT

        在某个值的前面或者后面插入值

        LINSERT key BEFORE|AFTER pivot value

        RPUSH

        在list尾部添加多个值

        RPUSH key value [value ...]

        RPUSHX

        在list尾部添加单个值

        RPUSHX key value

        RPOP key

        从尾部弹出值

        RPOP key

        RPOPLPUSH

        从一个集合尾部弹出值插入到里一个集合的头部

        RPOPLPUSH source destination

         list应用:

        list存储一些列表型的数据结构

        list存储一些列表型的数据结构,类似粉丝列表了、文章的评论列表了之类的东西

        在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}'

        list实现分页查询

        可以通过lrange命令,就是从某个元素开始读取多少个元素,可以基于list实现分页查询,这个很棒的一个功能,基于redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走

        取最新N个数据的操作:记录前N个最新登陆的用户Id列表,超出的范围可以从数据库中获得。

        //把当前登录人添加到链表里
        ret = r.lpush("login:last_login_times", uid) //保持链表只有N位
        ret = redis.ltrim("login:last_login_times", 0, N-1) //获得前N个最新登陆的用户Id列表
        last_login_list = r.lrange("login:last_login_times", 0, N-1)

        Redis不同数据类型命令使用及应用场景

        简单的消息队列

        可以搞个简单的消息队列,从list头怼进去,从list尾巴那里弄出来

        使用List做异步队列

        一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。

        如果不用sleep,list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。

        如果想要生产一次消费多次,可以使用pub/sub主题订阅者模式,可以实现1:N的消息队列,但在消费者下线后,生产的消息会丢失,想要持久化的话,需要使用消息队列如rabbitmq等。

        1.4 hash类型

        使用string的问题

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

        保存、更新:

        User对象  --->json(string)  ---> redis 

        如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 

        如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。

         

        hash叫散列类型,它提供了字段和字段值的映射。

        字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:

        Hash类型可以看成具有StringKey和StringValue的map容器。非常适合于存储值对象的信息。如Username、Password和Age等。

         

        Redis不同数据类型命令使用及应用场景

        命令

        描述

        例子

        HSET

        给key中filed字段赋值[

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

        ]

        HSET key field value

        HGET

        获取key中filed的值

        HGET key field

        HEXISTS

        判断filed是否存在

        HEXISTS key field

        HLEN

        获取key 的长度

        HLEN key

        HDEL

        删除file字段[

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

        ]

        HDEL key field [field ...]

        HSETNX

        如果filed不存在时赋值否则不做操作

        HSETNX key field value

        HINCRBY

        给filed增加步长

        HINCRBY key field increment

        HGETALL

        获取所有的filed和value

        HGETALL key

        HKEYS

        获取key

        HKEYS key

        HVALS

        获取value

        HVALS key

        HMGET

        获取所有filed字段的值

        HMGET key field [field ...]

        HMSET

        设置多个filed字段value

        HMSET key field value [field value ...]

         hash应用

        缓存结构化的数据

        商品信息
        商品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"

        Redis不同数据类型命令使用及应用场景

        1.5 set类型

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

        由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。

        Set类型看作为没有排序的字符集合,Set集合中不允许出现重复的元素,redis可以在服务器端完成多个Sets之间的计算操作,

        如unions、intersections和differences。

        这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销

        命令

        描述

        例子

        SADD

        添加值

        SADD key member [member ...]

        SMEMBERS

        遍历集合

        SMEMBERS key

        SCARD

        获取key的成员数量

        SCARD key

        SISMEMBER

        判断成员是否存在

        SISMEMBER key member

        Spop

        随机弹出值

        Spop key

        SREM

        删除指定的成员

        SREM key member [member ...]

        SRANDMEMBER

        随机返回成员,不删除原值

        SRANDMEMBER key

        SMOVE

        移动一个集合的成员到另一个集合

        SMOVE source destination member

        SDIFF

        求集合差集

        SDIFF key [key ...] 

        属于A并且不属于B的元素构成的集合

        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"

        SDIFFSTORE

        集合中的差集存储到新集合中

        SDIFFSTORE destination key [key ...]

        SINTER

        求集合交集

        SINTER key [key ...]

        属于A且属于B的元素构成的集合

        SINTER key [key ...]

        127.0.0.1:6379> sinter setA setB 

        1) "2"

        2) "3"

        SINTERSTORE

        将集合交集存储到新集合

        SINTERSTORE destination key [key ...]

        SUNION

        求集合并集

        SUNION key [key ...]

        属于A或者属于B的元素构成的集合(去重)

        SUNION key [key ...]

        127.0.0.1:6379> sunion setA setB

        1) "1"

        2) "2"

        3) "3"

        4) "4"

        SUNIONSTORE

        将集合的并集存储到新集合

        SUNIONSTORE destination key [key ...]

        set应用

        无序集合,自动去重

        直接基于set将系统里需要去重的数据扔进去,自动就给去重了,如果你需要对一些数据进行快速的全局去重,你当然也可以基于jvm内存里的HashSet进行去重,但是如果你的某个系统部署在多台机器上呢?

        得基于redis进行全局的set去重

        可以基于set玩儿交集、并集、差集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友是谁?对吧

        把两个大v的粉丝都放在两个set中,对两个set做交集

        特定时间内的特定项目

        另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源。比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。 每次我获得一次新的页面浏览时我只需要这样做:

        SADD page:day1:<page_id> <user_id>

        当然你可能想用unix时间替换day1,比如time()-(time()%3600*24)等等。 想知道特定用户的数量吗?只需要使用 SCARD page:day1:<page_id>

        需要测试某个特定用户是否访问了这个页面?

        SISMEMBER page:day1:<page_id>

        1.6 sortedset类型

        不允许出现重复的元素,每一个成员都会有一个分数(score)与之关联,用分数来进行排序,分数是可以重复的

        在集合类型的基础上有序集合类型为集合中的每个元素都关联一个分数,

        这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,

        还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。

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

        1、二者都是有序的。

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

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

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

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

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

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

        命令

        描述

        例子

        ZADD

        添加排序成员

        ZADD key score member [score] [member]

        ZCARD

        获取成员数量

        ZCARD key

        ZCOUNT

        获取分数在min和max之间成员有多少个

        ZCOUNT key min max

        ZINCRBY

        增加指定成员的分数

        ZINCRBY key increment member

        【增加某个元素的分数,返回值是更改后的分数】

        ZRANGE

        遍历成员以及分数

        ZRANGE key start stop [WITHSCORES]

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

        ZRANGE key start stop [WITHSCORES]

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

        【ZREVRANGE key start stop [WITHSCORES]照元素分数从大到小的顺序返回索引从startstop之间的所有元素(包含两端的元素)】

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

        ZRANGEBYSCORE

        返回分数在min和max之间的成员和分数

        ZRANGEBYSCORE key min max [WITHSCORES]

        ZRANK 

        返回成员的下标

        ZRANK key member

        ZREM

        删除指定成员

        ZREM key member [member ...]

        ZREVRANGE

        遍历成员以及分数从大到小

        ZREVRANGE key start stop [WITHSCORES]

        ZREVRANK 

        返回成员下标顺序从大到小

        ZREVRANK key member

        ZSCORE

        获取指定成员的分数

        ZSCORE key member

        ZREVRANGEBYSCORE

        获取成员以及分数按照从高到低

        ZREVRANGEBYSCORE key max min [WITHSCORES]

        ZREMRANGEBYRANK

        删除下标之间的数据

        ZREMRANGEBYRANK key start stop

        ZREMRANGEBYSCORE

        删除分数在min和max中的成员

        ZREMRANGEBYSCORE key min max

        sortedset应用

        排序

        排序的set,去重但是可以排序,写进去的时候给一个分数,自动根据分数排序,这个可以玩儿很多的花样,最大的特点是有个分数可以自定义排序规则

        比如说你要是想根据时间对数据排序,那么可以写入进去的时候用某个时间作为分数,人家自动给你按照时间排序了

        商品销售排行榜
        根据商品销售量对商品进行排行显示,定义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不同数据类型命令使用及应用场景

         使用sortedset实现延时队列

        使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。

        Redis各个数据类型应用场景:

        类型 简介 特性 场景
        String(字符串) 二进制安全 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M ---
        Hash(字典) 键值对集合,即编程语言中的Map类型 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) 存储、读取、修改用户属性
        List(列表) 链表(双向链表) 增删快,提供了操作某一段元素的API 1、最新消息排行等功能(比如朋友圈的时间线) 2、消息队列
        Set(集合) 哈希表实现,元素不重复 1、添加、删除、查找的复杂度都是O(1)  2、为集合提供了求交集、并集、差集等操作 1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐
        Sorted Set(有序集合) 将Set中的元素增加一个权重参数score,元素按score有序排列 数据插入集合时,已经进行天然排序 1、排行榜 2、带权重的消息队列

        1.7 redis对于key的应用

        使用对key的操作,通常可以用来维护数据

        命令

        描述

        例子

        KEYS 

        获取所有的key

        KEYS pattern [如:Keys * ]

        Del

        删除指定的key

        DEL key [key ...]

        EXISTS

        判断key是否存在

        EXISTS key

        MOVE

        移动一个key到另一个库中

        MOVE key db

        RENAME

        给key从新命名

        RENAME key newkey

        RENAMENX

        修改key的名字

        RENAMENX key newkey

        PERSIST

        持久化key

        PERSIST key

        EXPIRE

        设置key存活时间

        EXPIRE key seconds

        EXPIREAT

        设置key存活时间(年月日)

        EXPIREAT key timestamp

        TTL 

        实时查看key存活时间

        TTL key

        RANDOMKEY

        随机返回一个key

        RANDOMKEY

        TYPE

        查看key的中value数据类型

        TYPE key

        SELECT

        进入指定库

        SELECT NUM

        1.8 服务器命令

        命令

        描述

        例子

        ping

        测试连接是否存活

        //执行下面命令之前,我们停止redis 服务器

        redis 127.0.0.1:6379> ping

        Could not connect to Redis at 127.0.0.1:6379: Connection refused

        //执行下面命令之前,我们启动redis 服务器

        not connected> ping

        PONG

        redis 127.0.0.1:6379>

        第一个ping 时,说明此连接正常

        第二个ping 之前,我们将redis 服务器停止,那么ping 是失败的

        第三个ping 之前,我们将redis 服务器启动,那么ping 是成功的

         

        echo 

         

        在命令行打印一些内容

         

        在命令行打印一些内容

        redis 127.0.0.1:6379> echo HongWan

        "HongWan"

         

        select 

         

        选择数据库。Redis 数据库编号从0~15,我们可以选择任意一个数据库来进行数据的存取。

         

        选择数据库。Redis 数据库编号从0~15,我们可以选择任意一个数据库来进行数据的存取。

        redis 127.0.0.1:6379> select 1

        OK

        redis 127.0.0.1:6379[1]> select 16

        (error) ERR invalid DB index

        redis 127.0.0.1:6379[16]>

        当选择16 时,报错,说明没有编号为16 的这个数据库

         

        quit

         

        退出连接。

         

        redis 127.0.0.1:6379> quit

         

        dbsize

         

        返回当前数据库中key 的数目。

         

        redis 127.0.0.1:6379> dbsize

        (integer) 18

        redis 127.0.0.1:6379>

        结果说明此库中有18 个key

         

        info

         

        获取服务器的信息和统计。

         

        redis 127.0.0.1:6379> info

        redis_version:2.2.12

        redis_git_sha1:00000000

        redis_git_dirty:0

        arch_bits:32

        multiplexing_api:epoll

        process_id:28480

        uptime_in_seconds:2515

        uptime_in_days:0

        。。。。

        。。。。

         

        flushdb

         

        删除当前选择数据库中的所有key。

        redis 127.0.0.1:6379> dbsize

        (integer) 18

        redis 127.0.0.1:6379> flushdb

        OK

        redis 127.0.0.1:6379> dbsize

        (integer) 0

        redis 127.0.0.1:6379>

        在本例中我们将0 号数据库中的key 都清除了。

         

        flushall

         

        删除所有数据库中的所有key

         

        redis 127.0.0.1:6379[1]> dbsize

        (integer) 1

        redis 127.0.0.1:6379[1]> select 0

        OK

        redis 127.0.0.1:6379> flushall

        OK

        redis 127.0.0.1:6379> select 1

        OK

        redis 127.0.0.1:6379[1]> dbsize

        (integer) 0

        redis 127.0.0.1:6379[1]>

        在本例中我们先查看了一个1 号数据库中有一个key,然后我切换到0 号库执行flushall 命令,结果1 号库中的key 也被清除了,说是此命令工作正常。

         参考链接:https://juejin.cn/post/6844903951502934030

        上一篇:redhat 6.5 YUM安装kvm 并用VNC远程管理


        下一篇:《ANSYS Workbench 14有限元分析自学手册》——1.2 ANSYS Workbench分析的基本过程