“Redis:数据类型”的版本间差异

来自Wikioe
跳到导航 跳到搜索
→‎FAQ
→‎Set
第217行: 第217行:
=== Set ===
=== Set ===
----
----
Set 集合也是一个列表,不过它的特殊之处在于它是可以'''自动去掉重复元素'''的。
Set 集合类型的使用场景是:当需要存储一个列表,而又不希望有重复的元素(例如ID的集合)时,使用 Set 是一个很好的选择。
 
特点:
1、Set 类型拥有一个命令,它可用于'''判断某个元素是否存在''',而 List 类型并没有这种功能的命令。
2、通过 Set 集合类型的命令可以快速地向集合添加元素,或者从集合里面删除元素,也可以对多个 Set 集合进行'''集合运算''',例如并集、交集、差集。
集合类型:String 类型的无序集合,集合成员('''member''')是唯一的,即集合中'''不能出现重复的数据''';
集合类型:String 类型的无序集合,集合成员('''member''')是唯一的,即集合中'''不能出现重复的数据''';
: [[File:Redis-set.png|400px]]
: [[File:Redis-set.png|400px]]

2021年11月6日 (六) 05:25的版本


关于

Redis 以 key-value 存储数据,“key”为 String,其“数据类型”是指“value 的类型”;


Redis 支持五种数据类型:

数据类型 说明
string 字符串类型
list 列表类型
hash 哈希类型
set 集合类型
zset(sorted set) 有序集合类型

Redis 的 5 种数据类型

String


String 类型是 Redis 中最简单的数据结构。它既可以存储文字(例如"hello world"),又可以存储数字(例如整数 10086 和浮点数 3.14),还可以存储二进制数据(例如 10010100)。


字符串类型:字符串类型是Redis中最基本的数据类型;

Redis-string.png
  • 它能存储任何形式的字符串,包括二进制数据,序列化后的数据,JSON化的对象甚至是一张图片。


String 相关命令
命令 说明
append <key> <value> 如果 key 存在且是字符串, 则将 value 追加到 key 原来旧值的末尾;
  • 如果 key 不存在,就简单地将给定 key 设为 value ,就像执行 SET key value 一样;
strlen <key> 返回 key 所储存的字符串值的长度;
get <key> 获取 key 中设置的字符串值;
set <key> <value> 将字符串值 value 设置到 key 中;
mget <key> [<key>] 获取所有(一个或多个)给定 key 的值
mset <key> <value> [<key> <value>] 同时设置一个或多个 key-value 对
setnx <key> <value> setnx 是“set if not exists”的简写,如果key不存在,则设置值,存在则不设置值;
msetnx <key> <value> [<key> <value>] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在时才能设置成功,否则只要有一个key存在都会失败
getbit <key> offset 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
setbit <key> offset <value> 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
getrange <key> <start> <end> 获取 key 中字符串值从 start 开始 到 end 结束 的子字符串;
setrange <key> <offset> <value> 从指定的位置开始将 key 的值替换为新的字符串;
setex <key> <seconds> <value> set expire”的简写,设置 key 的值 ,并将 key 的生存时间设为 seconds (以秒为单位) ;
psetex <key> milliseconds <value> 这个命令和 setex 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 setex 命令那样,以秒为单位。
getset <key> <value> 设置 key 的值为 value ,并返回 key 的旧值;
incr <key> 将 key 中储存的数字值加 1;
  • 如果 key 不存在,则 key 的值先被初始化为 0 再执行 INCR 操作;
  • (只能对数字类型的数据操作,否则:“(error) ERR value is not an integer or out of range”);
decr <key> 将 key 中储存的数字值减 1;
  • (同上);
incrby <key> <increment> 将 key 所储存的值加上增量值;
  • 如果 key 不存在,则 key 的值先被初始化为 0 再执行 INCRBY 命令;
decrby <key> <decrement> 将 key 所储存的值减去减量值;
  • 如果 key 不存在,则 key 的值先被初始化为 0 再执行 DECRBY 命令;
