文章目录

  • 概述
  • Keys
  • Strings
  • Lists
  • Hashes
  • Sets
  • Sorted sets
  • Bitmaps
  • HyperLogLogs

原文: https://redis.io/topics/data-types-intro

概述

Redis 是一个 key-value 存储器,但是它的 value 的类型并不局限于 string,还可以是其他复杂的类型,如下表所示:

类型 说明 相关命令
Binary-safe strings 字符串 APPEND, BITCOUNT, BITFIELD, BITOP, BITPOS, DECR, DECRBY, GET, GETBIT, GETRANGE, GETSET, INCR, INCRBY, INCRBYFLOAT, MGET, MSET, MSETNX, PSETEX, SET, SETBIT, SETEX, SETNX, SETRANGE, STRLEN
Lists 按插入顺序排列的双向链表,元素类型为字符串 BLPOP, BRPOP, BRPOPLPUSH, LINDEX, LINSERT, LLEN, LPOP, LPUSH, LPUSHX, LRANGE, LREM, LSET, LTRIM, RPOP, RPOPLPUSH, RPUSH, RPUSHX,
Sets 无序,无重复值的字符串集合 SADD, SCARD, SDIFF, SDIFFSTORE, SINTER, SINTERSTORE, SISMEMBER, SMEMBERS, SMOVE, SPOP, SRANDMEMBER, SREM, SSCAN, SUNION, SUNIONSTORE,
Sorted sets 有序,无重复值的字符串集合,每个元素关联一个 float 值,作为 score,用以排序 BZPOPMAX, BZPOPMIN, ZADD, ZCARD, ZCOUNT, ZINCRBY, ZINTERSTORE, ZLEXCOUNT, ZPOPMAX, ZPOPMIN, ZRANGE, ZRANGEBYLEX, ZRANGEBYSCORE, ZRANK, ZREM, ZREMRANGEBYLEX, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZREVRANGE, ZREVRANGEBYLEX, ZREVRANGEBYSCORE, ZREVRANK, ZSCAN, ZSCORE, ZUNIONSTORE,
Hashes 元素为 field-value 形式的数据集,field 和 value 都为 string 型 HDEL, HEXISTS, HGET, HGETALL, HINCRBY, HINCRBYFLOAT, HKEYS, HLEN, HMGET, HMSET, HSCAN, HSET, HSETNX, HSTRLEN, HVALS,
Bit arrays bit 组,可看做位图,通过特定指令操作字符串对应的 bit 位 APPEND, BITCOUNT, BITFIELD, BITOP, BITPOS, DECR, DECRBY, GET, GETBIT, GETRANGE, GETSET, INCR, INCRBY, CRBYFLOAT, MGET, MSET, MSETNX, PSETEX, SET, SETBIT, SETEX, SETNX, SETRANGE, STRLEN,
HyperLogLogs
Streams

要想更好的理解 redis,并使用 redis 解决实际问题,必须先好好的了解 redis 的数据结构,它的概念?相关的命令?是怎么样的?等等。在学习 redis 时,可以多使用 redis-cli 工具,这是一个简单、方便、又强大的命令行工具。
.

Keys

redis 的键是二进制安全的,也就是说可以为二进制数据,比如 JPEG 文件,空字符串也是有效的 key。

键值不宜过长,比如 1024 字节的key,即不便于记忆,也不方便查询。但也不应太过简洁,例如 “u1000flw”, 显然不如 “user:1000:followers”,后者更易读。在实际应用中,需要在内存占用可理解性 两者之间做权衡。

键值最好有一定的结构性,类似 “object-type:id” 形式的,如 “user:1000”,或者 “comment?reply.to”,不同属性使用 : 分割,相同属性的多个单词之间可以使用 ._ 分割。

key 最大不超过 512 MB.

Strings

字符串是 redis 中最简单的值。

实际工作中,需要缓存 <string, string> 类型数据的场景很多,比如缓存 HTML 页。

> set mykey somevalue
OK
> get mykey
“somevalue”

