Redis数据结构及命令详解

个人博客地址:
http://xiaohe-blog.top/

文章目录

  • 0. 简述
  • 1. 通用命令
    • 1.1 keys
    • 1.2 del
    • 1.3 type
    • 1.4 exists
    • 1.5 expire
    • 1.6 ttl
  • 2. string 类型
    • 2.1 set
    • 2.2 get
    • 2.3 mset
    • 2.4 mget
    • 2.5 setnx
    • 2.6 setex
    • 2.4 incr
    • 2.5 incrby
    • 2.6 incrbyfloat
  • 3. hash 类型
    • 3.1 hset
    • 3.2 hget
    • 3.3 hmset
    • 3.4 hmget
    • 3.5 hgetall
    • 3.6 hkeys
    • 3.7 hvals
    • 3.8 hincrby
  • 4. list 类型
    • 4.1 lpush
    • 4.2 lpop
    • 4.3 rpush
    • 4.4 rpop
    • 4.5 lrange
  • 5. set 类型
    • 5.1 sadd
    • 5.2 smembers
    • 5.3 srem
    • 5.4 scard
    • 5.5 sismember
  • 6. sortedset 类型
    • 6.1 zadd
    • 6.2 zrem
    • 6.3 zscrore
    • 6.4 zrank
    • 6.5 zcard
    • 6.6 zcount
    • 6.7 zrange

0. 简述

Redis有五种简单的数据类型,他们各自有各自的编码方式。

简单数据结构 名字
string 字符串
hash 哈希
list 列表
set 无序集合
zset 有序集合

1. 通用命令

1.1 keys

keys [pattern]

查看当前数据库的所有匹配模板[pattern]的键。

# 查看所有键,数据量高时不建议使用
keys *

# 查看以 name 结尾的键
keys *name

# 查看有 name 的键
keys *name*

1.2 del

del key

删除指定名字的键,可以指定多个名字。

如果没有这个值就不删,返回值为影响行数

# 删除名字是 name 的键
del name
# 删除名字是 name age password 的键
del name age password

1.3 type

获取一个key 的类型

type [key]

# 获取name的类型
type name
--> string

1.4 exists

exists key

判断一个键是否存在,可以一次性判断多个

返回值为存在的个数

# 判断 name 是否存在
exists name
# 判断 name age password 是否存在
exists name age password

1.5 expire

expire key seconds

给键设置有效期。

如果不存在,返回0

不能一次性设置多个

# 将 name 的有效期设置为60秒(name已存在)
expire name 60

1.6 ttl

ttl key

查看键的有效期。

正值:该键的有效期。

-1 :该键的有效期为永久。

-2 :该键不存在。

# 查看name的有效期
ttl name

2. string 类型

string 是最基本的key-value结构,key是唯一标识,value是内容。

虽说是字符串,但redis又将它细分为字符串、数字。

  • string:普通字符串。
  • int :整数,可以做自增、自减操作。
  • float :浮点数,可以做自增、自减操作。
key 类型 value
message string “hello redis~~”
age int “18”
money float “12.1”

不管是哪种类型,底层都是字节数组形式存储,只不过编码方式不同,字符串类型的最大空间不能超过512M。

Redis构建了一种结构体来完成存储字符串的功能:简单动态字符串Simple Dynamic String),简称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)]

2.1 set

set [key] [value]

添加一个string类型的键值对.

如果已有,则覆盖。

# 给 name 赋值 "小明"
# 加不加引号无所谓
set name xioaming
set name "xiaoming"

2.2 get

get [key]

获取键值对的值

# 获取 name 的值
get name

2.3 mset

mset [key value] [key value]...

批量新增键值对

# 新增name为xiaoming, age为19
mset name "xiaoming" age "19"

2.4 mget

mget [key]...

批量获取键值对的值

# 获取name age money 的值
mget name age money

2.5 setnx

setnx key value

set if not exists ,如果不存在,就新增;如果已存在就不新增。

# 如果不存在name,则插入
setnx name xiaoming

2.6 setex

setex key seconds value

setex key value seconds

新增键值对的同时指定有效期。

# 新增name xiaoming,指定时间为20s
setex name 20 "xiaoming"
setex name "xiaoming" 20

2.4 incr

incr key

使 int 类型的数自增一,返回值自增后的值.

不能用到string、float上。

# 让age自增1
incr age

2.5 incrby

incrby key number

指定int类型增长的步数。

# 让age自增3
incrby age 3

2.6 incrbyfloat

incrbyfloat key number

指定float类型增长的步数。

# 将money增长1.1
incrbyfloat money 1.1

3. hash 类型

Hash类型,也叫散列,其value是一个无需字典,类似于Java中的HashMap结构。

