Redis常用五大数据类型

 redis的数据结构

 redis存储的是:key,value格式的数据其中key都是字符串value有5种不同的数据结构

                 1、字符串类型 String
                 2、哈希类型 hash:map格式  (对象-属性)
                 3、列表类型 List :linkedlist格式(允许重复元素
                 4、集合类型 set(不允许重复元素
                 5、有序集合类型 sortedset(不允许重复元素,且会自动排序)

value值都是存的字符串类型的值

了解Redis五大数据类型之前我们先来了解一个Redis的键(key)

Redis键(key)

指令含义
keys *查看当前库中所有的key
exists key判断某个key是否存在,如exists k1
type key查看某个key是什么类型
del key删除指定的key 如del k1
unlink key根据value选择非阻塞删除 仅将keys从keyspace原数据中删除,真正删除会在后续异步操作。
expire key 100为给定的key设置过期时间,其中数值是秒单位过期后获取的数值是nil
ttl key查看还有多少秒过期  -1表示永不过期   -2 表示已过期    其他值就是多少秒后过期
select 数值切换数据库,默认是0号数据库
dbsize 查看当前数据库的key的数量
flushdb清空当前库
flushall通杀全部库

代码操作: 

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 Tom
OK
127.0.0.1:6379> set k2 Jason
OK
127.0.0.1:6379> set k3 jerry
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> expire k1 30
(integer) 1
127.0.0.1:6379> get k1
"Tom"
127.0.0.1:6379> get k1
"Tom"
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
127.0.0.1:6379> expire k2 60
(integer) 1
127.0.0.1:6379> ttl k2
(integer) 56
127.0.0.1:6379> exists k2
(integer) 1
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k4 12
OK
127.0.0.1:6379> keys *
1) "k4"
127.0.0.1:6379> exists k4
(integer) 1
127.0.0.1:6379> del k4
(integer) 1
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> set k5 8
OK
127.0.0.1:6379> dbsize
(integer) 1
127.0.0.1:6379> 

1、Redis字符串(String)

String是Redis最基本的类型,是一个key对应一个value。key一直都是字符串类型的,这个String类型是指value值的类型一个Redis中字符串value最多可以是512M

1.1、常用命令

命令含义解释
增操作set key value添加键值对,key不存在时直接添加入库,key存在时将之前的value覆盖
mset  <key1><value1><key2><value2>  .....同时设置 一个或多个key-value
msetnx key1 value1 key2 value2 key3 value3....同时设置一个或多个key和value,必须保证key不存在,设置中有一个存在就返回0(所有设置不成功)原子性,一个不成功就失败。
查操作get key查询对应键值,返回value值
mget key1 key2 key3 ....同时获取一个或多个key的value
getrange key start end获取key的value值的start到end下标的值,类似Java中substring
strlen key获取key的value值的长度,返回长度数值
改操作append key value给指定的key追加到key的原值的末尾,返回追加后的value的长度值
setnx key value只有在key不存在时设置key的value,返回1表示设置成功如果key存在就返回0,设置不成功
incr key将key中存储的 "数字值" 增1,如果为空,新增值为1   (将字符串值解析成整型,将其加一,最后将结果保存为新的字符串值)   返回增1的数字    (increase增加
incrby key 步长对key中存储的"数字值"自增自定的步长
decr key将key中存储的 "数字值" 减1,如果为空,新减值为-1   (将字符串值解析成整型,将其减一,最后将结果保存为新的字符串值)   返回减1的数字    (decrease 减少
decr key  步长对key中存储的"数字值"自减自定的步长
setrange key start value用value值覆盖key所存储的字符串值,从start索引开始
setex key <过期时间> value设置键的同时设置过期时间,单位是秒。

1.2、代码演示

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 123a
OK
127.0.0.1:6379> set k2 12345
OK
127.0.0.1:6379> get k1
"123a"
127.0.0.1:6379> get k2
"12345"
127.0.0.1:6379> append k1 bc
(integer) 6
127.0.0.1:6379> get k1
"123abc"
127.0.0.1:6379> strlen k2
(integer) 5
127.0.0.1:6379> get k2
"12345"
127.0.0.1:6379> setnx k1 111
(integer) 0
127.0.0.1:6379> setnx k3 aaa
(integer) 1
127.0.0.1:6379> get k1
"123abc"
127.0.0.1:6379> get k3
"aaa"
127.0.0.1:6379> get k1
"123abc"
127.0.0.1:6379> incr k1
(error) ERR value is not an integer or out of range
127.0.0.1:6379> incr k2
(integer) 12346
127.0.0.1:6379> get k2
"12346"
127.0.0.1:6379> incr k2 12
(error) ERR wrong number of arguments for 'incr' command
127.0.0.1:6379> incrby k2 12
(integer) 12358
127.0.0.1:6379> get k2
"12358"
127.0.0.1:6379> decr k2
(integer) 12357
127.0.0.1:6379> decrby k2 12
(integer) 12345
127.0.0.1:6379> get k2
"12345"
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
127.0.0.1:6379> mset k4 1234 k5 123456
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k5"
4) "k4"
127.0.0.1:6379> mget k1 k2 k3 k4 k5
1) (nil)
2) "345"
3) "12345"
4) "1234"
5) "123456"
127.0.0.1:6379> setrange k1 0 1123
(integer) 4
127.0.0.1:6379> get k1
"1123"
127.0.0.1:6379> setex k1 100 123
OK
127.0.0.1:6379> ttl k1
(integer) 95
127.0.0.1:6379> ttl k1
(integer) 93
127.0.0.1:6379> ttl k1
(integer) 91
127.0.0.1:6379> ttl k1
(integer) 76
127.0.0.1:6379> ttl k1
(integer) -2
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> 

