您的位置:首页 > 数据库 > Redis

Redis学习记录之命令String(八)

2016-01-12 13:49 537 查看
1、APPEND

APPEND key value

如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。

如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。

可用版本:

2.0.0及以上

返回值:

追加 value 之后, key 中字符串的长度。

对不存在的 key 执行 APPEND

redis> EXISTS myphone # 确保 myphone 不存在

(integer) 0

redis> APPEND myphone “nokia” # 对不存在的 key 进行 APPEND ,等同于 SET myphone “nokia”

(integer) 5 # 字符长度

对已存在的字符串进行 APPEND

redis> APPEND myphone ” - 1110” # 长度从 5 个字符增加到 12 个字符

(integer) 12

redis> GET myphone

“nokia - 1110”

模式:时间序列(Time series)

APPEND 可以为一系列定长(fixed-size)数据(sample)提供一种紧凑的表示方式,通常称之为时间序列。

每当一个新数据到达的时候,执行以下命令:

APPEND timeseries “fixed-size sample”

然后可以通过以下的方式访问时间序列的各项属性:

STRLEN 给出时间序列中数据的数量

GETRANGE 可以用于随机访问。只要有相关的时间信息的话,我们就可以在 Redis 2.6 中使用 Lua 脚本和 GETRANGE 命令实现二分查找。

SETRANGE 可以用于覆盖或修改已存在的的时间序列。

这个模式的唯一缺陷是我们只能增长时间序列,而不能对时间序列进行缩短,因为 Redis 目前还没有对字符串进行修剪(tirm)的命令,但是,不管怎么说,这个模式的储存方式还是可以节省下大量的空间。

可以考虑使用 UNIX 时间戳作为时间序列的键名,这样一来,可以避免单个 key 因为保存过大的时间序列而占用大量内存,另一方面,也可以节省下大量命名空间。

下面是一个时间序列的例子:

redis> APPEND ts “0043”

(integer) 4

redis> APPEND ts “0035”

(integer) 8

redis> GETRANGE ts 0 3

“0043”

redis> GETRANGE ts 4 7

“0035”

2、BITCOUNT

BITCOUNT key [start] [end]

计算给定字符串中,被设置为 1 的比特位的数量。

一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。

start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值: 比如 -1 表示最后一个字节, -2 表示倒数第二个字节,以此类推。

不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

可用版本:

2.6.0及以上

返回值:

被设置为 1 的位的数量。

redis> BITCOUNT bits

(integer) 0

redis> SETBIT bits 0 1 # 0001

(integer) 0

redis> BITCOUNT bits

(integer) 1

redis> SETBIT bits 3 1 # 1001

(integer) 0

redis> BITCOUNT bits

(integer) 2

模式:使用 bitmap 实现用户上线次数统计

Bitmap 对于一些特定类型的计算非常有效。

假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 SETBIT 和 BITCOUNT 来实现。

比如说,每当用户在某一天上线的时候,我们就使用 SETBIT ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的为设置为 1 。

举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。

当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。

性能

前面的上线次数统计例子,即使运行 10 年,占用的空间也只是每个用户 10*365 比特位(bit),也即是每个用户 456 字节。对于这种大小的数据来说, BITCOUNT 的处理速度就像 GET 和 INCR 这种 O(1) 复杂度的操作一样快。

如果你的 bitmap 数据非常大,那么可以考虑使用以下两种方法:

将一个大的 bitmap 分散到不同的 key 中,作为小的 bitmap 来处理。使用 Lua 脚本可以很方便地完成这一工作。

使用 BITCOUNT 的 start 和 end 参数,每次只对所需的部分位进行计算,将位的累积工作(accumulating)放到客户端进行,并且对结果进行缓存 (caching)。

3、BITOP

BITOP operation destkey key [key …]

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。

operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种:

BITOP AND destkey key [key …] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。

BITOP OR destkey key [key …] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。

BITOP XOR destkey key [key …] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。

BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey 。

除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。

处理不同长度的字符串

当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。

空的 key 也被看作是包含 0 的字符串序列。

可用版本:

2.6.0及以上

返回值:

保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。

BITOP 的复杂度为 O(N) ,当处理大型矩阵(matrix)或者进行大数据量的统计时,最好将任务指派到附属节点(slave)进行,避免阻塞主节点。

redis> SETBIT bits-1 0 1 # bits-1 = 1001

(integer) 0

redis> SETBIT bits-1 3 1

(integer) 0

redis> SETBIT bits-2 0 1 # bits-2 = 1011

(integer) 0

redis> SETBIT bits-2 1 1

(integer) 0

redis> SETBIT bits-2 3 1

(integer) 0

redis> BITOP AND and-result bits-1 bits-2

(integer) 1

redis> GETBIT and-result 0 # and-result = 1001

(integer) 1

