Redis如何存储关联数组?设置或哈希还是列表?

max*_*022 28 associative-array redis phpredis

我对Redis的所有可用存储选项感到困惑.我想做一些简单的事情,我不想过度设计它.我正phpredis和我一起工作Redis v2.8.6.

我有这个简单的关联数组,我需要存储.我还需要能够通过其键检索项目并循环遍历所有项目.

$a = array(
    '12345' => array(
        'name' => 'Post A',
        'val2' => 'blah blah',
        'val3' => 'blah blah blah',
    ),
    '54321' => array(
        'name' => 'Post B',
        'val2' => 'blah blah',
        'val3' => 'blah blah blah',
    ),
    '998877' => array(
        'name' => 'Post C',
        'val2' => 'blah blah',
        'val3' => 'blah blah blah',
    )
);
Run Code Online (Sandbox Code Playgroud)

所以我到现在所做的是使用hash类型.像这样存储我的数组:

foreach ($a as $key => $value) {
    $this->redis->hSet('posts', $key, json_encode($value));
}
Run Code Online (Sandbox Code Playgroud)

就像我可以轻松地像这样访问密钥:

public function getPost($postId)
{
    return json_decode($this->redis->hGet('posts', $postId), true);
}

// This is returning the information of Post A
$post = getPost(12345);
Run Code Online (Sandbox Code Playgroud)

但现在我需要遍历所有帖子,我不知道如何做,如果我可以用我目前的结构.我不知道是否需要将所有内容存储post_id在另一个列表中以便能够遍历所有帖子?

所以我的问题是我应该使用哪些数据类型来存储我的帖子列表,允许我通过其id获取单个帖子并循环遍历所有帖子?

谢谢,Maxime

Jac*_*l's 26

您可以组合使用SET和Hash和SORT

redis 127.0.0.1:6379> HMSET TEST_12345 name "Post A" val2 "Blah Blah" val3 "Blah Blah Blah"
OK
redis 127.0.0.1:6379> HMSET TEST_54321 name "Post B" val2 "Blah Blah" val3 "Blah Blah Blah"
OK
redis 127.0.0.1:6379> HMSET TEST_998877 name "Post C" val2 "Blah Blah" val3 "Blah Blah Blah"
OK
redis 127.0.0.1:6379> SADD All_keys TEST_12345 TEST_54321 TEST_998877
(integer) 3
redis 127.0.0.1:6379> HGETALL TEST_12345
Run Code Online (Sandbox Code Playgroud)

要获得一个哈希:

redis 127.0.0.1:6379> HGETALL TEST_12345
1) "name"
2) "Post A"
3) "val2"
4) "Blah Blah"
5) "val3"
6) "Blah Blah Blah"
Run Code Online (Sandbox Code Playgroud)

获取所有HASH

redis 127.0.0.1:6379> SORT All_keys BY nosort GET *->name GET *->val2 GET *->val3
1) "Post A"
2) "Blah Blah"
3) "Blah Blah Blah"
4) "Post B"
5) "Blah Blah"
6) "Blah Blah Blah"
7) "Post C"
8) "Blah Blah"
9) "Blah Blah Blah"
Run Code Online (Sandbox Code Playgroud)

如果您不想使用sort,可以使用SMEMBERS从SET中获取所有键名,然后使用Redis Pipeline获取所有键


max*_*022 12

对于那些寻找PHP代码的人来说,这就是我最终使用的内容:

// Create a post hash
$key = 'post:'.$post->getId();
$this->redis->hSet($key, 'data', serialize($post->toArray()));

// Add a post in the account posts SET
$this->redis->sAdd($account->getId().':posts', $post->getId());

// You can execute the above code as many time as you need 
// to add an object in a SET

// Fetch the first $limit posts for this account
// SORT <account_id>:posts BY nosort GET <account_id>:post:*->data
$key = $account->getId().':posts';
$keys = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array($offset, $limit),
    'get' => 'post:*->data'
));

// All Good !
var_dump($keys);
Run Code Online (Sandbox Code Playgroud)

我希望这会对你们中的一些人有所帮助;)


Dar*_*ous 8

在PHP中你可以做到

$redis->set($key, json_encode($value));
Run Code Online (Sandbox Code Playgroud)

然后

$value = json_decode($redis->get($key));
Run Code Online (Sandbox Code Playgroud)

或者使用您喜欢的任何序列化技术.JSON编码/解码的性能足以让我不在乎.