1.3、 ​​​​​​数据结构

String的数据结构为简单动态字符串(Simple Dynamic String 简写SDS)就是可以修改字符串的值,内部结构实现类似Java的ArrayList,采用预分配冗余空间的方式。

如图内部为当前字符串实际分配的空间 capacity一般比实际字符串长度len高。当字符串长度小于1M时,扩容是加倍现有的空间,超过1M时扩容时一次多扩容1M的空间,但是字符串的最大长度为512M

2、Redis列表(List)

"单键多值",Redis列表是简单的字符串列表,按照插入顺序排序,可以添加一个元素在列表的头或者尾部。

它的底层实际是双向链表

2.1、常用命令

命令含义解释
lpush / rpush key value1 value2 value3 value4....从左边/右边插入一个或者多个值
linsert key before value newvalue 在value的左边插入一个newvalue值
 linsert key after value newvalue在value的右边插入一个newvalue值
lpop /  rpop key 从左边或者右边吐出一个值 (吐出来就从列表中删除
lrem key n value从左边删除n个value(从左到右列表中没有n个就删除列表中有多少(少于n)
rpoplpush key1 key2从key1列表中吐一个值,插到key2列表左边
lset key index value将列表key下标为index的值替换为value
lrange key start stop从列表key左到右获取元素(下标索引其中最右边的下标是-1 只是获取出来不会从列表中删除
lindex key 索引下标按照索引下标获取元素(从左到右
llen key获取列表长度

 2.2、代码演示

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush k1 v1 v2 v3 v4
(integer) 4
127.0.0.1:6379> rpush k1 1 2 3 4
(integer) 8
127.0.0.1:6379> lrange k1 0 -1
1) "v4"
2) "v3"
3) "v2"
4) "v1"
5) "1"
6) "2"
7) "3"
8) "4"
127.0.0.1:6379> linsert k1 before v4 v5
(integer) 9
127.0.0.1:6379> lrange k1 0 -1
1) "v5"
2) "v4"
3) "v3"
4) "v2"
5) "v1"
6) "1"
7) "2"
8) "3"
9) "4"
127.0.0.1:6379> linsert k1 after v4 v_4
(integer) 10
127.0.0.1:6379> lrange k1 0 -1
 1) "v5"
 2) "v4"
 3) "v_4"
 4) "v3"
 5) "v2"
 6) "v1"
 7) "1"
 8) "2"
 9) "3"
