Redis字符串简介
Redis字符串存储字节序列,包括文本、序列化对象和二进制数组。 因此,字符串是最基本的Redis数据类型。 它们通常用于缓存,但它们也支持额外的功能,让你实现计数器和执行位操作。
由于Redis的键是字符串,当我们也使用字符串类型作为值时,我们正在将一个字符串映射到另一个字符串。字符串数据类型很有用。适用于许多用例,例如缓存 HTML 片段或页面。
> SET bike:1 Deimos
OK
> GET bike:1
"Deimos"
var res1 = db.StringSet("bike:1", "Deimos");
Console.WriteLine(res1); // true
var res2 = db.StringGet("bike:1");
Console.WriteLine(res2); // Deimos
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // Deimos
res1 = r.set("bike:1", "Deimos")
print(res1) # True
res2 = r.get("bike:1")
print(res2) # Deimos
正如您所看到的,SET
和 GET
命令是我们设置和检索字符串值的方法。请注意,在键已经存在的情况下,即使键与非字符串值相关联,SET
也会替换已存储到键中的任何现有值。因此,SET
执行的是赋值。
值可以是各种字符串(包括二进制数据),例如,你可以在值中存储一张 jpeg 图像。值的大小不能超过 512 MB。
SET
命令有一些有趣的选项,可以作为附加参数提供。例如,我可以要求 SET
在键已经存在的情况下失败,或者相反,只在键已经存在的情况下成功:
> set bike:1 bike nx
(nil)
> set bike:1 bike xx
OK
var res3 = db.StringSet("bike:1", "bike", when: When.NotExists);
Console.WriteLine(res3); // false
Console.WriteLine(db.StringGet("bike:1"));
var res4 = db.StringSet("bike:1", "bike", when: When.Exists);
Console.WriteLine(res4); // true
Long res3 = jedis.setnx("bike:1", "bike");
System.out.println(res3); // 0 (because key already exists)
System.out.println(jedis.get("bike:1")); // Deimos (value is unchanged)
String res4 = jedis.set("bike:1", "bike", SetParams.setParams().xx()); // set the value to "bike" if it
// already
// exists
System.out.println(res4); // OK
res3 = r.set("bike:1", "bike", nx=True)
print(res3) # None
print(r.get("bike:1")) # Deimos
res4 = r.set("bike:1", "bike", xx=True)
print(res4) # True
还有许多其他用于操作字符串的命令。例如
GETSET
命令将键设置为新值,并将旧值作为结果返回。例如,如果你有一个系统,每当网站接收到一个新访客,就会使用 INCR
递增 Redis 的键值,你就可以使用这条命令。你可能希望每小时收集一次该信息,而不会丢失一次增量。你可以 GETSET
该键,将其赋值为新值“0”,然后读回旧值。
在一条命令中设置或检索多个键值的功能也有助于减少延迟。因此,有了 MSET
和 MGET
命令:
> mset bike:1 "Deimos" bike:2 "Ares" bike:3 "Vanth"
OK
> mget bike:1 bike:2 bike:3
1) "Deimos"
2) "Ares"
3) "Vanth"
var res5 = db.StringSet(new KeyValuePair<RedisKey, RedisValue>[]
{
new ("bike:1", "Deimos"), new("bike:2", "Ares"), new("bike:3", "Vanth")
});
Console.WriteLine(res5);
var res6 = db.StringGet(new RedisKey[] { "bike:1", "bike:2", "bike:3" });
Console.WriteLine(res6);
String res5 = jedis.mset("bike:1", "Deimos", "bike:2", "Ares", "bike:3", "Vanth");
System.out.println(res5); // OK
List<String> res6 = jedis.mget("bike:1", "bike:2", "bike:3");
System.out.println(res6); // [Deimos, Ares, Vanth]
res5 = r.mset({"bike:1": "Deimos", "bike:2": "Ares", "bike:3": "Vanth"})
print(res5) # True
res6 = r.mget(["bike:1", "bike:2", "bike:3"])
print(res6) # ['Deimos', 'Ares', 'Vanth']
当使用 MGET
时,Redis 返回一个值数组。
字符串作为计数器
即使字符串是 Redis 的基本值,你也可以对它们执行一些有趣的操作。例如,原子增量就是其中之一:
> set total_crashes 0
OK
> incr total_crashes
(integer) 1
> incrby total_crashes 10
(integer) 11
db.StringSet("total_crashes", 0);
var res7 = db.StringIncrement("total_crashes");
Console.WriteLine(res7); // 1
var res8 = db.StringIncrement("total_crashes", 10);
Console.WriteLine(res8);
jedis.set("total_crashes", "0");
Long res7 = jedis.incr("total_crashes");
System.out.println(res7); // 1
Long res8 = jedis.incrBy("total_crashes", 10);
System.out.println(res8); // 11
r.set("total_crashes", 0)
res7 = r.incr("total_crashes")
print(res7) # 1
res8 = r.incrby("total_crashes", 10)
print(res8) # 11
INCR
命令将字符串值解析为整数,
然后将其递增 1,最后将获得的值设置为新值。
还有其他类似的命令,例如 INCRBY
,
DECR
和 DECRBY
。从内部看,它们始终是同一条命令,只是执行方式略有不同。
INCR 原子性是什么意思?也就是说,即使多个客户端对同一键值发出 INCR,也不会出现竞争状态。例如,客户端 1 读取 "10",客户端 2 同时读取 "10",然后都递增到 11,并将新值设置为 11。最终值将始终是 12,而且在执行读取-递增-设置操作时,所有其他客户端不会同时执行命令。
限制
默认情况下,单个 Redis 字符串最大可为 512 MB。
基本命令
获取和设置字符串
SET
存储字符串值。
- 仅当键尚不存在时,
SETNX
才会存储字符串值。对于实现锁很有用。
GET
检索字符串值。
MGET
在单个操作中检索多个字符串值。
管理计数器
按位运算
要对字符串执行按位运算,请参阅位图数据类型文档。
请参阅字符串命令的完整列表。
大多数字符串操作都是 O(1),这意味着它们非常高效。
但是,请小心使用 SUBSTR
、GETRANGE
和 SETRANGE
命令,可以是 O(n)。
在处理大字符串时,这些随机访问字符串命令可能会导致性能问题。
备择方案
如果您将结构化数据存储为序列化字符串,您可能还需要考虑 Redis 哈希 或 JSON。
了解更多