Redis的数据类型、以及常用操作命令

Redis的数据类型

redis当中一共支持五种数据类型,分别是:

  • string字符串
  • list列表
  • set集合
  • hash表
  • zset有序集合

通过这五种不同的数据类型,可以实现各种不同的功能,也可以应用在各种不同的场景。

Redis的数据类型

Redis当中各种数据类型结构如上图:

对字符串string的操作

下表列出了常用的 redis 字符串命令

序号命令及描述示例
1SET key value 设置指定 key 的值示例:SET hello world
2GET key 获取指定 key 的值。示例:GET hello
4GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。示例:GETSET hello world2
5MGET key1 [key2…] 获取所有(一个或多个)给定 key 的值。示例:MGET hello world
6SETEX key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。示例:SETEX hello 10 world3
7SETNX key value 只有在 key 不存在时设置 key 的值。示例:SETNX key redisvalue
9STRLEN key 返回 key 所储存的字符串值的长度。示例:STRLEN key
10MSET key value [key value …] 同时设置一个或多个 key-value 对。示例:MSET key2 keyvalue2 key3 keyvalue3
12MSETNX key value [key value …] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。示例:MSETNX key4 keyvalue4 key5 keyvalue5
13PSETEX key milliseconds value 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。示例:PSETEX key6 6000 key6value
14INCR key 将 key 中储存的数字值增加一。示例:set key7 1INCR key7GET key7
15INCRBY key increment 将 key 所储存的值加上给定的增量值(increment)示例:INCRBY key7 2get key7
16INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment)示例:INCRBYFLOAT key7 0.8
17DECR key 将 key 中储存的数字值减一。示例:set key8 1DECR key8GET key8
18DECRBY key decrement key 所储存的值减去给定的减量值(decrement)示例:DECRBY key8 3
19APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。示例:APPEND key8 hello

对hash列表的操作

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)

下表列出了 redis hash 基本的相关命令:

序号命令及描述示例
1HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。示例:HSET key1 field1 value1
2HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。示例:HSETNX key1 field2 value2
3HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。示例:HMSET key1 field3 value3 field4 value4
4HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。示例:HEXISTS key1 field4HEXISTS key1 field6
5HGET key field 获取存储在哈希表中指定字段的值。示例:HGET key1 field4
6HGETALL key 获取在哈希表中指定 key 的所有字段和值示例:HGETALL key1
7HKEYS key 获取所有哈希表中的字段示例:HKEYS key1
8HLEN key 获取哈希表中字段的数量示例:HLEN key1
9HMGET key field1 [field2] 获取所有给定字段的值示例:HMGET key1 field3 field4
10HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。示例:HSET key2 field1 1HINCRBY key2 field1 1HGET key2 field1
11HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。示例:HINCRBYFLOAT key2 field1 0.8
12HVALS key 获取哈希表中所有值示例:HVALS key1
13HDEL key field1 [field2] 删除一个或多个哈希表字段示例:HDEL key1 field3HVALS key1

对list列表的操作

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

下表列出了列表相关的基本命令:

序号命令及描述示例
1LPUSH key value1 [value2] 将一个或多个值插入到列表头部示例:LPUSH list1 value1 value2
2LRANGE key start stop查看list当中所有的数据示例:LRANGE list1 0 -1
3LPUSHX key value 将一个值插入到已存在的列表头部示例:LPUSHX list1 value3LINDEX list1 0
4RPUSH key value1 [value2] 在列表中添加一个或多个值到尾部示例:RPUSH list1 value4 value5LRANGE list1 0 -1
5RPUSHX key value 为已存在的列表添加单个值到尾部示例:RPUSHX list1 value6
6LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素示例:LINSERT list1 BEFORE value3 beforevalue3
7LINDEX key index 通过索引获取列表中的元素示例:LINDEX list1 0
8LSET key index value 通过索引设置列表元素的值示例:LSET list1 0 hello
9LLEN key 获取列表长度示例:LLEN list1
10LPOP key 移出并获取列表的第一个元素示例:LPOP list1
11RPOP key 移除列表的最后一个元素,返回值为移除的元素。示例:RPOP list1
12BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。示例:BLPOP list1 2000
13BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。示例:BRPOP list1 2000
14RPOPLPUSH source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回示例:RPOPLPUSH list1 list2
15BRPOPLPUSH source destination timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。示例:BRPOPLPUSH list1 list2 2000
16LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。示例:LTRIM list1 0 2
17DEL key1 key2删除指定key的列表示例:DEL list2