10) "4"
127.0.0.1:6379> lpop k1 
"v5"
127.0.0.1:6379> lrange k1 0 -1
1) "v4"
2) "v_4"
3) "v3"
4) "v2"
5) "v1"
6) "1"
7) "2"
8) "3"
9) "4"
127.0.0.1:6379> rpop k1
"4"
127.0.0.1:6379> lrange k1 0 -1
1) "v4"
2) "v_4"
3) "v3"
4) "v2"
5) "v1"
6) "1"
7) "2"
8) "3"
127.0.0.1:6379> lrem k1 2 v4
(integer) 1
127.0.0.1:6379> lrange k1 0 -1
1) "v_4"
2) "v3"
3) "v2"
4) "v1"
5) "1"
6) "2"
7) "3"
127.0.0.1:6379> lindex k1 3
"v1"
127.0.0.1:6379> lindex k1 -1
"3"
127.0.0.1:6379> llen k1
(integer) 7
127.0.0.1:6379> lset k1 1 v_3
OK
127.0.0.1:6379> lrange k1 0 -1
1) "v_4"
2) "v_3"
3) "v2"
4) "v1"
5) "1"
6) "2"
7) "3"

 2.3、数据结构

List的数据结构为快速链表quickList。在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表。

它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成quicklist。

Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用

3、redis集合(set)

Redis set的功能类似List的功能,特殊之处可以自动排重,当需要存储一个列表数据,不可以重复的,可以考虑set,并且set中还可以判断某个成员是否在一个set集合中,List中没有的。

Redis的Set是String类型的无序集合,底层是value是null的哈希表添加、删除、查找的复杂度都是O(1)

3.1、常用命令

命令含义解释
sadd key1 value1 value2 value3 ....将一个或者多个member元素加到集合中,已经存在集合中的不会添加进去,被忽略。

 
srem key value1 value2 value3......删除集合中的某一个或者多个元素
spop key 或者 spop key n随机从改key集合中吐出一个值或者指定个数(会从集合中删除
移动smove key1 key2 value把集合key1中的value移到key2中,key1会把value移除,key2会添加上value(如果有就忽略)


 
smembers key取出集合key中的所有值,不会从集合中删除 
srandmember key n随机从集合key中取出n个值,不会从集合中删除
scard key返回集合key中的元素个数
判断sismember key value判断集合key是否含有value值,有就返回1,没有返回0
集合操作sinter key1 key2返回集合key1和key2的交集元素
sunion key1 key2返回集合key1和key2的并集元素
sdiff key1 key2返回集合key1和集合key2的差集元素(key1中的,但是不包括key2的

3.2、代码演示 

127.0.0.1:6379> sadd k1 1 2 3 4 5 a b c
(integer) 8
127.0.0.1:6379> sadd k2 1 2 3 adc 12
(integer) 5
127.0.0.1:6379> smembers k1
1) "4"
2) "a"
3) "5"
4) "c"
5) "b"
6) "1"
7) "2"
8) "3"
127.0.0.1:6379> smembers k2
1) "2"
2) "adc"
3) "3"
4) "1"
5) "12"
127.0.0.1:6379> srandmember  k1 3
1) "5"
2) "b"
3) "2"
127.0.0.1:6379> scard k2
(integer) 5
127.0.0.1:6379> sismember k2 22
(integer) 0
127.0.0.1:6379> sismember k2 adc
(integer) 1
127.0.0.1:6379> srem k2 1 2 3
(integer) 3
127.0.0.1:6379> spop k1 2
1) "b"
2) "4"
127.0.0.1:6379> smembers k1
1) "a"
2) "5"
3) "c"
4) "1"
5) "2"
6) "3"
127.0.0.1:6379> sinter k1 k2
(empty array)
127.0.0.1:6379> sunion k1 k2
1) "12"
2) "a"
3) "5"
4) "adc"
5) "c"
6) "1"
7) "2"
8) "3"
127.0.0.1:6379> sdiff k1 k2
1) "1"
2) "c"
3) "a"
4) "5"
5) "2"
6) "3"
127.0.0.1:6379> 

3.3、数据结构

Set数据结构是dict字典,字典是用哈希表实现的。

Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。

4、Redis哈希(hash)

Redis hash 是一个键值集合,是一个string类型的fieldvalue的映射表,hash特别适合用于存储对象。类似Java里面的Map<String,Object>

4.1、常用命令