incrbyfloat <key> <increment> 为 key 中所储存的值加上浮点数增量 increment;
  • 如果 key 不存在,那么 incrbyfloat 会先将 key 的值设为 0 ,再执行加法操作。
  • 当以下任意一个条件发生时,返回一个错误:
    1. key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型)
    2. key 当前的值或者给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)
bitcount <key> <start> <end> 计算给定字符串中,被设置为 1 的比特位的数量;
  • start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。
  • 不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。
bitop <operation> <destkey> <key> [<key> ...] 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上;
  • operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种:
    1. BITOP AND destkey key [key ...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。
    2. BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。
    3. BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。
    4. BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey 。
    • 除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。
  • 当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。
  • 空的 key 也被看作是包含 0 的字符串序列。

List


Redis 的 List 类型是基于【双向链表】实现的,可以支持正向、反向查找和遍历。从用户角度来说,List列表是简单的字符串列表,字符串按照添加的顺序排序。可以添加一个元素到List列表的头部(左边)或者尾部(右边)。一个List列表最多可以包含232-1个元素(最多可超过 40亿 个元素)。


List列表的典型应用场景:
   网络社区中最新的发帖列表、简单的消息队列、最新新闻的分页列表、博客的评论列表、排队系统等等。

举个具体的例子,在“双11”秒杀、抢购这样的大型活动中,短时间内有大量的用户请求发向服务器,而后台的程序不可能立刻响应每一个用户的请求,有什么好的办法来解决这个问题呢?
   我们需要一个排队系统。根据用户的请求时间,将用户的请求放入 List 队列中,后台程序依次从队列中获取任务,处理并将结果返回到结果队列。换句话说,通过List队列,可以将并行的请求转换成串行的任务队列,之后依次处理。


列表类型:简单的字符串列表,按照插入顺序排序。

Redis-list.png
  • 可以添加一个元素到列表的头部(左边)或者尾部(右边);
  • 一个列表最多可以包含 2^32 - 1 (40多亿)个元素。
  • List 列表的下标是从 0 开始的,index 为的时候是从后向前数(-1 表示最后一个元素)。当下标超出边界时,会返回 nil


List 相关命令
命令 说明
lpush <key> <value> [<value>] 将一个或多个值 value 插入到列表 key 的表头(最左边)
rpush <key> <value> [<value>] 将一个或多个值 value 插入到列表 key 的表尾(最右边)
lpushx <key> <value> 将一个值插入到已存在的列表头部,当且仅当 key 存在并且是一个列表
  • 和 LPUSH 命令相反,当 key 不存在时, LPUSHX 命令什么也不做。
rpushx <key> <value> 为已存在的列表添加值,当且仅当 key 存在并且是一个列表
  • 和 RPUSH 命令相反,当 key 不存在时, RPUSHX 命令什么也不做。
lpop <key> 从左边获取列表 key 的一个元素,并将该元素移除
rpop <key> 从右边获取列表 key 的一个元素,并将该元素移除
blpop <key> [<key>] timeout 移出并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的元素。
brpop <key> [<key>] timeout 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的元素。
rpoplpush <source> <destination> 将列表 source 中的最后一个元素(尾元素)弹出插入到目标列表(destination),作为目标列表的的头元素
brpoplpush <source> <destination> timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
llen <key> 获取列表 key 的长度
lindex <key> <index> 获取列表 key 中下标为指定 index 的元素
lset <key> <index> <value> 将列表 key 下标为 index 的元素的值设置为 value
linsert <key> BEFORE|AFTER <pivot> <value> 将值 value 插入到列表 key 当中位于值 pivot 之前或之后的位置
lrange <key> <start> <stop> 获取列表 key 中指定区间内的元素
  • 0 表示列表的第一个元素,以 1 表示列表的第二个元素, -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
lrem <key> <count> <value> 从左到右删除列表中指定个数(count)的“与指定value值相等的”value
ltrim <key> <start> <stop> 删除指定区域外的元素,比如“LTRIM list 0 2” ,表示只保留列表 list 的前三个元素,其余元素全部删除

Hash


Redis 中的 Hash 哈希表是一个 String 类型的 Field 字段和 Value 值之间的映射表,类似于 Java 中的 HashMap。

一个哈希表由多个“字段-值”对(Field-Value Pair)组成,Value 值可以是文字、整数、浮点数或者二进制数据。

在同一个 Hash 哈希表中,每个 Field 字段的名称必须是唯一的。这一点和 Java 中 HashMap 的 Key 键的规范要求也是八九不离十的。


哈希类型:是一个 String 类型的 fieldvalue 的映射表;

Redis-hash.png
  • Hash 特别适合用于存储对象
  • 每个 hash 可以存储 2^32 - 1 (40多亿)个键值对。


Hash 相关命令
命令 说明
hget <key> <field> 获取哈希表 key 中给定域 field 的值
hgetall <key> 获取哈希表 key 中所有的域和值
hset <key> <field> <value> 将哈希表 key 中的域 field 的值设为 value
hsetnx <key> <field> <value> 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在的时候才设置,否则不设置
hmset <key> <field> <value> [<field> <value>] 同时将多个 field-value (域-值)对设置到哈希表 key 中
hmget <key> <field> [<field>] 获取哈希表 key 中一个或多个给定域的值
hkeys <key> 查看哈希表 key 中的所有 field 域
hvals <key> 查看哈希表 key 中所有域的值
hexists <key> <field> 查看哈希表 key 中,给定域 field 是否存在
hlen <key> 获取哈希表 key 中域 field 的个数
hdel <key> <field> [<field>] 删除哈希表 key 中的一个或多个指定域 field
hincrby <key> <field> <increment> 为哈希表 key 中的域 field 的值加上增量 increment
hincrbyfloat <key> <field> <increment> 为哈希表 key 中的域 field 加上浮点数增量 increment
hscan <key> cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对【???】

Set


Set 集合也是一个列表,不过它的特殊之处在于它是可以自动去掉重复元素的。

Set 集合类型的使用场景是:当需要存储一个列表,而又不希望有重复的元素(例如ID的集合)时,使用 Set 是一个很好的选择。
 
特点:
1、Set 类型拥有一个命令,它可用于判断某个元素是否存在,而 List 类型并没有这种功能的命令。
2、通过 Set 集合类型的命令可以快速地向集合添加元素,或者从集合里面删除元素,也可以对多个 Set 集合进行集合运算,例如并集、交集、差集。


集合类型:String 类型的无序集合,集合成员(member)是唯一的,即集合中不能出现重复的数据

Redis-set.png
  • Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
  • 集合中最大的成员数为 2^32 - 1 (40多亿)。


Set 相关命令
命令 说明
sadd <key> <member> [<member>] 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将不会再加入
srem <key> <member> [<member>] 删除集合 key 中的一个或多个 member 元素
spop <key> [count] 随机从集合中删除一个元素
smove <source> <destination> <member> 将 member 元素从一个集合移动到另一个集合
scard <key> 获取集合里面的元素个数
smembers <key> 获取集合 key 中的所有成员元素
sismember <key> <member> 判断 member 元素是否是集合 key 的成员
srandmember <key> [count] 随机返回集合中的一个元素
sdiff <key> [<key>] 返回第一个集合与其他集合之间的差异。
sdiffstore <destination> <key> [<key>] 返回给定所有集合的差集并存储在 destination 中
sinter <key> [<key>] 返回给定所有集合的交集
sinterstore <destination> <key> [<key>] 返回给定所有集合的交集并存储在 destination 中
sunion <key> [key2] 返回所有给定集合的并集
sunionstore <destination> <key> [<key>] 所有给定集合的并集存储在 destination 集合中
sscan <key> cursor [MATCH pattern] [COUNT count] 迭代集合中的元素

Zset(sorted set)


有序集合类型:(有序的Set)不同的是 Zset 的每个元素(member)都会关联一个分数(score,分数可以重复),Redis 通过分数来为集合中的成员进行从小到大的排序。

Redis-zset.png
  • 有序集合的成员是唯一的,但分数(score)却可以重复。
  • 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
  • 集合中最大的成员数为 2^32 - 1 (40多亿)。


Zset 相关命令
命令 说明
zadd <key> [NX|XX] [CH] [INCR] <score> <member> [<score> <member>] 将一个或多个 member 元素及其 score 值加入到有序集合 key 中
zscore <key> <member> 返回有序集中,成员的分数值
zincrby <key> <increment> <member> 有序集合中对指定成员的分数加上增量 increment
zcard <key> 获取有序集合的成员数
zcount <key> <min> <max> 计算在有序集合中指定分数区间的成员数
zlexcount <key> <min> <max> 计算在有序集合中指定字典区间的成员数
zrank <key> <member> 返回有序集合中指定成员的索引
zrevrank <key> <member> 返回有序集合中指定成员的索引【rev:有序集成员按分数值递减(从大到小)排序】
zrange <key> <start> <stop> [WITHSCORES] 返回有序集中指定索引区间内的成员
zrevrange <key> <start> <stop> [WITHSCORES] 返回有序集中指定索引区间内的成员【rev:有序集成员按分数值递减(从大到小)排序】
zrangebylex <key> <min> <max> [LIMIT offset count] 返回有序集中指定字典区间内的成员
zrangebyscore <key> <min> <max> [WITHSCORES] [LIMIT offset count] 返回有序集中指定分数区间内的成员
zrevrangebyscore <key> <min> <max> [WITHSCORES] [LIMIT offset count] 返回有序集中指定分数区间内的成员【rev:有序集成员按分数值递减(从大到小)排序】
zrem <key> <member> [<member>] 移除有序集合 key 中的一个或多个成员
zremrangebylex <key> <min> <max> 移除有序集合中给定的字典区间的所有成员
zremrangebyrank <key> <start> <stop> 移除有序集合中给定的排名区间的所有成员
zremrangebyscore <key> <min> <max> 移除有序集合中给定的分数区间的所有成员
zinterstore <destination> numkeys <key> [<key>] 计算给定的一个或多个有序集的交集,并存储在新的 key 中
zunionstore <destination> numkeys <key> [<key>] 计算给定的一个或多个有序集的并集,并存储在新的 key 中
zscan <key> cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成员和元素分值)

