Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Cơ Sở Dữ Liệu

Làm chủ Redis Hashes: Fast, Flexible Data Storage

Hashes trong Redis là way store associated field-value pairs under a single key, nơi both field và values là strings. Redis allows modifications to both data structure as whole, và also to each field in structure. This makes it great (và very fast) backing store cho objects in an application.

CLI Examples

Create hash with two fields:

127.0.0.1:6379> HMSET my_hash key1 "foo" key2 "bar"
OK

List out fields và values associated with hash:

127.0.0.1:6379> HGETALL my_hash
1) "key1"
2) "foo"
3) "key2"
4) "bar"

Update value of one of the fields:

127.0.0.1:6379> HSET my_hash key1 "xyzzy"
(integer) 0
127.0.0.1:6379> HGET my_hash key1
"xyzzy"

Delete a single field from hash:

127.0.0.1:6379> HDEL my_hash key2
(integer) 1
127.0.0.1:6379> HGETALL my_hash
1) "key1"
2) "xyzzy"

Delete the hash:

127.0.0.1:6379> DEL my_hash
(integer) 1
127.0.0.1:6379> HGETALL my_hash
(empty list or set)

Redis's excellent documentation has more information about available commands for hashes. I won't copy/paste from there for you; instead, we're going to have a little fun with them.

Dwemthy's Array!

Dwemthy's Array là little example role playing game (RPG) written by Why the Lucky Stiff in Why's (poignant) guide to Ruby để explain Ruby metaprogramming. Here, we take same RPG idea, implement it using Redis hashes (with a little help from a Redis array).

Create hash for each monster in array, looking like this:

name: "AssistantViceTentacleAndOmbudsman"
life: 320
strength: 6
charisma: 144
weapon: 50

Example dive into depths of the array:

>>> import redis
>>> import dwemthy
>>> conn = redis.StrictRedis(host="localhost", port=6379)
>>> dw = dwemthy.Array.new(conn, {
  "name": "AssistantViceTentacleAndOmbudsman",
  "life": 320,
  "strength": 6,
  "charisma": 144,
  "weapon": 50
} )
"[Get ready. AssistantViceTentacleAndOmbudsman has emerged!]"
>>> rabbit = dwemthy.Rabbit(dw)
>>> rabbit.sword()
"[You hit with 2 points of damage!]"
"[Your enemy hit with 10 points of damage!]"
"[Rabbit has died!]"

Code as a whole, nếu bạn muốn follow along: dwemthy.py

Code Highlights

Firstly, khi user creates array với factory method provided, we'll setup data structures và return new dwemthy.Array object:

class Array(object):
  list_key = "dwemethys_array"
  ...
  @classmethod
  def new(cls, conn, *bad_guys):
    """ Create a new set of problems for our hero to boomerang! """
    conn.delete(cls.list_key)
    # Give each bad guy a cozy spot in the array!
    for bad_guy in bad_guys:
      key = uuid.uuid4()
      conn.hmset(key, bad_guy)
      conn.rpush(cls.list_key, key)
    dw_list = cls(conn)
    dw_list.next_enemy()
    return dw_list

conn.hmset here creates hash for bad guy. Once that happens, push bad guy's key into Redis list, used here as simple queue.

Khi all bad guys set up, make sure one at head of array ready với Array.next_enemy() method:

class Array(object):
  list_key = "dwemethys_array"
  ...
  def next_enemy(self):
    """ Bring out the next enemy for our rabbit to face! """
    # We're moving on!
    if self.current != None:
      self.conn.delete(self.current)
    enemy_key = self.conn.lpop(self.list_key)
    if enemy_key is None:
      # Like a boss!
      print "[Whoa. You decimated Dwemthy's List!]"
    else:
      # Get the new enemy ready!
      self.current = enemy_key
      print "[Get ready. {} has emerged!]".format(self["name"])

self["name"] on last line done by defining __setitem__ và __getitem__ methods on array object. This allows us treat array as mostly a python dict, và allows easy fetching và modifying fields on current bad guy:

class Array(object):
  ...
  def __setitem__(self, key, value):
    self.conn.hset(self.current, key, value)
  def __getitem__(self, key):
    value = self.conn.hget(self.current, key)
    # hashes only store strings!
    if key != "name":
      return int(value)
    return value

Conclusion

The myriad ways Redis allows us to modify hashes enables developers use it to solve a large set of problems. Hopefully this post given you ideas to use in your own projects.