理解Redis的几种数据结构

一、Redis数据库的优势

Redis是一个先进的Key-Value键值存储数据库,通常作为数据结构服务器。 


支持strings, hashes, lists, sets, sorted sets, bitmaps 和hyperloglogs


二、Redis数据结构

1、string - 字符串
Redis的字符串为SDS(Simple Dynamic String)可以存储任何东西,最大长度可达515兆。
#redis-cli.exe
127.0.0.1:6379> set name 'cbb'
OK
127.0.0.1:6379> get name
"cbb"
SDS的数据结构如下:
struct sdshdr {
// 记录 buf 数组中已使用字节的数量
// 等于 SDS 所保存字符串的长度
int len;
// 记录 buf 数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
};
常用命令:set, get
 
2,Hash - 哈希值

Redis的哈希值是字符串字段和字符串值之间的映射,所有它们被用来表示对象。
#redis-cli.exe
127.0.0.1:6379> HMSET user:1 username ccc password 123 age 20
OK
127.0.0.1:6379> HGETALL user:1 //取所有key
1> "username"
2> "ccc"
3> "passwrod"
4> "123"
5> "age"
6> "20"

127.0.0.1:6379> hget user:1 username //取一个key
"ccc"
上面的Hash数据类型,用于存储用户的基本信息,user:1是键。

hash解决了用户信息对象的存储:如用户ID为key,value为姓名name,年龄age,生日birthday等。 
用普通的key/value结构存储: 
a,set u001 “张三, 18, 20010101” 

这种方式的缺点是增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
b,mset user:001:name “李三” user:001:age 18 user:001:birthday “20010101” 
这种方法是用户信息对象有多少个成员就存成多少个key-value对儿,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费严重。

常用命令:hmset, hset, hget, hgetall 
3,List - 列表

列表是简单的字符串列表,排序插入顺序。可以添加元素到Redis列表的头部或尾部。
#redis-cli.exe
127.0.0.1:6379> lpush tutor redis
<integer> 1
127.0.0.1:6379> lpush tutor mongodb
<integer> 2
127.0.0.1:6379> lpush tutor rabitmq
<integer> 3
127.0.0.1:6379> lrange tutor 0 10
1> "rabitmq"
2> "mongodb"
3> "redis"
节点的定义:
typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void *value;
} listNode;
List的定义
typedef struct list {
// 表头节点
listNode *head;
// 表尾节点
listNode *tail;
// 链表所包含的节点数量
unsigned long len;
// 节点值复制函数
void *(*dup)(void *ptr);
// 节点值释放函数
void (*free)(void *ptr);
// 节点值对比函数
int (*match)(void *ptr, void *key);
} list;
补充:
 
  • 链表被广泛用于实现 Redis 的各种功能, 比如列表键, 发布与订阅, 慢查询, 监视器, 等等。
  • 因为链表表头节点的前置节点和表尾节点的后置节点都指向 NULL , 所以 Redis 的链表实现是无环链表。
  • 通过为链表设置不同的类型特定函数, Redis 的链表可以用于保存各种不同类型的值。


常用命令:lpush, rpush, lpop, rpop, lrange等 
4,Set - 集合

Set是字符串的无序集合。在Redis中可以添加、删除和测试值是否存在。
#redis-cli.exe
127.0.0.1:6379> sadd total 123
<integer> 1
127.0.0.1:6379> sadd total 234
<integer> 1
127.0.0.1:6379> sadd total 345
<integer> 1
127.0.0.1:6379> smembers total
1> "123"
2> "234"
3> "345"
常用命令:sadd, srem, spop, sdiff, smembers, sunion等
 
5,Sort Set - 有序集合

与Set类似,字符串不重复,但其是有序的 
常用命令:zadd, zrange,zrem,zcard等
 
6,Pub/Sub - 消息订阅

发布(Publish)和订阅(Subscribe)

~两客户端之间~ 
client1: 
QQ截图20180129142948.jpg

client2: 

QQ截图20180129143032.jpg


当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。 
这一功能最明显的用法是作为实时消息系统,比如普通的即时聊天,群聊等功能。

0 个评论

要回复文章请先登录注册