Redis 数据类型

本文详细解读了Redis中的核心数据结构,包括字符串的灵活应用、列表的增删操作、集合的独特特性和哈希表的高效存储。通过实例演示了如何利用这些数据结构进行计数器、消息队列和对象缓存等操作,以及过期时间和原子性操作的实践。
摘要由CSDN通过智能技术生成

Redis对象

typedef struct redisObject{
    //类型
    unsigned type:4;
    //编码
    unsigned encoding:4;
    //指向底层数据结构的指针
    void *ptr;
    //引用计数
    int refcount;
    //记录最后一次被程序访问的时间
    unsigned lru:22;
}robj

type : 五大数据类型(字符串,列表,集合)
encoding:指的是每种数据结构存储的不同数据(例如字符串可以存储字符类型,也可以存储数值类型).也用来数据类型的不同实现方式(list的压缩列表实现和双端链表实现).
prt : 指向的是底层数据结构的物理存储地址

String(字符串)

定义

字符串,能保存任何类型的数据,包括二进制数据,最大512M(单个的key-value)

所有的key都是string类型,另外其他数据结构的构成元素也是字符串

127.0.0.1:6379> set key1 v1 # 设置值

127.0.0.1:6379> get key1    # 获取值
"v1"

127.0.0.1:6379> keys *      # 获取所有的key
1) "key1"
2) "views"

127.0.0.1:6379> exists key1 # 判断是否存在指定key
(integer) 1

127.0.0.1:6379> append key1 "appendcontent" #追加字符串
(integer) 20
127.0.0.1:6379> get key1
"v1helloappendcontent"

incr #+1
decr #-1
INCRBY views 10 # 对指定key+指定数量
DECRBY view 5 # 对指定key -指定数量

GETRANGE key1 0 3 # 截取字符串[0,3]的字符

SETRANGE key1 1 xxx # 从指定位置开始替换为 指定字符串

####################################################################################
# setex(set with expire) # 设置过期时间
# setnx(set if not exit) # 不存在设置

setex key3 30 "hellow" # 设置key3 的值喂hello,30秒之后过期
setnx mykey "redis" # 如果mykey不存在,创建mykey
setnx mykey "MongoDB" # 如果mykey存在,创建失败

####################################################################################
mset
mget

mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
mget ke1 k2 k3 #同时获取多个值
msetnx k1 v1 k4 v4 # 此操作是原子性操作,要莫一起成功,要莫一起失败

# 对象
# key设计方法: user:{id}:{field}, 可以使用这种方法在redis使用key
set user:1 {name:zhangsanm age:3} # 设置一个user:1 对象值喂json字符来保存一个对象
mset user:1:name zhangsan user:1:age 2

####################################################################################
getset # 先get然后再set

127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb
"redis"
127.0.0.1:6379> get db
"mongodb"

String类似的使用场景:value出了我们的字符串还可以是我们的数字

  1. 计数器
  2. 统计多单位的数量
  3. 粉丝数
  4. 对象缓存存储

List

定义

​ list:列表,简单的字符串列表,按照插入顺序排序

​ 可以头添加和尾添加,底层使用链表实现

​ 格式: lpush name value1 value2…

####################################################################################
127.0.0.1:6379> LPUSH list one # 将一个值或者多个值插入到list中
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1 # 获取list中的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> RPush list rightr # 将一个值或者多个值,插入到列表右(尾部)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1 # 通过区间获取具体的值
1) "three"
2) "two"
3) "one"
4) "rightr"
####################################################################################
LPOP
RPOP
Lindex

LPOP list # 移除list的左(头部数据)
RPOP list # 移除list的右(尾部数据)
Lindex list # 列出list长度
Lrem list two # 移除指定
ltrim mylist 1 2 # 通过下标截取指定的长度,list已经发生改变,截取了剩下的元素

消息排列,消息队列(Lpush Rpop)

hset

定义

​ ​ set:集合,无序,成员唯一

​ 格式: sadd name value1 value2…

####################################################################################
127.0.0.1:6379> sadd myset "hello" # set集合中添加元素

127.0.0.1:6379> smembers myset # 查看指定set的所有值

127.0.0.1:6379> sismember myset world # 查看set中是否存在key

127.0.0.1:6379> scard myset # 获取set集合内元素个数

127.0.0.1:6379>  srem myset hello # 移除元素中指定元素

127.0.0.1:6379> SRANDMEMBER myset
"guan"
####################################################################################
将一个指定的值,移动到另一个集合中
smove myset myset2 "hello" # 将一个指定的值,移动到另外一个set集合

####################################################################################

数字集合类

  1. 差集
  2. 交集
  3. 并集
SDIFF key1 key2 # 差集

SINTER key1 key2 # 交集

SUNION key1 key2 # 并集

Hash

Map集, key-map。hset是一个map集合, 本质和String没有太大的区别,是一个简单的key-value

哈希类型,是一个string类型的field和value的映射表(参考Map,name指的是数据类型的名称,下同)
​ 格式: hmset name key1 value1 key2 value2…

不能存储相同的元素

ypedef struct dictht{
    //哈希表数组
    dictEntry **table;
    //哈希表大小
    unsigned long size;
    //哈希表大小掩码,用于计算索引值 总是等于 size-1
    unsigned long sizemask;
    //该哈希表已有节点的数量
    unsigned long used;
}dictht;

typedef struct dictEntry{
    //键
    void *key;
    //值
    union{
        void *val;
        uint64_tu64;
        int64_ts64;
    }v;
    //指向下一个哈希表节点,形成链表,链地址法解决哈希冲突
    struct dictEntry *next;
}dictEntry;
收缩和扩容

二倍扩容/收缩.对每一个元素重新哈希后放入新的内存空间,然后将原内存空间释放.

​ 负载因子 = 哈希表大小/数组长度

​ 执行磁盘访问时(BGSAVE和BGREWRITEAOF),负载因子大于5才会扩容,否则大于1就会扩容.

127.0.0.1:6379> hset myhash field1 guan # set一个具体 key-value
(integer) 1
127.0.0.1:6379> hget myhash field1 # 获取一个字段值
"guan"
127.0.0.1:6379> hmset myhash field1 hello field2 world # set多个key -value
OK
127.0.0.1:6379> hmget myhash field1 field2 # 获取多个字段值
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash # 获取全部字段值
1) "field1"
2) "hello"
3) "field2"
4) "world"

Zset

定义

​ 有序集和,每一个value都对应一个score(double类型)用以排序

​ 格式: zadd name score1 value1 score2 value2…

​ zset的成员是唯一的,但分数(score)却可以重复

使用了跳表进行数据结构存储

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值