对set集合的操作

  • Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
  • Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
  • 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

下表列出了 Redis 集合基本命令:

序号命令及描述示例
1SADD key member1 [member2] 向集合添加一个或多个成员示例:SADD set1 setvalue1 setvalue2
2SMEMBERS key 返回集合中的所有成员示例:SMEMBERS set1
3SCARD key 获取集合的成员数示例:SCARD set1
4SDIFF key1 [key2] 返回给定所有集合的差集示例:SADD set2 setvalue2 setvalue3SDIFF set1 set2
5SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中示例:SDIFFSTORE set3 set1 set2
6SINTER key1 [key2] 返回给定所有集合的交集示例:SINTER set1 set2
7SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中示例:SINTERSTORE set4 set1 set2
8SISMEMBER key member 判断 member 元素是否是集合 key 的成员示例:SISMEMBER set1 setvalue1
9SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合示例:SMOVE set1 set2 setvalue1
10SPOP key 移除并返回集合中的一个随机元素示例:SPOP set2
11SRANDMEMBER key [count] 返回集合中一个或多个随机数示例:SRANDMEMBER set2 2
12SREM key member1 [member2] 移除集合中一个或多个成员示例:SREM set2 setvalue1
13SUNION key1 [key2] 返回所有给定集合的并集示例:SUNION set1 set2
14SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中示例:SUNIONSTORE set5 set1 set2

对key的操作

下表给出了与 Redis 键相关的基本命令:

序号命令及描述示例
1DEL key 该命令用于在 key 存在时删除 key。示例:del key5
2DUMP key 序列化给定 key ,并返回被序列化的值。示例:DUMP key1
3EXISTS key 检查给定 key 是否存在。示例:exists key
4EXPIRE key seconds 为给定 key 设置过期时间,以秒计。示例:expire key 5
6PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。示例:PEXPIRE set3 3000
8KEYS pattern 查找所有符合给定模式( pattern)的 key 。示例:keys *
10PERSIST key 移除 key 的过期时间,key 将持久保持。示例:persist set2
11PTTL key 以毫秒为单位返回 key 的剩余的过期时间。示例:pttl set2
12TTL key 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。示例:ttl set2
13RANDOMKEY 从当前数据库中随机返回一个 key 。示例: randomkey
14RENAME key newkey 修改 key 的名称示例:rename set5 set8
15RENAMENX key newkey 仅当 newkey 不存在时,将 key 改名为 newkey 。示例:renamenx set8 set10
16TYPE key 返回 key 所储存的值的类型。示例:type set10

对ZSet的操作

  • Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员
  • 它用来保存需要排序的数据,例如排行榜,一个班的语文成绩,一个公司的员工工资,一个论坛的帖子等。
  • 有序集合中,每个元素都带有score(权重),以此来对元素进行排序
  • 它有三个元素:key、member和score。以语文成绩为例,key是考试名称(期中考试、期末考试等),member是学生名字,score是成绩。