FAQ

单个“Key”和“Value”数据大小

512 M512 M512 M!并非“1 G”。
  1. Key 的大小上限为 512 M
    • 建议 key 的大小不超过 1 KB,这样既节约存储空间,也利于 Redis 进行检索。
  2. String 类型的 value 值上限为 512 M
  3. 集合、链表、哈希等 key 类型,单个元素的 value 上限为 512 M
    • 事实上,集合、链表、哈希都可以看成由 String 类型的 key 按照一定的映射关系组合而成。

使用 Hash 的好处

应该尽量使用 Hash 哈希表而不是字符串键来缓存 Key-Value(“键-值对”)数据,优势为:方便管理、能够避免键名冲突、并且还能够节约内存。
  1. 将数据集中存放
    通过 Hash 哈希表,可以将一些相关的信息存储在同一个缓存 Key 键中,不仅方便了数据管理,还可以尽量避免误操作的发生。
  2. 避免键名冲突
    在介绍缓存 Key 的命名规范时,可以在命名键的时候,使用冒号分割符来避免命名冲突,但更好的避免冲突的办法是直接使用哈希键来存储“键-值对”数据。
  3. 减少 Key 键的内存占用
    在一般情况下,保存相同数量的“键-值对”信息,使用哈希键比使用字符串键更节约内存。
    • 因为 Redis 创建一个 Key 键都带有很多的附加管理信息(例如:这个 Key 键的类型、最后一次被访问的时间等),所以缓存的 Key 键越多,耗费的内存就越多,花在管理数据库 Key 键上的 CPU 也会越多