在 redis-cli 中,使用 set/get 命令来 设置/获取 键值对,当调用 set 时,如果 key 对应的 value 已存在,则用新值替换原值,不管原值为何种类型。

当 value 为 string 时,大小不能超过 512 MB。

SET 命令有些有意思的选项,在调用时作为附加参数,例如,当 key 存在时,使 set 失败;或者,只有当 key 存在时,set 才执行。

> set mykey newval nx
(nil)
> set mykey newval xx
OK

INCR, INCRBY, DECR and DECRBY,这些命令会将 string 解析为 integer,并原子性的增加或减少。

> set counter 100
OK
> incr counter
(integer) 101
incrby counter 50
(integer) 152

GETSET 命令在为 key 赋值的同时,返回 key 对应的旧值。这个命令有时很有用,比如,当有用户访问时,系统中的某个 counter 值就加 1,并且每过一个小时,获取 counter 当前值,并将 counter 重置为 0;如果不是 GETSET,当访问量较大时,统计必然会出现遗漏。

MSET 和 MGET 可以处理多个 key 的情况:

> mset a 10 b 20 c 30
OK
> mget a b c
“10”
“20”
“30”

MGET 返回的结果为数组。

可以使用 TYPE 命令查看 key 对应的值的类型。

> type mykey
string
del mykey
(integer) 1
type mykey
none

redis 支持设置 key 的过期时间,也就是 TTL(limited time to live),当 ttl 结束时,对应的 key 会自动清除。

相关的命令有:

  • EXPIRE key seconds
  • EXPIREAT key timestamp
  • PEXPIRE key milliseconds
  • PEXPIREAT key milliseconds-timestamp

ttl 相关信息会序列化到磁盘中,也就是说,即使 redis 服务关闭了,ttl 时间也会继续减少。

> set key some-value
OK
> expire key 5
(integer) 1
> get key (immediately)
“some-value”
> get key (after some time)
(nil)

PERSIT 命令用来取消 expire,让对应的 key 一致存在。

也可以使用 SET 附加属性来设置过期时间:

> set key 100 ex 10
OK
> ttl key
(integer) 9

Lists

redis 中的 list 是通过链表来实现的,因此可以快速的插入到表头或表尾,所消耗的时间与 list 的长度无关,其缺点是,随机访问比 array 慢。

在需要较多随机访问的场景中,可以选择使用 sorted set,而不是 list。

> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lpush mylist first
(integer) 3
> lrange mylist 0 -1
“first”
“A”
“B”

rpush/lpush 用于往 list 中添加元素,lrange 用以获取子 list,获取列表右侧的子list,可以使用负数下标。

可以同时添加多个元素

> rpush mylist 1 2 3 4 5 "foo bar"
(integer) 9
> lrange mylist 0 -1
“first”
“A”
“B”
“1”
“2”
“3”
“4”
“5”
“foo bar”

POP 命令用于获取并删除元素,当对空列表执行 POP 时,会返回 null:

> rpop mylist
(nil)

使用案例 :

  1. 在社交网络中,缓存用户最近的更新;twitter 中就是用 redis 缓存用户最近更新的内容;
  2. 跨进程间通信,作为消费者-生产者模型中的消息中间件,

大多数情况下,我们使用 redis list 来缓存最近的更新,不管是社交网络内容,日志,还是其他数据。使用 LTRIM 命令,可以让 list 始终保存最近的 N 个元素,删除旧的数据。

> rpush mylist 1 2 3 4 5
(integer) 5
> ltrim mylist 0 2
OK
> lrange mylist 0 -1
“1”
“2”
“3”

注意:LRANGE 操作的时间复杂度为 O(n)O(n)O(n)

redis list 可以用于消息队列,或者任务队列。当 list 为空时,RPOP 操作会返回 NULL,这时,可以选择等待一段时间后,再次调用 RPOP,这种方式称为轮询;或者使用 BRPOP 或 BLPOP 命令,当 list 为空时,让命令阻塞等待,直到有新的元素加入到 list 中,或者超时时间已过。