命令含义解释
hset key field value给key集合的filed键赋值value
hmset key field1 value1 filed2 value2 .....批量给key集合的filed1,filed赋值value1,value2...
hsetnx key filed value 将哈希表中的域filed的值设置为value,当且仅当域的filed不存在
hget key field 从key集合中的field获取出value值
hvals key列出hash集合中的所有value
hexists key field 查看哈希表key中是否存在field
hkeys key列出hash集合的所有field
hincrby key field 步长为哈希表key中的域field的值加上增量 步长

4.2、代码演示

127.0.0.1:6379> hset user id 10001
(integer) 1
127.0.0.1:6379> hget user id
"10001"
127.0.0.1:6379> hset user name lisi
(integer) 1
127.0.0.1:6379> hget user name
"lisi"
127.0.0.1:6379> hmset student id 10001 name zs age 20 classId 182042
OK
127.0.0.1:6379> hget student age
"20"
127.0.0.1:6379> hkeys user
1) "id"
2) "name"
127.0.0.1:6379> clear

127.0.0.1:6379> keys *
1) "user"
2) "student"
127.0.0.1:6379> hkeys user
1) "id"
2) "name"
127.0.0.1:6379> hkeys student
1) "id"
2) "name"
3) "age"
4) "classId"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hset stu Stno 18204201
(integer) 1
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hset stu:10001 Stno 18204201
(integer) 1
127.0.0.1:6379> hmset stu:10001 Sname ycy age 20 sex 1
OK
127.0.0.1:6379> hsetnx stu:10001 Sname 123
(integer) 0
127.0.0.1:6379> hsetnx stu:10001 classId 182042
(integer) 1
127.0.0.1:6379> hget stu:10001 Sname
"ycy"
127.0.0.1:6379> hval stu:10001
(error) ERR unknown command `hval`, with args beginning with: `stu:10001`, 
127.0.0.1:6379> hvals stu:10001
1) "18204201"
2) "ycy"
3) "20"
4) "1"
5) "182042"
127.0.0.1:6379> hkeys stu:10001
1) "Stno"
2) "Sname"
3) "age"
4) "sex"
5) "classId"
127.0.0.1:6379> hincrby stu:10001 age 2
(integer) 22
127.0.0.1:6379> hget stu:10001 age
"22"
127.0.0.1:6379> 

4.3、数据结构

Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。

5、Redis有序集合Zset(sorted set)

Redis有序集合Zset与普通集合set非常相似,是一个没有重复元素的字符串的集合。

不同之处:有序集合的每一个成员都关联了一个评分score),这个评分被用来按照从最低分到最高分的方式排序集合中的成员,集合中的成员是唯一的,但是评分是可以重复的

元素是有序的,可以很快根据评分或者次序来获取一个范围的元素。

5.1、常用命令

命令含义解释
zadd key score1 value1 score2 value2.....将一个或者多个member元素及其score值加入到有序集key当中
zrange key start end [ withscores ]      (小到大排序)返回有序集合可以中,下表索引start end之间的元素  带上withscores 可以让分数和值一起返回结果集 (小到大排序)
zrevrange key start end [ withscores ]  (大到小排序)返回有序集合可以中,下表索引start end之间的元素  带上withscores 可以让分数和值一起返回结果集 (大到小排序
zrangebyscore key min max [ withscore] [ limit offset count ]返回有序集合key中,所有score在min和max之间(包括等于)次序排序(limit 下标  显示个数)  (小到大排序)
zrevrangebyscore key max min [ withscore ] [ limit offset count ]返回有序集合key中,所有score在min和max之间(包括等于)次序排序(limit 下标  显示个数) (大到小排序)
zcount key min max统计该集合分数区间内的元素个数
zrank key value返回该值在集合中的排名,从0开始的
zincrby key 步长 value为元素值为value的score加上步长
zrem key value 删除该集合下,指定值的元素

5.2、代码演示

127.0.0.1:6379> zadd top 500 java 200 C 300 python 400 C++ 600 php
(integer) 5
127.0.0.1:6379> zrange top 0 -1 withsocres
(error) ERR syntax error
127.0.0.1:6379> zrange top 0 -1 withscores
 1) "C"
 2) "200"
 3) "python"
 4) "300"
 5) "C++"
 6) "400"
 7) "java"
 8) "500"
 9) "php"
