Redis String 类型操作及常用命令

Redis String 类型操作及常用命令

Scroll Down

七个原则

  1. Redis 是一个操作数据结构的语言工具,它提供基于 TCP 的协议以操作丰富的数据结构。在 Redis 中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身及这些操作的时间空间复杂度。
  2. Redis 定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis 能够有如此高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构, Redis 会尝试其它的存储方面的选择,但是永远不会改变它是一个内存数据库的角色。
  3. Redis 使用基础的 API 操作基础的数据结构, Redis 的 API 与数据结构一样,都是一些最基础的元素,你几乎可以将任何信息交互使用此 API 格式表示。作者调侃说,如果有其它非人类的智能生物存在,他们也能理解 Redis 的 API。因为它是如此的基础。
  4. Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》接上后四十回一样。
  5. Redis 始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
  6. Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操作。它们各有所长,但是我们不会推出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。
  7. 我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让 Redis 不好玩的开发模式。

String 类型及操作

String 是最简单的类型,一个 key 对应一个 value。

String 类型是二进制安全的。意思是 redis 的 String 可以包含任何数据, 比如 jpg 图片或者序列化的对象。 从内部实现来看其实 string 可以看作 byte 数组,最大上限是 1G 字节, 下面是 String 类型的定义:

struct sdshdr {
    long len;
    long free;
    char buf[];
};

len 是 buf 数组的长度。

free 是数组中剩余可用字节数, 由此可以理解为什么 string 类型是二进制安全的了, 因为它本质上就是个 byte 数组, 当然可以包含任何数据了。

buf 是个 char 数组用于存贮实际的字符串内容, 其实 char 和 c#中的 byte 是等价的,都是一个字节。

另外 string 类型可以被部分命令按 int 处理.比如 incr 等命令, 如果只用 String 类型, redis 就可以被看作加上持久化特性的 memcached。

常用命令及操作

set

设置 key 对应的值为 string 类型的 value。

例如:我们添加一个 name=Jacob 的键值对,可以这样做:

127.0.0.1:6379> set name Jacob
OK
setnx

设置 key 对应的值为 string 类型的 value。 如果 key 已经存在,返回 0, nx 是 not exist 的意思。

例如:我们添加一个 name=Jacob 的键值对,可以这样做:

127.0.0.1:6379> get name
"Jacob"
127.0.0.1:6379> setnx name Jacob
(integer) 0

由于原来 name 有一个对应的值,所以本次的修改不生效,且返回码是 0。

setex

设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期。
例如:我们添加一个 haircolor= red 的键值对,并指定它的有效期是 10 秒,可以这样做:

127.0.0.1:6379> setex color 10 red
OK
127.0.0.1:6379> get color
"red"
127.0.0.1:6379> get color
(nil)

可见由于最后一次的调用是 10 秒以后了,所以取不到 haicolor 这个键对应的值。

setrange

设置指定 key 的 value 值的子字符串。
例如我们希望将 HongWan 的 126 邮箱替换为 gmail 邮箱,那么我们可以这样做:

127.0.0.1:6379> setrange name 5 @jacob.com
(integer) 15
127.0.0.1:6379> get name
"Jacob@jacob.com"

其中的 8 是指从下标为 8(包含 8)的字符开始替换

mset

一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置。

127.0.0.1:6379> mset name1 Jacob1 name2 Jacob2
OK
127.0.0.1:6379> get name1
"Jacob1"
127.0.0.1:6379> get name2
"Jacob2"
msetnx

一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置, 但是不会覆盖已经存在的 key。

127.0.0.1:6379> get name1
"Jacob1"
127.0.0.1:6379> get name2
"Jacob2"
127.0.0.1:6379> msetnx name2 Jacob2 name3 Jacob3
(integer) 0
127.0.0.1:6379> get name2
"Jacob2"
127.0.0.1:6379> get name3
(nil)

可以看出如果这条命令返回 0,那么里面操作都会回滚,都不会被执行。(原子性)

get

获取 key 对应的 string 值,如果 key 不存在返回 nil。
例如我们获取一个库中存在的键 name,可以很快得到它对应的 value

127.0.0.1:6379> get name
"Jacob"
127.0.0.1:6379> get name3
(nil)

nil:表示无此键值对。

getset

设置 key 的值,并返回 key 的旧值。 如果 key 不存在,那么将返回 nil。

127.0.0.1:6379> get name
"Jacob@jacob.com"
127.0.0.1:6379> getset name Jacob_new
"Jacob@jacob.com"
127.0.0.1:6379> get name
"Jacob_new"
127.0.0.1:6379> getset name4 Jacob4
(nil)
getrange

获取指定 key 的 value 值的子字符串。

127.0.0.1:6379> get name
"Jacob_new"
127.0.0.1:6379> getrange name 0 1
"Ja"

字符串左面下标是从 0 开始的。

127.0.0.1:6379> getrange name -3 -1
"new"

字符串右面下标是从-1 开始的。

127.0.0.1:6379> getrange name 6 10
"new"

当下标超出字符串长度时,将默认为是同方向的最大下标。

mget

一次获取多个 key 的值,如果对应 key 不存在,则对应返回 nil。

127.0.0.1:6379> mget name name2 name3
1) "Jacob_new"
2) "Jacob2"
3) (nil)

name3 由于没有这个键定义,所以返回 nil。

incr

对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误, incr 一个不存在的 key,则设置 key 为 1

127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incr age
(integer) 19
incrby

同 incr 类似,加指定值 , key 不存在时候会设置 key,并认为原来的 value 是 0

127.0.0.1:6379> get age
"19"
127.0.0.1:6379> incrby age 6
(integer) 25
decr

对 key 的值做的是减减操作, decr 一个不存在 key,则设置 key 为-1

127.0.0.1:6379> get age
"25"
127.0.0.1:6379> decr age
(integer) 24
127.0.0.1:6379> get age
"24"
decrby

同 decr,减指定值。

127.0.0.1:6379> get age
"24"
127.0.0.1:6379> decrby age 6
(integer) 18
127.0.0.1:6379> get age
"18"
append

给指定 key 的字符串值追加 value,返回新字符串值的长度。
例如:我们向 name 的值追加一个@126.com 字符串,那么可以这样做:

127.0.0.1:6379> append name @jacob.com
(integer) 19
127.0.0.1:6379> get name
"Jacob_new@jacob.com"
strlen

取指定 key 的 value 值的长度。

127.0.0.1:6379> get name
"Jacob_new@jacob.com"
127.0.0.1:6379> strlen name
(integer) 19

hashes 类型及操作