#命令及描述示例
1ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数向ZSet中添加页面的PV值ZADD pv_zset 120 page1.html 100 page2.html 140 page3.html
2ZCARD key 获取有序集合的成员数获取所有的统计PV页面数量ZCARD pv_zset
3ZCOUNT key min max 计算在有序集合中指定区间分数的成员数获取PV在120-140在之间的页面数量ZCOUNT pv_zset 120 140
4ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment给page1.html的PV值+1ZINCRBY pv_zset 1 page1.html
5ZINTERSTORE destination numkeys key [key …] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中创建两个保存PV的ZSET:ZADD pv_zset1 10 page1.html 20 page2.htmlZADD pv_zset2 5 page1.html 10 page2.htmlZINTERSTORE pv_zset_result 2 pv_zset1 pv_zset2
7ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合指定区间内的成员获取所有的元素,并可以返回每个key对一个的scoreZRANGE pv_zset_result 0 -1 WITHSCORES
9ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员获取ZSET中120-140之间的所有元素ZRANGEBYSCORE pv_zset 120 140
10ZRANK key member 返回有序集合中指定成员的索引获取page1.html的pv排名(升序)ZRANK pv_zset page3.html
11ZREM key member [member …] 移除有序集合中的一个或多个成员移除page1.htmlZREM pv_zset page1.html
15ZREVRANGE key start stop [WITHSCORES] 返回有序集中指定区间内的成员,通过索引,分数从高到低按照PV降序获取页面ZREVRANGE pv_zset 0 -1
17ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序获取page2.html的pv排名(降序)ZREVRANK pv_zset page2.html
18ZSCORE key member 返回有序集中,成员的分数值获取page3.html的分数值ZSCORE pv_zset page3.html

对位图BitMaps的操作

  • 计算机最小的存储单位是位bit,Bitmaps是针对位的操作的,相较于String、Hash、Set等存储方式更加节省空间
  • Bitmaps不是一种数据结构,操作是基于String结构的,一个String最大可以存储512M,那么一个Bitmaps则可以设置2^32个位
  • Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量

Redis的数据类型

  • BitMaps 命令说明:将每个独立用户是否访问过网站存放在Bitmaps中, 将访问的用户记做1, 没有访问的用户记做0, 用偏移量作为用户的id

设置值

SETBIT key offset value

setbit命令设置的vlaue只能是01两个值

  • 设置键的第offset个位的值(从0算起),假设现在有20个用户,uid=0,5,11,15,19的用户对网站进行了访问, 那么当前Bitmaps初始化结果如图所示

Redis的数据类型

  • 具体操作过程如下, unique:users:2016-04-05代表2016-04-05这天的独立访问用户的Bitmaps

setbit unique:users:2016-04-05 0 1setbit unique:users:2016-04-05 5 1setbit unique:users:2016-04-05 11 1setbit unique:users:2016-04-05 15 1setbit unique:users:2016-04-05 19 1

  • 很多应用的用户id以一个指定数字(例如10000) 开头, 直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费, 通常的做法是每次做setbit操作时将用户id减去这个指定数字。
  • 在第一次初始化Bitmaps时, 假如偏移量非常大, 那么整个初始化过程执行会比较慢, 可能会造成Redis的阻塞。

获取值

GETBIT key offset

  • 获取键的第offset位的值(从0开始算),例:下面操作获取id=8的用户是否在2016-04-05这天访问过, 返回0说明没有访问过

getbit unique:users:2016-04-05 8

获取Bitmaps指定范围值为1的个数

BITCOUNT key [start end]

例:下面操作计算2016-04-05这天的独立访问用户数量:

bitcount unique:users:2016-04-05

Bitmaps间的运算

BITOP operation destkey key [key, …]

  • bitop是一个复合操作, 它可以做多个Bitmaps的and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在destkey中。 假设2016-04-04访问网站的userid=1, 2, 5, 9, 如图3-13所示:

Redis的数据类型

setbit unique:users:2016-04-04 1 1setbit unique:users:2016-04-04 2 1setbit unique:users:2016-04-04 5 1setbit unique:users:2016-04-04 9 1

例1:下面操作计算出2016-04-04和2016-04-05两天都访问过网站的用户数量, 如下所示。

bitop and unique:users:and:2016-04-04_05 unique:users:2016-04-04 unique:users:2016-04-05bitcount unique:users:2016-04-04_05