redis> GETBIT and-result 1

(integer) 0

redis> GETBIT and-result 2

(integer) 0

redis> GETBIT and-result 3

(integer) 1

4、DECR

DECR key

将 key 中储存的数字值减一。

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。

如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

本操作的值限制在 64 位(bit)有符号数字表示之内。

关于递增(increment) / 递减(decrement)操作的更多信息,请参见 INCR 命令。

可用版本:

1.0.0及以上

返回值:

执行 DECR 命令之后 key 的值。

对存在的数字值 key 进行 DECR

redis> SET failure_times 10

OK

redis> DECR failure_times

(integer) 9

对不存在的 key 值进行 DECR

redis> EXISTS count

(integer) 0

redis> DECR count

(integer) -1

对存在但不是数值的 key 进行 DECR

redis> SET company YOUR_CODE_SUCKS.LLC

OK

redis> DECR company

(error) ERR value is not an integer or out of range

5、DECRBY

DECRBY key decrement

将 key 所储存的值减去减量 decrement 。

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。

如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

本操作的值限制在 64 位(bit)有符号数字表示之内。

关于更多递增(increment) / 递减(decrement)操作的更多信息,请参见 INCR 命令。

可用版本:

1.0.0及以上

返回值:

减去 decrement 之后, key 的值。

对已存在的 key 进行 DECRBY

redis> SET count 100

OK

redis> DECRBY count 20

(integer) 80

对不存在的 key 进行DECRBY

redis> EXISTS pages

(integer) 0

redis> DECRBY pages 10

(integer) -10

6、GET

GET key

返回 key 所关联的字符串值。

如果 key 不存在那么返回特殊值 nil 。

假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。

可用版本:

1.0.0及以上

返回值:

当 key 不存在时,返回 nil ,否则,返回 key 的值。

如果 key 不是字符串类型,那么返回一个错误。

对不存在的 key 或字符串类型 key 进行 GET

redis> GET db

(nil)

redis> SET db redis

OK

redis> GET db

“redis”

对不是字符串类型的 key 进行 GET

redis> DEL db

(integer) 1

redis> LPUSH db redis mongodb mysql

(integer) 3

redis> GET db

(error) ERR Operation against a key holding the wrong kind of value**重点内容**

7、GETBIT

GETBIT key offset

对 key 所储存的字符串值,获取指定偏移量上的位(bit)。

当 offset 比字符串值的长度大,或者 key 不存在时,返回 0 。

可用版本:

2.2.0及以上

返回值:

字符串值指定偏移量上的位(bit)。

对不存在的 key 或者不存在的 offset 进行 GETBIT, 返回 0

redis> EXISTS bit

(integer) 0

redis> GETBIT bit 10086

(integer) 0

对已存在的 offset 进行 GETBIT

redis> SETBIT bit 10086 1

(integer) 0

redis> GETBIT bit 10086

(integer) 1

8、GETRANGE

GETRANGE key start end

返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。

负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。

GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。

在 <= 2.0 的版本里,GETRANGE 被叫作 SUBSTR。

可用版本:

2.4.0及以上

返回值:

截取得出的子字符串。

redis> SET greeting “hello, my friend”

OK

redis> GETRANGE greeting 0 4 # 返回索引0-4的字符,包括4。

“hello”

redis> GETRANGE greeting -1 -5 # 不支持回绕操作

“”

redis> GETRANGE greeting -3 -1 # 负数索引

“end”

redis> GETRANGE greeting 0 -1 # 从第一个到最后一个

“hello, my friend”

redis> GETRANGE greeting 0 1008611 # 值域范围不超过实际字符串,超过部分自动被符略

“hello, my friend”

9、GETSET

GETSET key value

将给定 key 的值设为 value ,并返回 key 的旧值(old value)。

当 key 存在但不是字符串类型时,返回一个错误。

可用版本:

1.0.0及以上

返回值:

返回给定 key 的旧值。

当 key 没有旧值时,也即是, key 不存在时,返回 nil 。

redis> GETSET db mongodb # 没有旧值,返回 nil

(nil)

redis> GET db

“mongodb”

redis> GETSET db redis # 返回旧值 mongodb

“mongodb”

redis> GET db

“redis”

模式

GETSET 可以和 INCR 组合使用,实现一个有原子性(atomic)复位操作的计数器(counter)。

举例来说,每次当某个事件发生时,进程可能对一个名为 mycount 的 key 调用 INCR 操作,通常我们还要在一个原子时间内同时完成获得计数器的值和将计数器值复位为 0 两个操作。

可以用命令 GETSET mycounter 0 来实现这一目标。

redis> INCR mycount

(integer) 11

redis> GETSET mycount 0 # 一个原子内完成 GET mycount 和 SET mycount 0 操作

“11”

redis> GET mycount # 计数器被重置

“0”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: