2014-02-24 6 views
24

Ich bin ein wenig verwirrt mit allen verfügbaren Speicheroptionen von Redis. Ich möchte etwas Einfaches tun und ich möchte es nicht überentwickeln. Ich arbeite mit phpredis und Redis v2.8.6.Redis Wie speichert man assoziatives Array? Set oder Hash oder Liste?

Ich habe dieses einfache assoziative Array, das ich speichern muss. Ich muss auch in der Lage sein, einen Gegenstand durch seinen Schlüssel und Schleife über alle Einzelteile zu erreichen.

$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', 
    ) 
); 

Also was ich bis jetzt tat war mit hash Typ. meine Array wie folgt zu speichern:

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

Wie, dass ich den Schlüssel leicht wie folgt zugreifen können:

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

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

Aber jetzt brauche ich, weiß ich nicht zu Schleife über alle Beiträge, wie es geht und wenn ich es mit meiner jetzigen Struktur machen kann. Ich weiß nicht, ob ich alle post_id in einer anderen Liste speichern muss, um alle Posts durchlaufen zu können?

Also meine Frage ist, welche Datentypen sollte ich verwenden, um meine Liste der Beiträge zu speichern, so dass ich einen einzigen Beitrag durch seine ID abrufen und Schleife über alle Beiträge?

Danke, Maxime

Antwort

24

Sie können SET und Hash und SORT in Kombination

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 

ein HASH benutzen Sie:

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" 

Alle HASH GET

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" 

Wenn Sie nicht wollen, Art verwenden, können Sie die Schlüsselnamen Alle Fetch verwenden von SET mit SMEMBERS und dann Redis Pipeline verwenden, um alle Schlüssel zu holen

+1

Also gibt es keine anderen Lösungen als den Hash der 'Post' in einem' SET' zu speichern? Was sind die besten Optionen 'SORT' oder' SMEMBERS' wenn ich Millionen Einträge im 'SET' habe? – maxwell2022

+0

Wenn Sie zum Sortieren bemerken, verwende ich Nosort, also wird es nicht sortieren.Auch, Ideale Struktur nach mir ist HASH, Schlüssel-Wert-Paar zu halten, ich bin sicher, dass Sie Millionen von Werten auf einmal nicht holen werden, Sie werden nur wenige Lets sagen 50, dann können Sie Limit mit Sort verwenden. http://redis.io/commands/SORT –

+0

Was ist, wenn ich den gesamten Hash aus diesem Satz löschen möchte? Muss ich alle durchlaufen, um sie zu löschen? – maxwell2022

11

Gerade für die Leute, für die PHP-Suche Code, hier ist, was ich am Ende mit:

// 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); 

ich hoffe, das einige von euch helfen;)

+0

Sie sollten nach igbinary suchen: '$ igbinary = function_exists ('igbinary_serialize'); $ codiert = $ igbinary? igbinary_serialize ($ data): serialize ($ data); ' Es sollte etwas schneller sein als die reguläre Serialisierung. – Seb

6

In PHP können Sie einfach tun

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

Dann

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

Oder verwenden, was Serialisierungstechnik Sie bevorzugen. JSON encode/decode war so performant, dass ich mich nicht darum kümmern musste.

+1

Aber wenn Sie dies für Tausende von Ergebnissen tun müssen, würde es wahrscheinlich mehr Ressourcen als nötig verwenden. Die Verwendung einer Redis only-Lösung wird Sie weniger in Leistungsstörungen bringen. –

+0

@BobKruithof Ja, abso-verdammt-laut. Diese Antwort ist ein bisschen ein schmutziger Hack und ich schäme mich etwas dafür. Es funktionierte gut für das, was ich zu der Zeit tat. – Fuser97381

Verwandte Themen