> brpop tasks 5
“tasks”
“do_something”

当 timeout 值为 0 时,会一直等待。

Redis 对 BRPOP 命令的处理是有序的,第一个调用的 client 会首先得到返回值。另外,由于 BLPOP 与 BRPOP 允许操作多个 list,所以其返回值是 (key, value) 元组。

RPOPLPUSH srclist, dst list 删除 srclist 中的元素,并将其添加到 dstlist 中。

注意,Redis 会自动创建不存在的 list,并且删除那些元素为空的 list。

Hashes

Redis hash 中存储的是 (field, value) 二元组。

> hmset user:1000 username antirez birthyear 1977 verified 1
OK
> hget user:1000 username
“antirez”
> hget user:1000 birthyear
“1977”
> hgetall user:1000
“username”
“antirez”
“birthyear”
“1977”
“verified”
“1”

hash 中 field 的数目没有大小限制。

  • HMSET :设置多个字段值;
  • HGET:获取单个字段值;
  • HMGET: 获取多个字段值;返回的是值的数组;
  • HGETALL:获取所有字段值;返回包括全部数据的数组,包括字段和值;
  • HINCRBY: 增加字段值的大小;

> hincrby user:1000 birthyear 10
(integer) 1987
> hincrby user:1000 birthyear 10
(integer) 1997

Sets

Sets 是无序的字符串集合。sets 相关的操作有元素的添加删除(SADD),判断存在性(SISMEMBER),求多个集合的交集,并集,差集,等待。

sadd myset 1 2 3
(integer) 3
smembers myset
3
1
2

SADD 命令往 sets 中添加元素,由上例可见,smembers 获取的元素是无序的。

> sismember myset 3
(integer) 1
> sismember myset 30
(integer) 0

集合很适于用来表示对象之间的关系,比如,用 sets 来存储对象的标签集,每个需要标注的对象,都分配一个 set,set 中保存该对象所有标签的 id。

对象所有标签的集合:

> sadd news:1000:tags 1 2 5 77
(integer) 4

标签关联的对象集:

> sadd tag:1:news 1000
(integer) 1
> sadd tag:2:news 1000
(integer) 1
> sadd tag:5:news 1000
(integer) 1
> sadd tag:77:news 1000
(integer) 1
> smembers news:1000:tags
5
1
77
2

备注:上例中,还需要一个用来映射标签 id 与 标签名称的 hash。

有时,会需要一些复杂的集合操作,比如想获得标注了 1,2,10,27 这四个标签的所有对象的集合,可以使用 SINTER 命令:

> sinter tag:1:news tag:2:news tag:10:news tag:27:news
… results here …

除了交集,还可以求并集,差集等。

下例中,用 set 来表示一副扑克,其中 C 梅花,D 方块,H 红桃,S 黑桃:

> sadd deck C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 HJ HQ HK S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 SJ SQ SK
(integer) 52

SPOP 会随机的获取集合中的一个元素,因此,可以完美的模拟随机发牌的场景。当下一局发牌时,还需要重新初始化 derk,可以使用 SUNIONSTORE 命令来备份 set,这样就不需要每次都重新初始化了。

> sunionstore game:1:deck deck
(integer) 52
> spop game:1:deck
“C6”
> spop game:1:deck
“CQ”
> spop game:1:deck
“D1”
> spop game:1:deck
“CJ”
> spop game:1:deck
“SJ”

SCARD 能返回集合中元素的个数,又称为集合的基数(cardinality)。

scard game:1:deck
(integer) 47
The math works: 52 - 5 = 47.

如果仅仅希望随机获取元素,但不删除,可以使用 SRANDMEMBER,该命令支持重复获取和非重复获取元素两种方式。

Sorted sets

Sorted sets 像是 sets 与 hash 的混合体,首先,它像 sets 一样是非重复元素的集合,但是 sorted sets 中的元素会关联一个 float 值,称为 score,这跟 hash 有点像。

zadd key [NX|XX] [CH] [INCR] score member [score member ...]