Hash类型分为key、value。value又包含一个键和一个值。

通用命令只能作用于整个hash结构,不能作用于一个hash结构的具体的键

例如expire只能指定整个hash结构的有效期,不能指定具体哪个值的有效期

Redis数据结构及命令详解_第1张图片

3.1 hset

添加一个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"
}

3.2 hget

获取一个hash类型的值

hget key field

# 获取user下的name值
hget user name

3.3 hmset

添加一个key的多个值

hmset key [field value] [field value]...

# 设置user 的name、age
hmset user name "xiaoming" age "19"

3.4 hmget

获取一个key的多个值

hmget key field...

# 获取user的name age
hmget user name age

3.5 hgetall

获取一个key中的所有field和value。

hgetall key

# 获取user的所有键和值
hgetall user

#输出:
 1)  "name"
 2)  "xiaoming"
 3)  "age"
 4)  "19"

3.6 hkeys

获取一个key的所有field

hkeys key

# 获取user的所有field
hkeys user

3.7 hvals

获取一个key的所有value

hvals user

# 获取user的所有value
hvals user

3.8 hincrby

让一个key的field的值指定步数增长。

hincrby key field number

# 让user 的age增长2
hincrby user age 2

4. list 类型

Redis中的List类型与Java中的LinkedList类似,可以看作是一个双向链表结构,既支持正向检索也支持反向检索。

特征:

  • 有序
  • 元素可以重复

image-20220922131625849

链表节点:

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;

4.1 lpush

在列表左侧插入一个或多个数据

lpush key element...

# 向names这个列表左侧先后插入xiaoming xiaohong
lpush names xiaoming xiaohong
# 插入后names的值: xiaohong xiaoming

4.2 lpop

移除并返回指定列表最左侧的元素,没有则返回nil

lpop key

# 返回&移除names最左侧的值
lpop names
# xiaoming

4.3 rpush

在列表右侧插入一个或多个元素

rpush key element...

# 在names最右侧插入xiaoming xiaohong
rpush names xiaoming xiaohong

4.4 rpop

移除并返回列表最右侧的元素,没有则返回nil

rpop key

# 返回并移除names最右侧的元素
rpop names

4.5 lrange

返回一定范围的所有元素

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"

5. set 类型

redis的set结构与Java中的HashSet类似,可以看作是一个value为null的HashMap。

特征:

  • 无序
  • 元素不可重复
  • 支持交集、并集、差集

5.1 sadd

向字典中添加一个或多个元素。

sadd key [element...]

# 向names中插入xiaohe xiaohe xiaoming  
# 由于无法重复,所以返回值为2
sadd names xiaohe xiaohe xiaoming

5.2 smembers

随机返回字典中所有的元素

这里的“随机”不是每一次返回顺序都不同,是返回的顺序与你插入的顺序不同,但是只要你不插入,返回的顺序是一样的。

smembers key

# 返回names中的所有元素
smembers names

5.3 srem

从字典中删除指定的一个或多个元素,返回值为影响行数。

srem key [element...]

# 从names中删除xiaohe xiaoming xiaowang
srem xiaohe xiaoming xiaowang

5.4 scard

返回字典中元素的个数。

scard key

# 返回names中的元素个数
scard names

5.5 sismember

判断一个元素是否存在于set中。返回值为0或1。

sismenber key member

# 判断xiaowang是否在names中
sismember names xiaowang

6. sortedset 类型

有序字典。每一个元素都带有一个score属性,可以基于score属性对元素进行排序,底层实现是skiplist + hash。

特点:

  • 可排序
  • 元素不重复

6.1 zadd

添加一个或多个元素到有序字典集,如果已存在就更新score值

zadd key score value

# 添加一个100分的name,值为xiaoming
zadd name 100 xiaoming

6.2 zrem

删除有序字典集的指定元素。

zrem key value

# 删除key为name,value为xiaoming的值。
zrem name xiaoming

6.3 zscrore

获取指定元素的score值。

zscore key value

# 获取指定key&&指定value的score值
zscore name xiaoming

6.4 zrank

获取指定元素的排名(排序为从小到大,起始为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

6.5 zcard

获取有序字典的元素个数

zcard key

# 获取name的元素个数
zcard name

6.6 zcount

获取score值在指定范围内的元素个数

zcount key min max

# 获取name的score在50-100的元素个数
zcount name 50 100

6.7 zrange

按照score排序后,获取指定排名范围的元素

zrange key min max

# 按照score排序后,获取第1-3个。(倒数第二到倒数第四)
zrange name 1 3
Redis数据结构及命令详解_第2张图片

你可能感兴趣的:(Redis,redis,数据结构,数据库)