Redis学习笔记——基础命令(list、hash、set、zset)

list

双向链表实现,列表首尾操作(删除和增加)时间复杂度 O(1) ;查找中间元素时间复杂度为O(n) ;

列表中数据是否压缩的依据:

  • 元素长度小于 48,不压缩;

  • 元素压缩前后长度差不超过 8,不压缩;

基础命令
# 从队列的左侧入队一个或多个元素
LPUSH key value [value ...] 
# 从队列的左侧弹出一个元素 
LPOP key 
# 从队列的右侧入队一个或多个元素 
RPUSH key value [value ...]
# 从队列的右侧弹出一个元素 
RPOP key
# 返回从队列的 start 和 end 之间的元素 0, 1 2 
LRANGE key start end 
# 从存于 key 的列表里移除前 count 次出现的值为 value 的元素 
LREM key count value 
# 它是 RPOP 的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候阻塞连接  阻塞的是该命令所在的连接
BRPOP key timeout
存储结构
/* Minimum ziplist size in bytes for attempting compression. */ 
#define MIN_COMPRESS_BYTES 48 
/* quicklistNode is a 32 byte struct describing a ziplist for a quicklist. 
 * We use bit fields keep the quicklistNode at 32 bytes. 
 * count: 16 bits, max 65536 (max zl bytes is 65k, so max count actually < 32k).
 * encoding: 2 bits, RAW=1, LZF=2. 
 * container: 2 bits, NONE=1, ZIPLIST=2.
 * recompress: 1 bit, bool, true if node is temporary decompressed for usage. 
 * attempted_compress: 1 bit, boolean, used for verifying during testing. 
 * extra: 10 bits, free for future use; pads out the remainder of 32 bits */
typedef struct quicklistNode { 
    struct quicklistNode *prev; 
    struct quicklistNode *next; 
    unsigned char *zl; 
    unsigned int sz; /* ziplist size in bytes */ 
    unsigned int count : 16; /* count of items in ziplist */ 
    unsigned int encoding : 2; /* RAW==1 or LZF==2 */ 
    unsigned int container : 2; /* NONE==1 or ZIPLIST==2 */ 
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */ 
    unsigned int extra : 10; /* more bits to steal for future usage */ 
} quicklistNode; 
typedef struct quicklist { 
    quicklistNode *head; 
    quicklistNode *tail; 
    unsigned long count; /* total count of all entries in all ziplists */ 
    unsigned long len; /* number of quicklistNodes */ 
    int fill : QL_FILL_BITS; /* fill factor for individual nodes */ 
    unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */ 
    unsigned int bookmark_count: QL_BM_BITS; 
    quicklistBookmark bookmarks[]; 
} quicklist;
应用
栈(先进后出FILO)
LPUSH + LPOP # 或者 
RPUSH + RPOP
队列(先进先出FIFO)
LPUSH + RPOP 
# 或者 
RPUSH + LPOP
阻塞队列(blocking queue)
LPUSH + BRPOP 
# 或者 
RPUSH + BLPOP
#brpop为空的时候回阻塞,只阻塞brpop所在的连接
异步消息队列

获取固定窗口记录(redis里很多都用到了固定窗口来实现应用)

# 在某些业务场景下,需要获取固定数量的记录;比如获取最近50条战绩;这些记录需要按照插入的先 后顺序返回; 
lpush says 'xxxxx_1' 
lpush says 'xxxxx_2' 
lpush says 'xxxxx_3'
lpush says 'xxxxx_4' 
lpush says 'xxxxx_5'
lpush says 'xxxxx_6' 
# 裁剪最近5条记录 
ltrim says 0 4 
lrange says 0 -1

实际项目中需要保证命令的原子性,所以一般用 lua 脚本 或者使用 pipeline 命令;

-- redis lua脚本 
local record = KEYS[1] 
redis.call("LPUSH", "says", record) 
redis.call("LTRIM", "says", 0, 4)

hash

散列表,在很多高级语言当中包含这种数据结构;c++ unordered_map 通过 key 快速索引value;

基础命令
# 获取 key 对应 hash 中的 field 对应的值 
HGET key field 
# 设置 key 对应 hash 中的 field 对应的值 
HSET key field value 
# 设置多个hash键值对
HMSET key field1 value1 field2 value2 ... fieldn valuen 
# 获取多个field的值 
HMGET key field1 field2 ... fieldn 
# 给 key 对应 hash 中的 field 对应的值加一个整数值 
HINCRBY key field increment 
# 获取 key 对应的 hash 有多少个键值对 
HLEN key 
# 删除 key 对应的 hash 的键值对,该键为field
HDEL key field
存储结构

节点数量大于 512(hash-max-ziplist-entries) 或所有字符串长度大于 64(hash-max-ziplist value),则使用 dict 实现;