> zadd hackers 1940 "Alan Kay"
(integer) 1
> zadd hackers 1957 "Sophie Wilson"
(integer) 1
> zadd hackers 1953 "Richard Stallman"
(integer) 1
> zadd hackers 1949 "Anita Borg"
(integer) 1
> zadd hackers 1965 "Yukihiro Matsumoto"
(integer) 1
> zadd hackers 1914 "Hedy Lamarr"
(integer) 1
> zadd hackers 1916 "Claude Shannon"
(integer) 1
> zadd hackers 1969 "Linus Torvalds"
(integer) 1
> zadd hackers 1912 "Alan Turing"
(integer) 1

ZADD 的使用方式跟 SADD 类似,但是多了个一个 score 参数。

> zrange hackers 0 -1
“Alan Turing”
“Hedy Lamarr”
“Claude Shannon”
“Alan Kay”
“Anita Borg”
“Richard Stallman”
“Sophie Wilson”
“Yukihiro Matsumoto”
“Linus Torvalds”

使用 ZREVRANGE 来获取反序的列表

> zrevrange hackers 0 -1
“Linus Torvalds”
“Yukihiro Matsumoto”
“Sophie Wilson”
“Richard Stallman”
“Anita Borg”
“Alan Kay”
“Claude Shannon”
“Hedy Lamarr”
“Alan Turing”

使用 WITHSCORES 参数,可以获取包含 score 的结果列表:

> zrange hackers 0 -1 withscores
“Alan Turing”
“1912”
“Hedy Lamarr”
“1914”
“Claude Shannon”
“1916”
“Alan Kay”
“1940”
“Anita Borg”
“1949”
“Richard Stallman”
“1953”
“Sophie Wilson”
“1957”
“Yukihiro Matsumoto”
“1965”
“Linus Torvalds”
“1969”

sorted sets 还支持很多强大的,复杂的操作,比如使用 ZRANGEBYSCORE 命令获取所有 1950 年之前出生的黑客,使用

> zrangebyscore hackers -inf 1950
“Alan Turing”
“Hedy Lamarr”
“Claude Shannon”
“Alan Kay”
“Anita Borg”

Bitmaps

bitmaps 并不是实际的数据类型,而是一组定义在字符串上的 bit 操作集。redis 中字符串的最大长度为 512 MB,也就是说最大位数为 2322^{32}232。

比特操作分为两类:单点操作,组操作。

位图,又称为位掩码,比如,40亿人的性别信息,可以使用 512 MB大小的比特位来表示,而不是使用 id + boolean 的形式。

HyperLogLogs

A HyperLogLog is a probabilistic data structure used in order to count unique things (technically this is referred to estimating the cardinality of a set). Usually counting unique items requires using an amount of memory proportional to the number of items you want to count, because you need to remember the elements you have already seen in the past in order to avoid counting them multiple times. However there is a set of algorithms that trade memory for precision: you end with an estimated measure with a standard error, which in the case of the Redis implementation is less than 1%. The magic of this algorithm is that you no longer need to use an amount of memory proportional to the number of items counted, and instead can use a constant amount of memory! 12k bytes in the worst case, or a lot less if your HyperLogLog (We’ll just call them HLL from now) has seen very few elements.

HLLs in Redis, while technically a different data structure, are encoded as a Redis string, so you can call GET to serialize a HLL, and SET to deserialize it back to the server.

Conceptually the HLL API is like using Sets to do the same task. You would SADD every observed element into a set, and would use SCARD to check the number of elements inside the set, which are unique since SADD will not re-add an existing element.

While you don’t really add items into an HLL, because the data structure only contains a state that does not include actual elements, the API is the same:

Every time you see a new element, you add it to the count with PFADD.
Every time you want to retrieve the current approximation of the unique elements added with PFADD so far, you use the PFCOUNT.

pfadd hll a b c d
(integer) 1
pfcount hll
(integer) 4

An example of use case for this data structure is counting unique queries performed by users in a search form every day.

Redis is also able to perform the union of HLLs, please check the full documentation for more information.

