redis数据类型简介

本教程的主体内容是python如何操作redis,可假如没有一些redis数据库的知识,学习也就变得索然无味了。redis是当下最流行的key-value数据库,多用于缓存功能。虽然是单线程,可是性能极佳,很大原因在于数据都存储在内存中,你需要了解它能够存储和处理的数据类型。

本文只是对这些数据类型做简单的介绍,侧重于应用场景,每一种数据类型都有很多命令,本文不一一讲解,具体可参考redis教程

1. string

string 是redis中最简单,最基础的数据类型,还记得么,redsi是key-value数据库,所以,任何时候,你都要先去关心key是什么,然后再去关心value是什么,执行redis-cli,执行下面的命令

127.0.0.1:6379> set score 100
OK
127.0.0.1:6379> get score
"100"

score 是key, 100是value,这种一个key对应一个value的结构,是不是很像字典呢?这种数据结构是非常有用的,比如mysql里记录了学生的考试分数,很多人来你的网站上根据学生学号查询自己的考试分数,面对这些请求,你都要查询数据库么,这对mysql是一种负担。这种情况下,就可以将学生的学号和考试分数存入到redis,那么查询redis的速度自然是要比查询mysql快的多了

127.0.0.1:6379> set 001 99
OK
127.0.0.1:6379> set 002 98
OK
127.0.0.1:6379> get 001
"99"
127.0.0.1:6379> get 002
"98"
127.0.0.1:6379> mget 001 002
1) "99"
2) "98"

2. 哈希 hash

hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。前面讲string时所举的例子是用学生的学号做key,考试分数做value,这是一个比较单间的情况,学生考试,肯定是考了很多门的课程,那么分数也是很多,比如英语,物理,化学,咱们假设只有这三门学科,学生001 的分数分别是90, 87, 89 ,那么用string如何存储呢?

127.0.0.1:6379> set 001::physics 87
OK
127.0.0.1:6379> set 001::chemistry 89
OK
127.0.0.1:6379> get 001::english
"90"
127.0.0.1:6379> get 001::physics
"87"
127.0.0.1:6379> get 001::chemistry
"89"

为了存储一个学生的三门考试成绩,不得不设置3个key,这显然是太麻烦了,如果用hash,就让事情变得简单

127.0.0.1:6379> del 001
(integer) 1
127.0.0.1:6379> hmset 001 english 90 physics 87 chemistry 89
OK
127.0.0.1:6379> hmget 001 english
1) "90"
127.0.0.1:6379> hgetall 001
1) "english"
2) "90"
3) "physics"
4) "87"
5) "chemistry"
6) "89"

001 仍然是key,但是value是由多个key-value组成的,这样就可以将一个对象的所有信息都存储在一个key下。

3. list

list 是一个字符串列表,按照插入顺序排序,你可以用它来存储一个人的粉丝列表,也可以用它来做简单的消息队列。

127.0.0.1:6379> lpush fans 001 002 003 004 005 006
(integer) 6
127.0.0.1:6379> lrange fans 0 3
1) "006"
2) "005"
3) "004"
4) "003"
127.0.0.1:6379> lpop fans
"006"

lpush 是从左侧向队列里增加一个数据,lrange 根据索引范围返回数据,lpop 从左侧弹出一个数据。

使用list做消息队列,可以使用lpush从左侧压入数据,使用rpop从右侧弹出数据。

list 提供了lrange命令,可以返回指定索引范围内的数据,因此也可以用来做分页,比如app下载次数排行榜,翻页时,使用lrange要比关系型数据库的limit 操作快的多了,但这种用法只适用于更新不频繁的排行榜,实时计算的排行榜就不要用list了,可以考虑有序set。

4. set

redis里的set, 我们可以像理解python的set一样去理解它。

127.0.0.1:6379> sadd 001:friend 002 003 004
(integer) 3
127.0.0.1:6379> sadd 006:friend 002 003 005
(integer) 3
127.0.0.1:6379> sinter 001:friend 006:friend
1) "003"
2) "002"

001 的朋友有002, 003, 004 ,006 的朋友有002, 003 , 005 ,他们共同的好友是002, 003。你可能会对redis的set产生质疑,既然和python中的set一样,为啥不用python的set呢?

想想,你面对的是几百万的用户,这些人的好友定然存储在数据库中,比如mysql。你从mysql中查询出001和006的好友数据,再使用set存储他们,再做交集运算,这得耗费多少时间啊。如果用redis呢,好友数据就存储在set中,直接查询redis数据库就可以了,只需要一条简单的命令sinter,是不是比你自己实现这个功能要快捷的多呢?

5. sorted set

有序集合与集合相比,区别在于有序集合是排序的集合,它既有元素不重复的特性,也有有序的特性,这使得他非常适合做各种排行榜,比如游戏里按照比赛得分计算的排行榜,使用有序集合,要比其他任何方式都容易。

127.0.0.1:6379> zadd game 897 xiaoming
(integer) 1
127.0.0.1:6379> zadd game 900 xiaohong
(integer) 1
127.0.0.1:6379> zadd game 865 xiaogang
(integer) 1
127.0.0.1:6379> zadd game 903 xiaoli
(integer) 1
127.0.0.1:6379> zadd game 987 xiaozhang
(integer) 1

我向有序集合中加入了5个人的游戏分数,现在,我想获得前三名,就可以这样操作

127.0.0.1:6379> zrevrange game 0 2 withscores
1) "xiaozhang"
2) "987"
3) "xiaoli"
4) "903"
5) "xiaohong"
6) "900"

xiaoli(小丽)重新玩了一局,得了100分,程序应该向有序集合中加入新的分数

127.0.0.1:6379> zadd game  1000 xiaoli
(integer) 0
127.0.0.1:6379> zrevrange game 0 2 withscores
1) "xiaoli"
2) "1000"
3) "xiaozhang"
4) "987"
5) "xiaohong"
6) "900"

有序集合中的排名立刻发生变化。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案