命令教程:https://www.runoob.com/redis/redis-tutorial.html
Redis是什么
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、key-value数据库,并提供多种语言的AIP。
1.Redis安装在磁盘。
2.Redis数据存储在内存。(首先存储在内存,如果要持久化则存在磁盘)
一、Redis基本通讯模型
执行过程:发送指令 -> 执行命令 -> 返回结果。
执行命令:单线程执行,所有命令进入队列,按顺序执行。
单线程快原因:纯内存访问,单线程避免线程切换和竞争产生资源消耗,RESP协议简单。
问题:如果某个命令执行慢,会造成其他命令的阻塞。
二、数据结构
字符串(String)
设置命令:
set age 23 ex 10 //10秒后过期 px10000毫秒过期。
setnx name test // 不存在键name时,返回1设置成功,并设置值;存在的话返回0。
获取命令:
get age //存在则返回value,不存在返回nil。
批量设置:mset key1 value1 key2 value2
批量获取:mget key1 key2 key3 //返回value1,value2,keys没值为nil。
计数命令:
incr age // 必须为整数自加1,非整数返回错误,无age键则从0自增返回1
decr age // 整数age减1
incrby age 2 //整数age + 2
decrby age 2 // 整数age - 2
incrbyfloat score 1.1 // 浮点型score + 1.1
字符串的追加:
append 追加指令:
set name hello;append name world // 追加后成helloworld
字符串长度:
set hello “世界” ; strlen hello //结果为6,每个中文占3个字节
截取字符串:
set name helloworld; getrange name 2 4 // 返回llo
哈希(hash)
哈希(hash)是一个string类型的field和value的映射表,hash特适合用于存储对象。
命令: hset key field value
设置:hset user:1 name bruce//成功返回1,失败返回0
取值:hget user:1 name //返回bruce
删值:hdel user:1 age //返回删除的个数
计算个数: hset user:1 name bruce;hset user:1 age 23;
hlen user:1 //返回2,user:1有两个属性值
批量设置:hmset user:2 name bruce age 23 sex boy //返回ok
批量取值:hmget user:2 name age sex //返回三行:bruce 23 boy
判断field是否存在:hexists user:2 name // 如存在返回1,不存在返回0
获取所有的field:hkeys user:2 //返回name age sex 三个field
获取user:2 所有value:hvals user:2 //返回bruce 23 boy
获取user:2所有field与value:hgetall user:2 //name bruce age 23 sex boy值
增加1:hincrby user:2 age 1 //age + 1
bincrbyfloat user:2 age 2 // 浮点型加2
列表(list)
用来存储多个有序的字符串,一个列表最多可以存2的32次方减1个元素。因为有序,可以通过索引下标获取元素或某个范围内元素列表,列表元素可以重复。
添加命令:
rpush bruce c b a //从右向左插入cba,返回值3
lrange bruce 0 -1 //从左到右获取列表所有元素 返回 c b a
lpush key c b a //从左向右插入 c b a
linsert bruce before b teacher //在b之前插入teacher,after为之后,使用lrange bruce 0 -1 查看:c teacher b a
查找命令:
lrange key start end //索引下标特点:从左到右为0到N-1
lindex bruce -1 //返回最右末尾a, -2为倒数第二位b
llen bruce //返回当前列表长度
lpop bruce //把最左边的第一个元素c删除
rpop bruce //把最右边的元素删除
集合(set)
用于标签,社交,查询有共同兴趣爱好的人,智能推荐。
保存多元素,与列表不一样的是不允许有重复元素,且集合是无序,一个集合最多可存2的32次方减1个元素,除了支持增删改查,还支持集合交集、并集、差集。
命令:
exists user //检查user健值是否存在
sadd user a b c //向user插入3个元素,返回3
sadd user a b //向user加入相同的元素,则重复无效,返回0
smembers user //获取user的所有元素,返回结果无序
srem user a //返回1,删除a元素
scard user // 返回2,计算元素个数
sdiff key1 key2 //返回第一个集合与其他集合之间的差异
sinter key1 key2 //返回给定所有集合的交集
spop key //移除并返回集合中的一个随机元素
有序集合(zset)
常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数与集合有联系,不能有重复的成员。
命令:
zadd key score member [score member…] //根据score排名
zadd user:zan 200 bruce //bruce点赞数第一
zadd user:zan 200 bruce 120 mike 100 li // 返回3
zadd test:1 nx 100 bruce //键test:1必须不存在,主要用于添加
zadd test:1 xx incr 200 bruce //键test:1必须存在,主要用于修改,此时为300
zadd test:1 xx ch incr -299 bruce //返回操作结果1,300-299=1
zrange test:1 0 -1 withsocres //查看点赞(分数)与成员名
zcard test:1 //计算成员个数
全局命令
1.查看所有键:
keys *
2.键总数:
dbsize // 如果存在大量键,线上禁止使用此指令
3.检查键是否存在:
exists key //不存在返回0,存在返回1
4.删除键:
del key //返回删除键的个数,删除不存在键返回0
5.键过期:
expire key seconds //设置过期时间 秒
ttl key // 查看剩余的过期时间
6.键的数据结构类型:
type key //type hello 返回string 键不存在返回none
redis数据库管理:
select 0 //有0-15 16个库,可以选择使用,默认使用0库
flushdb //删除当前的库
flushall //删除0-15所有的库
三种方案实现用户信息存储优缺点
1.原生:set user:1:name bruce;
set user:1:age 23
set user:1:sex boy
优点:简单直观,每个键对应一个值。
缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境。
2.将对象序列化存入redis
set user:1 serialize(userInfo)
优点:编程简单,若使用序列化合理内存使用率高。
缺点:序列化与反序列化有一定开销,更新属性时需要把userInfo全取出来进行反序列化,更新后再序列化到redis。
3.使用hash类型(推荐)
hmset user:1 name bruce age 23 sex boy
优点:简单直观,使用合理可减少内存空间消耗。
缺点:要控制ziplist与hashtable两种编码转换(一般不会有谁存一个value值大于512m吧~),且hashtable会消耗更多内存serialize(userInfo)。
排名场景:
zadd user:3 200 bruce 120mike 100 lee //先插入数据
zrange user:3 0 -1 withscores //查看分数与成员
zrank user:3 bruce //返回名次:第3名 返回2,从0开始到2
zrevrank user:3 bruce //返回0,反排序,点赞数越高,排名越前
应用场景:
排行系统,如视频网站需要对用户上传的视频做排行榜
点赞数:
zadd user:1:20210308 10 bruce //bruce 获得3个赞
再获一赞:
zincrby user:1:20210308 1 bruec // 在10的基础上加1
用户作弊,将用户从排行榜删除掉:
zrem user:1:20210308 bruce
展示赞数最多的五个用户:
zrevrangebyrank user:1:20210308 0 4
查看用户赞数与排名:
zscore user:1:20210308 bruce
zrank user:1:20210308 bruce