■ 写在前面:
前面讲的基本的键值对操作,好处是方便,高效。但是,在某些应用中,比如把一个UID作为键,USER对象作为值存进去,USER对象内有大量属性(比如name,age等等),这时候如果要取其中的某条属性,就需要把整个USER对象取出来,看上去是十分浪费I/O的。
redis的散列类型(HASH)可以解决这个问题,只取出你想要的属性值,好处非常明显。坏处是,除了基本的键值对结构,其他结构(比如这个hash结构),都要redis多耗费一些CPU资源(凡事都有代价,时间换空间),虽然这种开销并不大。
■ Python操作redis的hash结构方法定义:
常用的操作方法:
1,hset(name, key, value) ---- 更新一条数据的属性,没有则新建
2,hget(name, key) ---- 读取这条数据的指定属性, 返回字符串类型
3,hmset(name, mapping) ---- 批量更新数据(没有则新建)属性
4,hmget(name, keys, *args) ---- 批量读取数据(没有则新建)属性
5,hgetall(name) ---- 获取这条数据的所有属性和对应的值,返回字典类型
6,hkeys(name) ---- 获取这条数据的所有属性名,返回列表类型
6,hdel(name, *keys) ---- 删除这条数据的指定属性
简单来说,hash操作,对比基本的键值对操作,只是多了一个必传的键名name而已。
■ 例子:
我们假设一个键名为 "123456" 的用户对象,具体结构为:
hash操作代码:
#! /usr/bin/env python
#coding=utf-8
import redis
r = redis.Redis(host="127.0.0.1", port=6379, db=0)
# 新建一条键名为"123456"的数据, 包含属性attr_1
r.hset("123456", "attr_1", 100)
# 更改键名为"123456"的数据, 更改属性attr_1的值
r.hset("123456", "attr_1", 200)
# 取出属性attr_1的值
attr_1 = r.hget("123456", "attr_1")
# 输出看一下(发现属性值已经为str)
print "-- get attr_1:", attr_1
# 属性集合
attr_dict = {
"name": "常成功",
"alias": "常城",
"sex": "male",
"height": 175,
"postal code": 100086,
"Tel": None,
}
# 批量添加属性
r.hmset("123456", attr_dict)
# 取出所有数据(返回值为字典)
h_data = r.hgetall("123456")
# 输出看一下(取出来的时候都变成了str)
print "-- get all attr:", h_data
# 删除属性(可以批量删除)
r.hdel("123456", "Tel")
# 取出所有属性名
h_keys = r.hkeys("123456")
print "-- get attr name:", h_keys
输出结果:
-- get attr_1: 200
-- get all attr: {'attr_1': '200', 'Tel': 'None', 'name': '\xe5\xb8\xb8\xe6\x88\x90\xe5\x8a\x9f', 'age': '1111111', 'height': '175', 'alias': '\xe5\xb8\xb8\xe5\x9f\x8e', 'postal code': '100086', 'sex': 'male'}
-- get attr name: ['name', 'postal code', 'alias', 'height', 'sex', 'age', 'attr_1']