10) "600"
127.0.0.1:6379> zrange top 0 -1
1) "C"
2) "python"
3) "C++"
4) "java"
5) "php"
127.0.0.1:6379> zrangebyscore top 200 400 limit offset 4
(error) ERR value is not an integer or out of range
127.0.0.1:6379> zrangebyscore top 200 400 limit offset 2
(error) ERR value is not an integer or out of range
127.0.0.1:6379> zrangebyscore top 200 400
1) "C"
2) "python"
3) "C++"
127.0.0.1:6379> zrangebyscore top 200 400 limit 2
(error) ERR syntax error
127.0.0.1:6379> zrangebyscore top 200 400 limit offset 1
(error) ERR value is not an integer or out of range
127.0.0.1:6379> zrangebyscore top 200 400 limit offset 0
(error) ERR value is not an integer or out of range
127.0.0.1:6379> zrangebyscore top 200 400 limit 1 1
1) "python"
127.0.0.1:6379> zrangebyscore top 200 400 limit 0 1
1) "C"
127.0.0.1:6379> zrangebyscore top 200 400 limit 0 2
1) "C"
2) "python"
127.0.0.1:6379> zrevrange top 0 -1
1) "php"
2) "java"
3) "C++"
4) "python"
5) "C"
127.0.0.1:6379> zrevrange top 200 400
(empty array)
127.0.0.1:6379> zrevrange top 0 -1 limit 0 3
(error) ERR syntax error, LIMIT is only supported in combination with either BYSCORE or BYLEX
127.0.0.1:6379> zrevrange top 0 -1 withscores
 1) "php"
 2) "600"
 3) "java"
 4) "500"
 5) "C++"
 6) "400"
 7) "python"
 8) "300"
 9) "C"
10) "200"
127.0.0.1:6379> zrevrange top 0 -1 withscores limit 0 1
(error) ERR syntax error, LIMIT is only supported in combination with either BYSCORE or BYLEX
127.0.0.1:6379> zrangebyscore top 100 400 limit 0 1
1) "C"
127.0.0.1:6379> zrangebyscore top 100 600 limit 0 3
1) "C"
2) "python"
3) "C++"
127.0.0.1:6379> zrevrangebyscore top 600 400 limit 0 2
1) "php"
2) "java"
127.0.0.1:6379> zincrby top 100 java
"600"
127.0.0.1:6379> zrange top 0 -1 withscores
 1) "C"
 2) "200"
 3) "python"
 4) "300"
 5) "C++"
 6) "400"
 7) "java"
 8) "600"
 9) "php"
10) "600"
127.0.0.1:6379> zrank top java
(integer) 3

案例:如何利用zset实现一个文章访问量的排行榜? 

5.3、数据结构

它等价于Java的数据结构Map<String, Double>,可以给每一个元素value赋予一个权重score,

另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。

zset底层使用了两个数据结构

(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。

(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在TP5中,如果你想要使用Redis作为单例,并且使`__call`方法生效,你需要按照以下步骤进行操作: 1. 首先,确保你已经安装了Redis扩展,并在`config/database.php`文件中配置了Redis的连接信息。 2. 创建一个类,并将其作为Redis单例类,例如命名为`RedisSingleton`。 3. 在`RedisSingleton`类中定义一个静态属性,用于保存Redis连接实例。 4. 在`__construct`方法中,使用`self::$instance`来检查Redis连接实例是否已经存在,如果存在则直接返回该实例。 5. 如果Redis连接实例不存在,则可以通过`self::$instance = new Redis()`来创建一个新的Redis连接实例。 6. 最后,在`__call`方法中调用Redis实例的对应方法。 以下是一个示例代码: ```php use think\facade\Config; class RedisSingleton { private static $instance; private function __construct() { // 私有构造函数 } public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new Redis(); $config = Config::get('database.redis'); self::$instance->connect($config['host'], $config['port']); // 可根据需要设置其他 Redis 配置,如密码等 } return self::$instance; } public function __call($name, $arguments) { $redis = self::getInstance(); return call_user_func_array([$redis, $name], $arguments); } } // 使用示例 $redisSingleton = RedisSingleton::getInstance(); $redisSingleton->set('key', 'value'); // 调用 __call ``` 通过以上步骤,你可以在TP5中实现Redis单例模式,并且使`__call`方法生效。希望对你有所帮助!如果你有任何疑问,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值