高性能redis(三):基础数据结构

2,228 阅读7分钟

redis 有5种基础数据结构, 分别是 string, list, set, hash, zset

string (字符串)

string 表示的是一个可变的字节数组,数组里的单个元素是单个字符,字符串最大长度为512M

开始我们讲过了 redis 是 key-value 的开源数据库,所以在存储数据时,我们需要设置一个key,存储的数据内容为value

创建字符串 [set key value]

> set test hello-world
OK

获取字符串内容 [get key]

> get test
"hello-world"

上面说过string表示一个动态的字节数组,现在我们把一组字符串当成一个数组来看

获取字符串长度* [strlen key]

> strlen test
(integer) 11

截取部分字符串 [getrange key start end]

> getrange test 0 4
"hello"

覆盖字符串 [setrange key start value]

> setrange test 6 hi
> (integer) 11            // test: "hello-hirld"

追加字符串 [append key value]

> append test -end
(integer) 15             // test: "hello-hirld-end"

删除字符串 [del key]

> del test
(integer) 1

设置字符串过期时间 [expire key time]

时间单位为秒

> expire test 10    
(integer) 1

获取字符串剩余时间

> ttl test
(integer) 3

字符串运算 [incrby key value , decrby key value]

其中 incrby test 1 可写成 incr test , decrby test 1 写成 decr test

> set number 10
OK
> incrby number 10
(integer) 20
> decrby number 5
(integer) 15

list (列表)

list 的存储结构用的是双向链表,所以随机定位能力较弱,首尾插入删除能力较强

支持负下标 ,list 的下标可以用0, 1, 2, 3, ....表示, 也可以用-1, -2 表示倒数第一个和倒数第二个

链表可以从首尾追加和移除元素,可以将list 当做队列和堆栈使用

首尾追加移除 [rpush key value, lpush key value, rpop key, lpop value]

rpush 表示右边添加, lpush 表示左边添加, rpop, lpop 同理

> rpush list 01            // list: 01
(integer) 1
> rpush list 02            // list: 01 02
(integer) 2
> lpush list 03            // list: 03 01 02
(integer) 3

> lpop list                // list: 01 02
"03"
> rpop list                // list: 01
"02"

获取list长度 [llen key]

> llen list
(integer) 1

访问指定位置的元素 [lrange key startIndex endIndex]

> lrange list 0 2
1) "01"
2) "12"
3) "11"

> lrange list 0 -1        // 负下标
1) "01"
2) "12"
3) "11"

注意:endIndex 也可以用负下标表示,如上

修改指定元素 [lset key index value]

> lset list 0 13                  // before: 01  12  11
OK                                // after: 13  12  11

插入元素 [linsert key postion value newValue ]

注意: 这里的postion有两个值beforeafter, 分别表示插入在特定的value之前和之后

由于是根据具体的值来选择插入位置,由于list的变动,该值位置也在变化,所以运用场景很少

> linsert list before 12 12.5               // before: 13 12 11
(integer) 4                                 // after: 13 12.5 12 11

删除元素 [lrem key count value]

删除元素也是根据来删除的,这里相同的值可能不止一个 ,所以这里有个count的参数表示删除多少个元素

> lrem list 1 13                           // before: 13 13 12.5 12 11
(integer) 1								   // after: 13 12.5 12 11

定长列表 [ltrim key startIndex endIndex]

用于删除startIndexendIndex之外的列表元素,保留该范围内的元素。

常用于控制元素数量,如中奖人数

> ltrim list -3 -1                          // before: 1 2 3 4 5
OK											// after: 3 4 5

注意:列表的llen, lrange, lset命令是有规律的,比如获取字符串长度是str前缀的strlen, 所以这里获取list长度是以l为前缀的llen, len, range, set 表示操作的指令, l 是类型。其他同理请自行参照string类型的命令

set (集合)

集合里的元素是不能重复,因此可以用来去重,set 底层是一个特殊的 hash

添加元素 [sadd key value]

可以一次性添加一个或者多个元素

> sadd fruits apple banana pear
(integer) 2

获取所有元素 [smembers key]

> smembers fruits
1) "apple"
2) "banana"
3) "pear"

获取集合长度 [scard key]

> scard fruits
(integer) 3

随机获取元素 [srandmember key count]

该命令可以随机获取指定个数元素, 当命令后不指定个数时, 默认随机获取一个

> srandmember fruits
"pear"

> srandmember fruits 2
1) "apple"
2) "pear"

随机删除 [spop key count]

该命令可以随机删除指定个数元素, 当命令后不指定个数时, 默认随机删除一个

> spop fruits
"pear"

> spop fruits 2
1) "apple"
2) "banana"