Redis 几种数据类型的详细介绍相关推荐

  1. Redis五种数据类型介绍

    概述 Redis的键值可以使用物种数据类型:字符串,散列表,列表,集合,有序集合.本文详细介绍这五种数据类型的使用方法.本文命令介绍部分只是列举了基本的命令,至于具体的使用示例,可以参考Redis官方 ...

  2. Redis八种数据类型及应用场景介绍

    本文来说下Redis八种数据类型及应用场景介绍 文章目录 概述 String 介绍 应用场景 Hash 介绍 应用场景 List 介绍 应用场景 Set 介绍 应用场景 ZSet 介绍 应用场景 Bi ...

  3. 2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

    作者:小林coding 计算机八股文网(操作系统.计算机网络.计算机组成.MySQL.Redis):https://xiaolincoding.com 大家好,我是小林. 我们都知道 Redis 提供 ...

  4. 吃透Redis系列(九):Redis代理twemproxy和predixy详细介绍

    Redis系列文章: 吃透Redis系列(一):Linux下Redis安装 吃透Redis系列(二):Redis六大数据类型详细用法 吃透Redis系列(三):Redis管道,发布/订阅,事物,过期时 ...

  5. redis五种数据类型的使用场景

    string 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...

  6. redis五种数据类型对应的底层数据结构

    redis五种数据类型对应的底层数据结构 redis的五种数据类型 redis核心对象redisObject type数据类型 encoding编码类型 ptr指针 redis五种数据类型对应的底层数 ...

  7. Redis五种数据类型及应用场景

    Redis五种数据类型及应用场景 MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样 ...

  8. Redis五种数据类型及命令(一)

    Redis 五种数据类型详解及命令 Redis五种数据类型分别为: String:最基本的字符串类型. list:列表(如果对比java来看,这个list不是ArrayList,而是LinkedLis ...

  9. redis五种数据类型及其常见操作

    redis五种数据类型及其常见操作 Redis支持5种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 1.strin ...

最新文章

  1. Unity 简单示例代码和向导/Unity Aplication Block
  2. alter table add column多个字段_SQL对表中字段的操作 alter
  3. OpenHarmony的介绍
  4. Eclipse里PHP built-in server在操作系统中的实际位置
  5. 牛客题霸 [顺时针旋转矩阵] C++题解/答案
  6. php的toast,jQuery 一句代码轻松实现 Toast 的提示框
  7. Linux学习之基础命令
  8. 一文了解NLP领域国内外主要学术组织、会议和论文
  9. c语言side输出空心正方形,回溯法--正方形(蛋糕切分)问题
  10. 【电子书下载】《Android应用程序开发与典型案例》完整版!!
  11. 易飞erp postgre mysql_pgadmin 执行sql
  12. 手机计算机软件删除了怎么恢复,手机卸载的软件怎么恢复?手机卸载的软件恢复方法介绍...
  13. 【nvidia npp】——图像resize
  14. 个人理财软件CheckBook Pro for Mac
  15. springboot自动装配原理
  16. NVI(Non-Virtual Interface)手法
  17. Cy5 COOH非活性染料溶于有机溶剂1032678-07-1 科研
  18. 如何学习三点透视?该注意什么?
  19. C#精挑整理知识要点11 委托和事件(建议收藏)
  20. 燕山大学2019年计算机全国排名,燕山大学2019年排名第90位 较2018年下降6名

热门文章

  1. 准备弄一个Bambook来看书
  2. 团队-排课软件-需求分析
  3. SpringCloud Gateway 增加了context-path 404解决办法
  4. 采样与保持实验报告计算机控制,计算机控制技术实验--模拟信号采样与保持文库 .doc...
  5. 听乌森聊强化学习的那些事
  6. K8S中安装ES集群
  7. 我爱log4j.properties
  8. CodeLab:Android fundamentals 01.3:Text and scrolling views
  9. 03 pyecharts 直角坐标系图表(示例代码+效果图)
  10. 真阳性假阳性假阴性分割可视化