例2:如果想算出2016-04-04和2016-04-03任意一天都访问过网站的用户数量(例如月活跃就是类似这种) , 可以使用or求并集, 具体命令如下:

bitop or unique:users:or:2016-04-04_05 unique:users:2016-04-04 unique:users:2016-04-05bitcount unique:users:or:2016-04-04_05

Redis的数据类型

对HyperLogLog结构的操作

应用场景

HyperLogLog常用于大数据量的统计,比如页面访问量统计或者用户访问量统计。

要统计一个页面的访问量(PV),可以直接用redis计数器或者直接存数据库都可以实现,如果要统计一个页面的用户访问量(UV),一个用户一天内如果访问多次的话,也只能算一次,这样,我们可以使用SET集合来做,因为SET集合是有去重功能的,key存储页面对应的关键字,value存储对应的userid,这种方法是可行的。但如果访问量较多,假如有几千万的访问量,这就麻烦了。为了统计访问量,要频繁创建SET集合对象。

Redis实现HyperLogLog算法,HyperLogLog 这个数据结构的发明人 是Philippe Flajolet(菲利普·弗拉若莱)教授。Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

UV计算示例

node1.key.cn:6379> help @hyperloglogPFADD key element [element …]summary: Adds the specified elements to the specified HyperLogLog.since: 2.8.9PFCOUNT key [key …]summary: Return the approximated cardinality(基数) of the set(s) observed by the HyperLogLog at key(s).since: 2.8.9PFMERGE destkey sourcekey [sourcekey …]summary: Merge N different HyperLogLogs into a single one.since: 2.8.9

Redis集成的HyperLogLog使用语法主要有pfadd和pfcount,顾名思义,一个是来添加数据,一个是来统计的。为什么用pf?是因为HyperLogLog 这个数据结构的发明人 是Philippe Flajolet教授 ,所以用发明人的英文缩写,这样容易记住这个语法了。

下面我们通过一个示例,来演示如何计算uv。

node1.key.cn:6379> pfadd uv user1(integer) 1node1.key.cn:6379> keys *1) "uv"node1.key.cn:6379> pfcount uv(integer) 1node1.key.cn:6379> pfadd uv user2(integer) 1node1.key.cn:6379> pfcount uv(integer) 2node1.key.cn:6379> pfadd uv user3(integer) 1node1.key.cn:6379> pfcount uv(integer) 3node1.key.cn:6379> pfadd uv user4(integer) 1node1.key.cn:6379> pfcount uv(integer) 4node1.key.cn:6379> pfadd uv user5 user6 user7 user8 user9 user10(integer) 1node1.key.cn:6379> pfcount uv(integer) 10

HyperLogLog算法一开始就是为了大数据量的统计而发明的,所以很适合那种数据量很大,然后又没要求不能有一点误差的计算,HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,不过这对于页面用户访问量是没影响的,因为这种统计可能是访问量非常巨大,但是又没必要做到绝对准确,访问量对准确率要求没那么高,但是性能存储方面要求就比较高了,而HyperLogLog正好符合这种要求,不会占用太多存储空间,同时性能不错

pfaddpfcount常用于统计,需求:假如两个页面很相近,现在想统计这两个页面的用户访问量呢?这里就可以用pfmerge合并统计了,语法如例子:

node1.key.cn:6379> pfadd page1 user1 user2 user3 user4 user5(integer) 1node1.key.cn:6379> pfadd page2 user1 user2 user3 user6 user7(integer) 1node1.key.cn:6379> pfmerge page1+page2 page1 page2OKnode1.key.cn:6379> pfcount page1+page2(integer) 7

HyperLogLog为什么适合做大量数据的统计

  • Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
  • 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
  • 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

什么是基数?

比如:数据集{1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集{1, 3, 5, 7, 8},基数(不重复元素)为5。基数估计就是在误差可接受的范围内,快速计算基数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我:yueda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值