判断元素是否存在 [sismember key value]

默认只能查询一个元素

 // 存在 apple
 > sismember fruits apple
(integer) 1

// 不存在 peach
> sismember fruits peach
(integer) 0

sortedset (有序集合)

sortedset

sortedset(zset) 给每一个元素value赋予一个权重 score,内部的元素会自动按照权重score进行排序,可以根据score范围获取元素,可以用来筛选名次

增加元素 [zadd key score value]

可以添加一个或者多个元素,示范如下:

// 添加一个元素
> zadd exam 60 Chinese
(integer) 1

// 添加多个元素
> zadd exam 90 math 70 english
(integer) 2

获取长度 [zcard key]

> zcard exam
(integer) 3

删除元素 [zrem key value]

可以删除一个或者多个元素

// 删除一个元素
> zrem exam math
(integer) 1

// 删除多个元素
> zrem exam Chinese english
(integer) 2

运算 [zincrby score key]

这里的元素和string 结构里的元素类似

> zincrby exam 1.5 math
"91.5"

获取权重 [zscore key value]

可以通过上面的命令查询指定 value 的权重

> zscore exam Chinese
"60"
> zscore exam english
"70"
> zscore exam math
"91.5"

排序 [zrank key value] [zrevrank key value]

zrank 是根据分数从小到大排序,返回的数值越大,所对应的value 权重越大,zrevrank 根据权重从大到小排序,返回的数值越大,权重越小

> zrank exam math
(integer) 2
> zrank exam english
(integer) 1
> zrank exam Chinese
(integer) 0


> zrevrank exam math
(integer) 0
> zrevrank exam english
(integer) 1
> zrevrank exam Chinese
(integer) 2

获取元素 [zrange key start end] [zrevrange key start end]

zrange 获取指定范围的元素按照从小到大的顺序 , zrevrange 获取指定范围的元素按照从大到小的顺序。加上 withscores 参数可以显示权重

// 获取所有元素
> zrange exam 0 -1
1) "Chinese"
2) "english"
3) "math"

// 从小到大
> zrange exam 0 -1 withscores
1) "Chinese"
2) "60"
3) "english"
4) "70"
5) "math"
6) "91.5"

// 从大到小
zrevrange exam 0 -1 withscores
1) "math"
2) "91.5"
3) "english"
4) "70"
5) "Chinese"
6) "60"

根据score范围获取元素 [zrangebyscore key start end] [zrevrangebyscore key start end]

参数-inf表示负无穷,+inf表示正无穷, withscores表示显示权重。

> zrangebyscore exam 70 90
1) "english"

> zrangebyscore exam 70 90 withscores
1) "english"
2) "70"

> zrevrangebyscore  exam 90 60 withscores
1) "english"
2) "70"
3) "Chinese"
4) "60"

> zrevrangebyscore  exam +inf -inf withscores
1) "math"
2) "91.5"
3) "english"
4) "70"
5) "Chinese"
6) "60"

注意:在使用zrevrangebyscore 命令时, 筛选范围也应该是 从大到小的,如上例 中的zrevrangebyscore exam 90 60 withscores

hash (哈希)

hash 类似Java语言的HashMap, Python 的dict 或者js 里的object

添加元素 [hset key field value | hmset field value ... field value]

hset 可以添加单个元素hmset 添加多个元素, 这里的field 类似于上述语言结构中的key

// 添加单个
> hset person name qiaoyu
(integer) 1

// 添加多个
> hmset person sex man age 23
OK

获取元素 [hset key field] [hmset key field1 field2]

hset根据对应的key 获取相应的元素, hmset根据对应的key 获取多个相应的元素,这里多出m 可以理解成many 的意思

> hget person name
"qiaoyu"

> hmget person name age sex
1) "qiaoyu"
2) "23"
3) "man"

获取所有的键值对 [hgetall key]

> hgetall person
1) "name"
2) "qiaoyu"
3) "age"
4) "23"
5) "sex"
6) "man"

获取所有的key [hkeys key]

> hkeys person
1) "name"
2) "age"
3) "sex"

获取所有的value [hvals]

> hvals person
1) "qiaoyu"
2) "23"
3) "man"

删除元素 [hdel key]

hdel 可以删除单个元素,也可以删除多个元素

// 删除单个元素
> hdel person name
(integer) 1

// 删除多个元素
> hdel person sex age
(integer) 2

判断元素是否存在 [**hexists ** key]

返回1表示存在, 0表示不存在

// 预先添加一个进行测试
> hset person name tom age 15
(integer) 1

> hexists person name
(integer) 1

运算 [hincrby key field increment]

increment 表示添加的数值

> hincrby person age 2
(integer) 2