个人博客地址:
http://xiaohe-blog.top/
Redis有五种简单的数据类型,他们各自有各自的编码方式。
简单数据结构 | 名字 |
---|---|
string |
字符串 |
hash |
哈希 |
list |
列表 |
set |
无序集合 |
zset |
有序集合 |
keys [pattern]
查看当前数据库的所有匹配模板[pattern]
的键。
# 查看所有键,数据量高时不建议使用
keys *
# 查看以 name 结尾的键
keys *name
# 查看有 name 的键
keys *name*
del key
删除指定名字的键,可以指定多个名字。
如果没有这个值就不删,返回值为影响行数
# 删除名字是 name 的键
del name
# 删除名字是 name age password 的键
del name age password
获取一个key 的类型
type [key]
# 获取name的类型
type name
--> string
exists key
判断一个键是否存在,可以一次性判断多个
返回值为存在的个数
# 判断 name 是否存在
exists name
# 判断 name age password 是否存在
exists name age password
expire key seconds
给键设置有效期。
如果不存在,返回0
不能一次性设置多个
# 将 name 的有效期设置为60秒(name已存在)
expire name 60
ttl key
查看键的有效期。
正值:该键的有效期。
-1 :该键的有效期为永久。
-2 :该键不存在。
# 查看name的有效期
ttl name
string 是最基本的key-value结构,key是唯一标识,value是内容。
虽说是字符串,但redis又将它细分为字符串、数字。
key | 类型 | value |
---|---|---|
message | string | “hello redis~~” |
age | int | “18” |
money | float | “12.1” |
不管是哪种类型,底层都是字节数组形式
存储,只不过编码方式
不同,字符串类型的最大空间不能超过512M。
Redis构建了一种结构体来完成存储字符串的功能:简单动态字符串
(S
imple D
ynamic S
tring),简称SDS。
struct __attribute__ ((__packed__)) sdshdr8{
//字节数组,用于存储string/int/float
char buf[];
//记录buf数组申请的总字节数,类型为:8位无符号整型。
// 不包括结束标志
uint8_t alloc;
//记录buf数组中已经使用的字节的数量,类型为:8位无符号整型。
// 不包括结束标志
uint8_t len;
// 此字段记录SDS的空间大小
// 因为存储空间不同,SDS类型也不同,有很多不同类型的SDS
unsigned char flags;
};
之所以被称为动态字符串,因为这个字符串有扩容机制:
扩容后
的空间小于1M :扩容后的空间大小乘以2+1扩容后
的空间大于1M :空间直接+1M+1# 扩容方案:
ni -> nihao
# 原空间:
len=2
alloc=2
# 扩容后:
len=5
alloc=10
# 为什么没有加一?
因为字符串后面有 '\0', 而这len和alloc两个字段都不计算结束标志。
但是alloc的类型是8位无符号整型,只能存储2^8数量级的char,太有限,所以Redis提供了不同类型的SDS,它们的其他特性都相同,只有alloc、len的类型不同,有5位、8位、16位、32位。
如何区分?使用 flag
这个字段。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K4RJkaK2-1671076295061)(https://typorehwf.oss-cn-chengdu.aliyuncs.com/image-20221212203840905.png)]
set [key] [value]
添加一个string类型的键值对.
如果已有,则覆盖。
# 给 name 赋值 "小明"
# 加不加引号无所谓
set name xioaming
set name "xiaoming"
get [key]
获取键值对的值
# 获取 name 的值
get name
mset [key value] [key value]...
批量新增键值对
# 新增name为xiaoming, age为19
mset name "xiaoming" age "19"
mget [key]...
批量获取键值对的值
# 获取name age money 的值
mget name age money
setnx key value
set if not exists ,如果不存在,就新增;如果已存在就不新增。
# 如果不存在name,则插入
setnx name xiaoming
setex key seconds value
setex key value seconds
新增键值对的同时指定有效期。
# 新增name xiaoming,指定时间为20s
setex name 20 "xiaoming"
setex name "xiaoming" 20
incr key
使 int 类型的数自增一,返回值自增后的值.
不能用到string、float上。
# 让age自增1
incr age
incrby key number
指定int类型增长的步数。
# 让age自增3
incrby age 3
incrbyfloat key number
指定float类型增长的步数。
# 将money增长1.1
incrbyfloat money 1.1
Hash类型,也叫散列,其value是一个无需字典,类似于Java中的HashMap结构。
Hash类型分为key、value。value又包含一个键和一个值。
通用命令只能作用于整个hash结构,不能作用于一个hash结构的具体的键
例如expire只能指定整个hash结构的有效期,不能指定具体哪个值的有效期
添加一个hash类型的值。
hset的key类型是hash,field和value类型都是string
hset key [field value]
# 添加一个user, name为xiaoming
hset user name "xiaoming"
# 给user 添加一个age:19
hset user age "19"
user:
{
"name": "xiaoming",
"age": "19"
}
获取一个hash类型的值
hget key field
# 获取user下的name值
hget user name
添加一个key的多个值
hmset key [field value] [field value]...
# 设置user 的name、age
hmset user name "xiaoming" age "19"
获取一个key的多个值
hmget key field...
# 获取user的name age
hmget user name age
获取一个key中的所有field和value。
hgetall key
# 获取user的所有键和值
hgetall user
#输出:
1) "name"
2) "xiaoming"
3) "age"
4) "19"
获取一个key的所有field
hkeys key
# 获取user的所有field
hkeys user
获取一个key的所有value
hvals user
# 获取user的所有value
hvals user
让一个key的field的值指定步数增长。
hincrby key field number
# 让user 的age增长2
hincrby user age 2
Redis中的List类型与Java中的LinkedList类似,可以看作是一个双向链表结构,既支持正向检索也支持反向检索。
特征:
链表节点:
typedef struct listNode{
//前置节点
struct listNode * prev;
//后置节点
struct listNode * next;
//节点的值
void * value;
};
链表:
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;
在列表左侧插入一个或多个数据
lpush key element...
# 向names这个列表左侧先后插入xiaoming xiaohong
lpush names xiaoming xiaohong
# 插入后names的值: xiaohong xiaoming
移除并返回指定列表最左侧的元素,没有则返回nil
lpop key
# 返回&移除names最左侧的值
lpop names
# xiaoming
在列表右侧插入一个或多个元素
rpush key element...
# 在names最右侧插入xiaoming xiaohong
rpush names xiaoming xiaohong
移除并返回列表最右侧的元素,没有则返回nil
rpop key
# 返回并移除names最右侧的元素
rpop names
返回一定范围的所有元素
lrange key [start end]
超出范围不会报错,有多少返回给你多少
如果想取出所有值,使用 0 -1
# 向numbers列表中存放1 2 3 4 5 6
rpush numbers 1 2 3 4 5 6
# 取出下标0-4的数:
lrange numbers 0 4
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
# 取出numbers列表的所有值
lrange numbers 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
redis的set结构与Java中的HashSet类似,可以看作是一个value为null的HashMap。
特征:
向字典中添加一个或多个元素。
sadd key [element...]
# 向names中插入xiaohe xiaohe xiaoming
# 由于无法重复,所以返回值为2
sadd names xiaohe xiaohe xiaoming
随机返回字典中所有的元素
这里的“随机”不是每一次返回顺序都不同,是返回的顺序与你插入的顺序不同,但是只要你不插入,返回的顺序是一样的。
smembers key
# 返回names中的所有元素
smembers names
从字典中删除指定的一个或多个元素,返回值为影响行数。
srem key [element...]
# 从names中删除xiaohe xiaoming xiaowang
srem xiaohe xiaoming xiaowang
返回字典中元素的个数。
scard key
# 返回names中的元素个数
scard names
判断一个元素是否存在于set中。返回值为0或1。
sismenber key member
# 判断xiaowang是否在names中
sismember names xiaowang
有序字典。每一个元素都带有一个score属性,可以基于score属性对元素进行排序,底层实现是skiplist + hash。
特点:
添加一个或多个元素到有序字典集,如果已存在就更新score值
zadd key score value
# 添加一个100分的name,值为xiaoming
zadd name 100 xiaoming
删除有序字典集的指定元素。
zrem key value
# 删除key为name,value为xiaoming的值。
zrem name xiaoming
获取指定元素的score值。
zscore key value
# 获取指定key&&指定value的score值
zscore name xiaoming
获取指定元素的排名(排序为从小到大,起始为0。故分数越小,排名数字越小)
zrank key value
# 获取xiaohe的排名
zadd name 100 xiaoming
zadd name 90 xiaohong
zadd name 80 xiaohe
排名为:
0) xiaohe
1) xiaohong
2) xiaoming
zrank name xiaohe
--> 0
获取有序字典的元素个数
zcard key
# 获取name的元素个数
zcard name
获取score值在指定范围内的元素个数
zcount key min max
# 获取name的score在50-100的元素个数
zcount name 50 100
按照score排序后,获取指定排名范围的元素
zrange key min max
# 按照score排序后,获取第1-3个。(倒数第二到倒数第四)
zrange name 1 3