Подтвердить что ты не робот

Redis, как сохранить ассоциативный массив? Set или Hash или List?

Я немного запутался со всеми доступными вариантами хранения 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',
    )
);

Так что до сих пор я использовал тип 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 в другом списке, чтобы иметь возможность перебирать все сообщения?

Итак, мой вопрос в том, какие типы данных следует использовать для хранения моего списка сообщений, позволяя мне получать одну запись по ее идентификатору и перебирать все сообщения?

Спасибо, Maxime

4b9b3361

Ответ 1

Вы можете использовать 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

Чтобы получить один HASH:

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"

ПОЛУЧИТЬ ВСЕ ХАШКИ

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"

Если вы не хотите использовать сортировку, вы можете использовать Fetch Все имена ключей из SET с помощью SMEMBERS, а затем использовать Redis Pipeline для извлечения всех ключей

Ответ 2

Просто для людей, которые ищут 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);

Надеюсь, это поможет некоторым из вас;)

Ответ 3

В PHP вы можете просто сделать

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

Тогда

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

Или используйте любую технику сериализации, которую вы предпочитаете. Кодирование/декодирование JSON было достаточно для меня, чтобы не заботиться.