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

时间:2014-02-24 23:17:59

标签: redis associative-array phpredis

我对Redis的所有可用存储选项感到困惑。 我想做一些简单的事情,我不想过度设计它。 我正在使用phpredisRedis 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',
    )
);

所以到目前为止我所做的是使用hash类型。像这样存储我的数组:

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

就像我可以像这样容易地访问密钥:

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

// This is returning the information of Post A
$post = getPost(12345);

但是现在我需要遍历所有帖子,我不知道该怎么做以及我是否可以使用我当前的结构。我不知道是否需要将所有post_id存储在另一个列表中以便能够遍历所有帖子?

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

谢谢, 马克西姆

3 个答案:

答案 0 :(得分:25)

您可以组合使用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

获取一个哈希:

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"

获取所有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"

如果您不想使用排序,可以使用 SMEMBERS 从SET获取所有键名,然后使用Redis管道获取所有键

答案 1 :(得分: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);

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

答案 2 :(得分:8)

在PHP中你可以做到

$redis->set($key, json_encode($value));

然后

$value = json_decode($redis->get($key));

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