当前位置:网站首页>Redis的5中数据类型总结
Redis的5中数据类型总结
2022-08-02 14:20:00 【风吹起海棠】
这篇文章总结Redis的五种常用数据类型:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)
String(字符串)
string是redis最基本的类型,键值对类型,一个key对应value,最大能够容纳512MB
常用的命令:set、get、decr、incr、mget、mset
string的底层实现:string会采用SDS动态字符串进行存储,包含多种编码,包括raw、embstr、int。
①如果value为数字且长度小于20时,会采用int整形存储
②数据值为数字且长度大于20时,或者数据值为字符串且长度小于等于44时,采用embstr编码
③当字符串长度大于44时,将会使用raw编码
SDS详解:①SDS是基于c的结构体实现,包含了3个重要属性,int len、int free、char buf[]。len会记录当前字符串长度,free记录字符数组buf未使用的字节数,buf数组保存字符串的每一个字符。
②SDS的预分配策略:当最小需要分配的长度newlen小于1KB时,扩容为newlen + newlen(即最小需要长度的2倍);当最小需要分配的长度newlen大于1MB时,预分配长度 = newlen + 1MB
SDS的优势:
①SDS的预分配策略避免字符串的修改而频繁的进行扩容操作,减少内存重分配次数
②惰性空间释放:优化SDS的缩容操作,当要缩短SDS保存的字符串时,程序不会立刻进行内存重分配回收内存,而是通过free属性记录缩容后释放的字节数量,以便后续使用
③避免缓冲区溢出:c不会记录字符串长度,相邻字符就容易产生缓冲溢出。SDS在添加时会检查长度是否足够,不足再进行扩容操作
④c语言中不会记录字符串的长度,因此获取字符串长度时需要进行遍历操作。而SDS通过len记录当前字符串长度,可以通过O(1)的时间复杂度获取字符串长度
Hash(哈希)
Hash非常适用存储对象类型的信息,hash支持对特定的某一项进行修改操作,Hash可以看作key-map的数据结构,map中包含多个键值对,可以支持对其中某个键值对的修改操作。如果采用string类型存放对象并要进行修改时,就需要先序列化这个对象,再将某个值修改后重新放入redis,会增大开销。
常用指令:
127.0.0.1:6379> hset myhash name ren age 18 sex 1 //创建一个hash元素,key为myhash
(integer) 3
127.0.0.1:6379> hget myhash name //获取hash中的某个field属性
"ren"
127.0.0.1:6379> hmget myhash name age sex //获取hash中多个field属性
1) "ren"
2) "18"
3) "1"
127.0.0.1:6379> hdel myhash sex //删除某个field属性
(integer) 1
127.0.0.1:6379> hget myhash sex
(nil)
127.0.0.1:6379> hlen myhash //获取field的个数
(integer) 2
127.0.0.1:6379> hsetnx myhash name 1 //hsetnx实现若该field存在则创建失败,不存在就创建
(integer) 0
127.0.0.1:6379> hsetnx myhash grade 196
(integer) 1
127.0.0.1:6379> hgetall myhash //获取hash中field中的所有key以及value
1) "name"
2) "ren"
3) "age"
4) "18"
5) "grade"
6) "196"
127.0.0.1:6379> hkeys myhash //获取hash中field的所有key
1) "name"
2) "age"
3) "grade"
127.0.0.1:6379> hvals myhash //获取hash中field中的所有value
1) "ren"
2) "18"
3) "196"
127.0.0.1:6379> hincrby myhash age 6 //将hash中的某个field的value增加6
(integer) 24
127.0.0.1:6379>
Hash使用的数据结构介绍:
Hash的实现包含两种数据结构:zipList和hashtable
(1)hashtable
hashtable即hash表,采用和hashMap一样的rehash(渐进式hash)进行重新的散列排布,涉及两个对象h[0]和h[1],元素最初再h[0]中,进行扩容或者缩容时会将h[0]中的元素迁移至h[1]中,扩容大小时h[0].used的两倍大的第一个2的幂,缩容为h[0].used的第一个大于等于2的整数幂。在rehash的过程中,会重新计算每个元素到新数组的下标,数据迁移完成后h[0]会被释放掉,h[1]成为新的h[1]。
每次进行更新、删除、查询操作时都会在h[0]和h[1]中进行,插入操作只会在h[1]中进行,因此h[0]的元素只减少不增,当h[0]没有元素是时,h[0]就会被释放掉
(2)zipList
zipList为压缩链表,本意不是指空间压缩,而是指一段连续的内存空间,可以充分利用内存空间,减少碎片化,它是经过特殊编码的双向链表,可提高存储内存,可以存储整数和字符串,提高时间复杂度为O(1)的push和pop操作。
使用场景:可用于保存对象类型的信息,可以基于hash实现购物车操作
List类型
list即列表类型,采用zipList和LinkedList两种数据结构,zipList之前已经介绍过,LinkedList为双向链表,每个节点都是一个zipList,支持Lpop,Lpush,Rpop,Rpush的相关操作,这些操作的时间复杂度都为O(1),但如果是查找某个元素,时间复杂度即为O(n)。可以基于list实现简单的队列
127.0.0.1:6379> rpush list 0 //右侧插入元素0
(integer) 1
127.0.0.1:6379> rpush list 1
(integer) 2
127.0.0.1:6379> rpush list 2 3 4 5 //右侧插入多个元素
(integer) 6
127.0.0.1:6379> lrange list 0 10 //获取某个索引区间的元素
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
127.0.0.1:6379> lset list 0 hello //给list的某个索引位重新赋值
OK
127.0.0.1:6379> lrange list 0 10
1) "hello"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
127.0.0.1:6379> llen
(error) ERR wrong number of arguments for 'llen' command
127.0.0.1:6379> llen list //获取list的长度
(integer) 6
127.0.0.1:6379> lpop list //删除左侧首元素
"hello"
127.0.0.1:6379> lrange list 0 10
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379>
Set类型
set集合实现元素的去重操作,元素无序排列,也可以实现两个集合并、差、交集的操作。
涉及的命令:
127.0.0.1:6379> sadd set1 hello world age name so lala //向set1中加入多个元素
(integer) 6
127.0.0.1:6379> smembers set1 //获取set1中的所有元素
1) "name"
2) "hello"
3) "world"
4) "age"
5) "so"
6) "lala"
127.0.0.1:6379> srem set1 name //移除set中的某个元素
(integer) 1
127.0.0.1:6379> smembers set1
1) "world"
2) "age"
3) "hello"
4) "so"
5) "lala"
127.0.0.1:6379> spop set1 1 //随机删除set中指定个数的元素
1) "age"
127.0.0.1:6379> srandmember set1 2 //随机获取set中指定个数的元素
1) "lala"
2) "so"
127.0.0.1:6379> sadd set2 hello lala pop push ola
(integer) 5
127.0.0.1:6379> sinter set1 set2 //多个set的交集
1) "hello"
2) "lala"
127.0.0.1:6379> sunio set1 set2
(error) ERR unknown command `sunio`, with args beginning with: `set1`, `set2`,
127.0.0.1:6379> sunion set1 set2 //多个set的并集
1) "hello"
2) "so"
3) "pop"
4) "lala"
5) "ola"
6) "push"
7) "world"
127.0.0.1:6379> sdiff set1 set2 //多个set的差集
1) "so"
2) "world"
127.0.0.1:6379> smove set1 age set2
(integer) 0
127.0.0.1:6379> smove set1 so set2
(integer) 0
127.0.0.1:6379> smembers set1
1) "hello"
2) "so"
3) "lala"
4) "world"
127.0.0.1:6379> smove set1 set2 so //将第一个set中的元素移动到另一个set集合
(integer) 1
127.0.0.1:6379> smembers set2
1) "hello"
2) "so"
3) "lala"
4) "pop"
5) "ola"
6) "push"
127.0.0.1:6379>
底层数据结构:
set底层实现包含hashtable和intset两种数据结构,inset叫做整形集合,存放整数型的元素
使用场景:可以实现共同好友,好友推荐、随机抽奖、去重
Zset类型:
和set一样可以实现元素去重,但多了一个属性score,可以基于score实现排序操作。
相关指令:
127.0.0.1:6379> zadd myset 0 hello 1 sex 2 name 3 age //向某个zset添加元素
(integer) 3
127.0.0.1:6379> zrange myset 0 1 //获取某个区间范围的元素,升序排列
1) "hello"
2) "sex"
127.0.0.1:6379> zrank myset hello //获取zset中某个元素的排序位置
(integer) 0
127.0.0.1:6379> zrangebyscore myset -inf +inf //根据score查询某个区间的元素
1) "hello"
2) "sex"
3) "world"
4) "name"
5) "soso"
6) "age"
7) "lala"
涉及数据结构:
包含两种数据结构zipList和skipList(跳跃表)
同时满足以下条件使用zipList:
①元素数量小于128
②元素长度都小于64字节
应用场景:排行榜、热帖
边栏推荐
猜你喜欢
随机推荐
lammps学习(一)单晶硅纳米磨削
Servlet 技术1
DOM —— 事件机制及事件链
makefile——library
JS本地存储(附实例)
Mysql索引优化二
一分钟之内搭建自己的直播服务器?
解决跨域问题的方法 --- JSONP
The DOM event type
[Fault Diagnosis] Weak Fault Diagnosis of Fan Bearing Based on PSO_VMD_MCKD Method
为什么 RTP 的视频的采样率是 90kHz ?
Explain in detail how the bit manipulation operators in C language can be used?
【数据知多少】一文学懂通过Tushare、AKshare、baostock、Ashare、Pytdx获取股票行情数据(含代码)
IDEA如何进行远程Debug
Golang学习(三十五) go 连接redis
这几年让你大呼惊人的AI应用,都离不开这项技术
时频分析之Wigner-Ville分布
网络运维系列:GoDaddy Shell DDNS配置
Based on the SVM regression forecast 】 【 LibSVM realize the prediction of a characteristic data
解决跨域的方法 --- Proxy