节点数量小于等于 512 且有一个字符串长度小于 64,则使用 ziplist 实现;

简单应用
存储对象
hmset hash:10001 name mark age 18 sex male 
# 与 string 比较 
set hash:10001 '{["name"]:"mark",["sex"]:"male",["age"]:18}' 
# 假设现在修改 mark的年龄为19岁 
# hash: 
hset hash:10001 age 19 
# string: 
	get role:10001 
	# 将得到的字符串调用json解密,取出字段,修改age值
	# 再调用json加密 
	set role:10001 '{["name"]:"mark",["sex"]:"male",["age"]:19}'
购物车
# 将用户id作为 key 
# 商品id作为 field 
# 商品数量作为 value 
# 注意:这些物品是按照我们添加顺序来显示的;
# 添加商品: 
hset MyCart:10001 40001 1 
lpush MyItem:10001 40001 
# 增加数量:
hincrby MyCart:10001 40001 1
hincrby MyCart:10001 40001 -1 // 减少数量1 
# 显示所有物品数量: 
hlen MyCart:10001 
# 删除商品: 
hdel MyCart:10001 40001
lrem MyItem:10001 1 40001 
# 获取所有物品: 
lrange MyItem:10001 
# 40001 40002 40003 
hget MyCart:10001 40001 
hget MyCart:10001 40002
hget MyCart:10001 40003

set

集合;用来存储唯一性字段,不要求有序;

基础命令
# 添加一个或多个指定的member元素到集合的 key中 
SADD key member [member ...] 
# 计算集合元素个数 
SCARD key 
# SMEMBERS key 
SMEMBERS key 
# 返回成员 member 是否是存储的集合 key的成员 
SISMEMBER key member 
# 随机返回key集合中的一个或者多个元素,不删除这些元素 
SRANDMEMBER key [count] 
# 从存储在key的集合中移除并返回一个或多个随机元素 
SPOP key [count] 
# 返回一个集合与给定集合的差集的元素 
SDIFF key [key ...] 
# 返回指定所有的集合的成员的交集 
SINTER key [key ...] 
# 返回给定的多个集合的并集中的所有成员 
SUNION key [key ...]
存储结构

元素都为整数且节点数量小于等于 512(set-max-intset-entries),则使用整数数组存储;

元素当中有一个不是整数或者节点数量大于 512,则使用字典存储

简单应用
抽奖
# 添加抽奖用户 
sadd Award:1 10001 10002 10003 10004 10005 10006
sadd Award:1 10009 
# 查看所有抽奖用户 
smembers Award:1 
# 抽取多名幸运用户 
srandmember Award:1 10   #抽10名,不够就全部显示
# 如果抽取一等奖1名,二等奖2名,三等奖3名,该如何操作?
共同关注
sadd follow:A aaa bbb ccc ddd eee 
sadd follow:C aaa bbb ccc 
sinter follow:A follow:C
推荐好友
sadd follow:A aaa bbb ccc ddd eee 
sadd follow:C aaa bbb ccc 
# C可能认识的人: 
sdiff follow:A follow:C 

zset

有序集合;可以用来实现排行榜等

基础命令
# 添加到键为key有序集合(sorted set)里面 
ZADD key [NX|XX] [CH] [INCR] score member [score member ...] 
# 从键为key有序集合中删除 member 的键值对 
ZREM key member [member ...] 
# 返回有序集key中,成员member的score值 
ZSCORE key member 
# 为有序集key的成员member的score值加上增量increment 
ZINCRBY key increment member
# 返回key的有序集元素个数 
ZCARD key
# 返回有序集key中成员member的排名 
ZRANK key member
# 返回存储在有序集合key中的指定范围的元素
ZRANGE key start stop [WITHSCORES] 
# 返回有序集key中,指定区间内的成员(逆序) 
ZREVRANGE key start stop [WITHSCORES]
存储结构

节点数量大于 128或者有一个字符串长度大于64,则使用跳表(skiplist);

节点数量小于等于128(zset-max-ziplist-entries)且所有字符串长度小于等于64(zset-max ziplist-value),则使用 ziplist 存储;

简单应用
搜索热榜
# 点击新闻:
zincrby hot:20210203 1 10001 
zincrby hot:20210203 1 10002
zincrby hot:20210203 1 10003 
zincrby hot:20210203 1 10004
zincrby hot:20210203 1 10005 
zincrby hot:20210203 1 10006 
zincrby hot:20210203 1 10007 
zincrby hot:20210203 1 10008 
zincrby hot:20210203 1 10009 
zincrby hot:20210203 1 10010 
# 获取排行榜: 
zrevrange hot:20210203 0 9 withscores
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值