Redis 字符串
Redis 字符串简介
Redis 字符串存储字节序列,包括文本、序列化对象和二进制数组。因此,字符串是你可以与 Redis 键关联的最简单的值类型。它们常用于缓存,但也支持附加功能,使你能够实现计数器并执行位操作。
由于 Redis 键是字符串,当我们也将字符串类型用作值时,我们实际上是在将一个字符串映射到另一个字符串。字符串数据类型对于许多用例都很有用,例如缓存 HTML 片段或页面。
> SET bike:1 Deimos
OK
> GET bike:1
"Deimos"
"""
Code samples for String doc pages:
https://redis.ac.cn/docs/latest/develop/data-types/strings/
"""
import redis
r = redis.Redis(decode_responses=True)
res1 = r.set("bike:1", "Deimos")
print(res1) # True
res2 = r.get("bike:1")
print(res2) # Deimos
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
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']
r.set("total_crashes", 0)
res7 = r.incr("total_crashes")
print(res7) # 1
res8 = r.incrby("total_crashes", 10)
print(res8) # 11
import assert from 'assert';
import { createClient } from 'redis';
const client = await createClient();
await client.connect();
const res1 = await client.set("bike:1", "Deimos");
console.log(res1); // OK
const res2 = await client.get("bike:1");
console.log(res2); // Deimos
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
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']
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
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.SetParams;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StringExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // Deimos
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
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]
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
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos
.toCompletableFuture();
setAndGet.join();
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
System.out.println(v); // >>> false (because key already exists)
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos (value is unchanged)
.toCompletableFuture();
setnx.join();
// set the value to "bike" if it already exists
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
.thenAccept(System.out::println) // >>> OK
.toCompletableFuture();
setxx.join();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
})
.thenAccept(System.out::println)
// >>> [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
// Vanth]]
.toCompletableFuture();
mset.join();
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
System.out.println(v); // >>> 1
return asyncCommands.incrby("total_crashes", 10);
})
.thenAccept(System.out::println) // >>> 11
.toCompletableFuture();
incrby.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import reactor.core.publisher.Mono;
import java.util.*;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
System.out.println(v); // OK
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos
}).then();
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
System.out.println(v); // false (because key already exists)
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos (value is unchanged)
}).then();
Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
System.out.println(res); // OK
}).then();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
}).then();
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
.doOnNext(v -> {
System.out.println(v); // 1
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
System.out.println(res); // 11
}).then();
Mono.when(setAndGet, setnx, setxx, mset, incrby).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_set_get() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_setnx_xx() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_mset() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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]
}
func ExampleClient_incr() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
public class StringSnippets
{
public void run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
var res1 = db.StringSet("bike:1", "Deimos");
Console.WriteLine(res1); // true
var res2 = db.StringGet("bike:1");
Console.WriteLine(res2); // Deimos
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
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);
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);
}
}
如你所见,使用 SET
和 GET
命令是设置和检索字符串值的方式。请注意,如果键已经存在,即使它与非字符串值关联,SET
命令也会替换键中存储的任何现有值。因此,SET
执行的是赋值操作。
值可以是任何类型的字符串(包括二进制数据),例如你可以在值中存储一个 jpeg 图像。一个值不能超过 512 MB。
SET
命令有一些有趣的选项,作为附加参数提供。例如,我可以要求 SET
在键已经存在时失败,或者相反,只在键已经存在时成功。
> set bike:1 bike nx
(nil)
> set bike:1 bike xx
OK
"""
Code samples for String doc pages:
https://redis.ac.cn/docs/latest/develop/data-types/strings/
"""
import redis
r = redis.Redis(decode_responses=True)
res1 = r.set("bike:1", "Deimos")
print(res1) # True
res2 = r.get("bike:1")
print(res2) # Deimos
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
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']
r.set("total_crashes", 0)
res7 = r.incr("total_crashes")
print(res7) # 1
res8 = r.incrby("total_crashes", 10)
print(res8) # 11
import assert from 'assert';
import { createClient } from 'redis';
const client = await createClient();
await client.connect();
const res1 = await client.set("bike:1", "Deimos");
console.log(res1); // OK
const res2 = await client.get("bike:1");
console.log(res2); // Deimos
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
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']
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
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.SetParams;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StringExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // Deimos
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
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]
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
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos
.toCompletableFuture();
setAndGet.join();
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
System.out.println(v); // >>> false (because key already exists)
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos (value is unchanged)
.toCompletableFuture();
setnx.join();
// set the value to "bike" if it already exists
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
.thenAccept(System.out::println) // >>> OK
.toCompletableFuture();
setxx.join();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
})
.thenAccept(System.out::println)
// >>> [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
// Vanth]]
.toCompletableFuture();
mset.join();
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
System.out.println(v); // >>> 1
return asyncCommands.incrby("total_crashes", 10);
})
.thenAccept(System.out::println) // >>> 11
.toCompletableFuture();
incrby.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import reactor.core.publisher.Mono;
import java.util.*;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
System.out.println(v); // OK
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos
}).then();
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
System.out.println(v); // false (because key already exists)
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos (value is unchanged)
}).then();
Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
System.out.println(res); // OK
}).then();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
}).then();
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
.doOnNext(v -> {
System.out.println(v); // 1
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
System.out.println(res); // 11
}).then();
Mono.when(setAndGet, setnx, setxx, mset, incrby).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_set_get() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_setnx_xx() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_mset() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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]
}
func ExampleClient_incr() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
public class StringSnippets
{
public void run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
var res1 = db.StringSet("bike:1", "Deimos");
Console.WriteLine(res1); // true
var res2 = db.StringGet("bike:1");
Console.WriteLine(res2); // Deimos
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
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);
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);
}
}
还有许多其他用于操作字符串的命令。例如,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"
"""
Code samples for String doc pages:
https://redis.ac.cn/docs/latest/develop/data-types/strings/
"""
import redis
r = redis.Redis(decode_responses=True)
res1 = r.set("bike:1", "Deimos")
print(res1) # True
res2 = r.get("bike:1")
print(res2) # Deimos
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
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']
r.set("total_crashes", 0)
res7 = r.incr("total_crashes")
print(res7) # 1
res8 = r.incrby("total_crashes", 10)
print(res8) # 11
import assert from 'assert';
import { createClient } from 'redis';
const client = await createClient();
await client.connect();
const res1 = await client.set("bike:1", "Deimos");
console.log(res1); // OK
const res2 = await client.get("bike:1");
console.log(res2); // Deimos
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
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']
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
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.SetParams;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StringExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // Deimos
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
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]
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
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos
.toCompletableFuture();
setAndGet.join();
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
System.out.println(v); // >>> false (because key already exists)
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos (value is unchanged)
.toCompletableFuture();
setnx.join();
// set the value to "bike" if it already exists
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
.thenAccept(System.out::println) // >>> OK
.toCompletableFuture();
setxx.join();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
})
.thenAccept(System.out::println)
// >>> [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
// Vanth]]
.toCompletableFuture();
mset.join();
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
System.out.println(v); // >>> 1
return asyncCommands.incrby("total_crashes", 10);
})
.thenAccept(System.out::println) // >>> 11
.toCompletableFuture();
incrby.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import reactor.core.publisher.Mono;
import java.util.*;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
System.out.println(v); // OK
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos
}).then();
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
System.out.println(v); // false (because key already exists)
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos (value is unchanged)
}).then();
Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
System.out.println(res); // OK
}).then();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
}).then();
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
.doOnNext(v -> {
System.out.println(v); // 1
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
System.out.println(res); // 11
}).then();
Mono.when(setAndGet, setnx, setxx, mset, incrby).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_set_get() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_setnx_xx() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_mset() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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]
}
func ExampleClient_incr() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
public class StringSnippets
{
public void run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
var res1 = db.StringSet("bike:1", "Deimos");
Console.WriteLine(res1); // true
var res2 = db.StringGet("bike:1");
Console.WriteLine(res2); // Deimos
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
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);
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);
}
}
使用 MGET
时,Redis 返回一个值的数组。
将字符串用作计数器
即使字符串是 Redis 的基本值,你也可以用它们执行一些有趣的操作。例如,其中之一是原子递增。
> set total_crashes 0
OK
> incr total_crashes
(integer) 1
> incrby total_crashes 10
(integer) 11
"""
Code samples for String doc pages:
https://redis.ac.cn/docs/latest/develop/data-types/strings/
"""
import redis
r = redis.Redis(decode_responses=True)
res1 = r.set("bike:1", "Deimos")
print(res1) # True
res2 = r.get("bike:1")
print(res2) # Deimos
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
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']
r.set("total_crashes", 0)
res7 = r.incr("total_crashes")
print(res7) # 1
res8 = r.incrby("total_crashes", 10)
print(res8) # 11
import assert from 'assert';
import { createClient } from 'redis';
const client = await createClient();
await client.connect();
const res1 = await client.set("bike:1", "Deimos");
console.log(res1); // OK
const res2 = await client.get("bike:1");
console.log(res2); // Deimos
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
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']
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
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.SetParams;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StringExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // Deimos
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
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]
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
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos
.toCompletableFuture();
setAndGet.join();
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
System.out.println(v); // >>> false (because key already exists)
return asyncCommands.get("bike:1");
})
.thenAccept(System.out::println) // >>> Deimos (value is unchanged)
.toCompletableFuture();
setnx.join();
// set the value to "bike" if it already exists
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
.thenAccept(System.out::println) // >>> OK
.toCompletableFuture();
setxx.join();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
System.out.println(v); // >>> OK
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
})
.thenAccept(System.out::println)
// >>> [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
// Vanth]]
.toCompletableFuture();
mset.join();
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
System.out.println(v); // >>> 1
return asyncCommands.incrby("total_crashes", 10);
})
.thenAccept(System.out::println) // >>> 11
.toCompletableFuture();
incrby.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import reactor.core.publisher.Mono;
import java.util.*;
public class StringExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
System.out.println(v); // OK
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos
}).then();
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
System.out.println(v); // false (because key already exists)
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
System.out.println(res); // Deimos (value is unchanged)
}).then();
Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
System.out.println(res); // OK
}).then();
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");
Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
}).then();
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
.doOnNext(v -> {
System.out.println(v); // 1
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
System.out.println(res); // 11
}).then();
Mono.when(setAndGet, setnx, setxx, mset, incrby).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_set_get() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_setnx_xx() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
func ExampleClient_mset() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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]
}
func ExampleClient_incr() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
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
}
public class StringSnippets
{
public void run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
var res1 = db.StringSet("bike:1", "Deimos");
Console.WriteLine(res1); // true
var res2 = db.StringGet("bike:1");
Console.WriteLine(res2); // Deimos
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
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);
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
命令将字符串值解析为整数,将其加一,然后将获得的值设置为新值。还有其他类似的命令,如 INCRBY
、DECR
和 DECRBY
。本质上它们是同一个命令,只是操作方式略有不同。
INCR
的原子性意味着什么?即使多个客户端对同一个键执行 INCR
命令,也永远不会发生竞态条件。例如,永远不会出现客户端 1 读取 "10",客户端 2 同时读取 "10",然后两者都递增到 11 并将新值设置为 11 的情况。最终值总是 12,并且在执行读取-递增-设置操作时,所有其他客户端都不会同时执行命令。
限制
默认情况下,单个 Redis 字符串的最大大小为 512 MB。
基本命令
获取和设置字符串
管理计数器
INCR
原子性地将给定键存储的计数器加 1。INCRBY
原子性地递增(传递负数时为递减)给定键存储的计数器。- 对于浮点计数器,存在另一个命令:
INCRBYFLOAT
。
位操作
要对字符串执行位操作,请参阅位图数据类型文档。
查看完整的字符串命令列表。
性能
大多数字符串操作是 O(1) 的,这意味着它们效率很高。但是,对于可能是 O(n) 的 SUBSTR
、GETRANGE
和 SETRANGE
命令要小心。这些随机访问字符串命令在处理大字符串时可能会导致性能问题。
替代方案
如果你将结构化数据存储为序列化字符串,你可能还需要考虑使用 Redis 哈希表或 JSON。
了解更多
- Redis Strings Explained 是一个简短、全面的关于 Redis 字符串的视频讲解。
- Redis University 的 RU101 课程详细介绍了 Redis 字符串。