Appearance
Redis 字符串
Redis 字符串简介
Redis 字符串存储字节序列,包括文本、序列化对象和二进制数组。 因此,字符串是您可以关联的最简单的值类型 一个 Redis 密钥。 它们通常用于缓存,但它们支持其他功能,这些功能允许您实现计数器并执行按位运算。
由于 Redis 键是字符串,因此当我们也使用字符串类型作为值时, 我们正在将一个字符串映射到另一个字符串。字符串数据类型很有用 适用于许多用例,例如缓存 HTML 片段或页面。
bash
> SET bike:1 Deimos
OK
> GET bike:1
"Deimos"
python
res1 = r.set("bike:1", "Deimos")
print(res1) # True
res2 = r.get("bike:1")
print(res2) # Deimos
js
const res1 = await client.set("bike:1", "Deimos");
console.log(res1); // OK
const res2 = await client.get("bike:1");
console.log(res2); // Deimos
java
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // Deimos
go
res1, err := rdb.Set(ctx, "bike:1", "Deimos", 0).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> OK
res2, err := rdb.Get(ctx, "bike:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> Deimos
csharp
var res1 = db.StringSet("bike:1", "Deimos");
Console.WriteLine(res1); // true
var res2 = db.StringGet("bike:1");
Console.WriteLine(res2); // Deimos
如您所见,使用 SET 和 GET 命令是我们设置 并检索字符串值的方式。请注意,SET 将替换任何现已经存储到 key 中的值,如果 key 已经存在,即使 键与非字符串值相关联。所以 SET 执行一个赋值。
值可以是各种字符串(包括二进制数据),例如 可以将 JPEG 图像存储在值中。值不能大于 512 MB。
SET 命令具有有趣的选项,这些选项作为附加选项提供 参数。例如,如果 key 已经存在,我可能会要求 SET 失败, 或者相反,它仅在 key 已存在时才会成功:
bash
> set bike:1 bike nx
(nil)
> set bike:1 bike xx
OK
python
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
js
const res3 = await client.set("bike:1", "bike", {'NX': true});
console.log(res3); // null
console.log(await client.get("bike:1")); // Deimos
const res4 = await client.set("bike:1", "bike", {'XX': true});
console.log(res4); // OK
java
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
go
res3, err := rdb.SetNX(ctx, "bike:1", "bike", 0).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> false
res4, err := rdb.Get(ctx, "bike:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> Deimos
res5, err := rdb.SetXX(ctx, "bike:1", "bike", 0).Result()
if err != nil {
panic(err)
}
fmt.Println(res5) // >>> OK
csharp
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
还有许多其他命令可用于对字符串进行操作。例如 GETSET
命令将键设置为新值,将旧值作为 结果。您可以使用此命令,例如,如果您有 系统,每次您的网站收到新访客时,都会使用 INCR
递增一个 Redis 密钥。你可能想要收集这个 信息,而不会丢失任何增量。 您可以 GETSET 键,为其分配新值 “0” 并读取 旧值返回。
能够在单个 命令对于减少延迟也很有用。因此,有 MSET
和 MGET
命令:
bash
> mset bike:1 "Deimos" bike:2 "Ares" bike:3 "Vanth"
OK
> mget bike:1 bike:2 bike:3
1) "Deimos"
2) "Ares"
3) "Vanth"
python
res5 = r.mset({"bike:1": "Deimos", "bike:2": "Ares", "bike:3": "Vanth"})
print(res5) # True
res6 = r.mget(["bike:1", "bike:2", "bike:3"])
js
const res5 = await client.mSet([
["bike:1", "Deimos"],
["bike:2", "Ares"],
["bike:3", "Vanth"]
]);
console.log(res5); // OK
const res6 = await client.mGet(["bike:1", "bike:2", "bike:3"]);
console.log(res6); // ['Deimos', 'Ares', 'Vanth']
java
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]
go
res6, err := rdb.MSet(ctx, "bike:1", "Deimos", "bike:2", "Ares", "bike:3", "Vanth").Result()
if err != nil {
panic(err)
}
fmt.Println(res6) // >>> OK
res7, err := rdb.MGet(ctx, "bike:1", "bike:2", "bike:3").Result()
if err != nil {
panic(err)
}
fmt.Println(res7) // >>> [Deimos Ares Vanth]
csharp
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);
使用 MGET 时,Redis 返回一个值数组。
字符串作为计数器
即使字符串是 Redis 的基本值,也有一些有趣的操作 你可以和他们一起表演。例如,一个是原子增量:
bash
> set total_crashes 0
OK
> incr total_crashes
(integer) 1
> incrby total_crashes 10
(integer) 11
python
r.set("total_crashes", 0)
res7 = r.incr("total_crashes")
print(res7) # 1
res8 = r.incrby("total_crashes", 10)
print(res8) # 11
js
await client.set("total_crashes", 0);
const res7 = await client.incr("total_crashes");
console.log(res7); // 1
const res8 = await client.incrBy("total_crashes", 10);
console.log(res8); // 11
java
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
go
res8, err := rdb.Set(ctx, "total_crashes", "0", 0).Result()
if err != nil {
panic(err)
}
fmt.Println(res8) // >>> OK
res9, err := rdb.Incr(ctx, "total_crashes").Result()
if err != nil {
panic(err)
}
fmt.Println(res9) // >>> 1
res10, err := rdb.IncrBy(ctx, "total_crashes", 10).Result()
if err != nil {
panic(err)
}
fmt.Println(res10) // >>> 11
csharp
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);
INCR
命令将字符串值解析为整数 将其递增 1,最后将获取的值设置为新值。 还有其他类似的命令,如 INCRBY
、DECR
和 DECRBY
。在内部,它是 总是相同的命令,但作用方式略有不同。
INCR 是原子的是什么意思? 甚至多个客户针对 同一键永远不会进入争用条件。例如,它永远不会 碰巧客户端 1 读取 “10”,客户端 2 同时读取 “10”,两者 increment 设置为 11,并将新值设置为 11。最终值将始终为 12 执行 read-increment-set 操作,而所有其他 客户端不会同时执行命令。
限制
默认情况下,单个 Redis 字符串的最大大小为 512 MB。
基本命令
获取和设置 String
SET
存储字符串值。SETNX
仅在键不存在时存储字符串值。用于实现锁。GET
检索字符串值。MGET
在单个操作中检索多个字符串值。
管理计数器
INCRBY
原子递增(并在传递负数时递减)存储在给定键处的计数器。- 存在另一个用于浮点计数器的命令:
INCRBYFLOAT
。
按位运算
要对字符串执行按位运算,请参阅 bitmaps 数据类型文档。
请参阅 string 命令的完整列表。
性能
大多数字符串操作都是 O(1),这意味着它们非常高效。 但是,请小心使用 SUBSTR
、GETRANGE
和 SETRANGE
命令,这些命令可以是 O(n)。 这些随机访问字符串命令在处理大型字符串时可能会导致性能问题。
选择
如果要将结构化数据存储为序列化字符串,则可能还需要考虑 Redis 哈希或 JSON。
了解更多信息
- Redis 字符串解释是关于 Redis 字符串的简短而全面的视频解释器。
- Redis 大学的 RU101 详细介绍了 Redis 字符串。