0

【Redis 系列】redis 学习三,redis 数据结构之 string 和 list 基本使用及熟悉

 3 months ago
source link: https://segmentfault.com/a/1190000041291158
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is damaged, please click the button below to view the snapshot at that time.

redis 五大数据结构

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件

它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询

Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)

redis key 的基本命令

查看客户端是否连接成功

  • set key value

设置 key 和 value

  • get key

获取 key 的值

  • keys *

获取所有 key

  • move key 1

删除 key

  • expire key number

对 key 设置过期时间

  • ttl key

查看 key 的剩余有效时间

  • type key

查看 key 的类型

  • EXISTS key

查看是否存在 key

root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name xiaomotong
OK
127.0.0.1:6379> get name
"xiaomotong"
127.0.0.1:6379> type name
string
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXISTS xiaozhu
(integer) 0
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> set hobby sports
OK
127.0.0.1:6379> EXPIRE hobby 20
(integer) 1
127.0.0.1:6379> ttl hobby
(integer) 14
127.0.0.1:6379> ttl hobby
(integer) 13
127.0.0.1:6379> get hobby
(nil)
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379>

string 字符串

设置单个值

  • APPEND key value

在字符串后面追加字符串

  • STRLEN key

计算 key 对应 value 的长度

  • incr key

对 key 的值 +1

  • decr key

对 key 的值 -1

  • INCRBY key number

对 key +number

  • DECRBY key number

对 key -number

  • GETRANGE key start end

获取字符范围,获取 key 对应 value 的 第 start 到 end 的字符串

GETRANGE key 0 -1get key 是一个效果

  • setrange key offset value

替换 key 对应 value 从左到有 offset 个偏移量后面的字符串

127.0.0.1:6379> set name xiaozhu
OK
127.0.0.1:6379> get name
"xiaozhu"
127.0.0.1:6379> APPEND name xiaopang
(integer) 15
127.0.0.1:6379> get name
"xiaozhuxiaopang"
127.0.0.1:6379> STRLEN name
(integer) 15
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> incr views
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> incr views
(integer) 3
127.0.0.1:6379> decr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> INCRBY views 20
(integer) 22
127.0.0.1:6379> get views
"22"
127.0.0.1:6379> DECRBY views 10
(integer) 12
127.0.0.1:6379> get views
"12"
127.0.0.1:6379> set words "hello wrold"
OK
127.0.0.1:6379> GETRANGE words 2 5
"llo "
127.0.0.1:6379> set key1 xiaozhupeiqi
OK
127.0.0.1:6379> GETRANGE key1 0 -1
"xiaozhupeiqi"
127.0.0.1:6379>
127.0.0.1:6379> setrange key1 4 pangziyo
(integer) 12
127.0.0.1:6379> get key1
"xiaopangziyo"
  • setex key second value (set with expire)

设置 key 对应的过期时间 ,

  • ttl key

查看 key 的有效时间

  • setnx key value (if not exist)

如果 key 不存在,那就设置 , 这个指令通常用于分布式锁

127.0.0.1:6379> setex call 30 xiaomotong
OK
127.0.0.1:6379> ttl call
(integer) 24
127.0.0.1:6379> ttl call
(integer) 21
127.0.0.1:6379> setnx call xiaozhu
(integer) 1
127.0.0.1:6379> get call
"xiaozhu"
127.0.0.1:6379> setnx call xiaoming
(integer) 0
127.0.0.1:6379> get call
"xiaozhu"

批量设置多个值

  • mset key value [key value ...]

设置多个 key value

  • mget key [key ...]

获取多个 key 对应的值

  • MSETNX key value [key value ...]

设置多个值,如果 key 不存在,则设置值,这是一个原子操作,要么全部成功,要么全部失败

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 k4 v4
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k4"
3) "k3"
4) "k1"
127.0.0.1:6379> mget k1 k2 k3 k4
1) "v1"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379> msetnx k4 44
(integer) 0
127.0.0.1:6379> msetnx k4 44 k5 55
(integer) 0

设置对象

设置对象,咱们可以将 redis 的 key 设计成为我们业务需要的字符 key ,例如下面的例子

127.0.0.1:6379> set student:1:name xiaozhuy
OK
127.0.0.1:6379> set student:2:name xiaopangzi
OK
127.0.0.1:6379> mset student:3:name xiaopeiqi student:3:age 18 student:3:hobby basketball
OK
127.0.0.1:6379> keys student:3*
1) "student:3:hobby"
2) "student:3:age"
3) "student:3:name"
127.0.0.1:6379> mget student:3:hobby student:3:age student:3:name
1) "basketball"
2) "18"
3) "xiaopeiqi"
  • getset

先 get 值,再 set 值

127.0.0.1:6379> getset location beijing
(nil)
127.0.0.1:6379> get location
"beijing"
127.0.0.1:6379> getset location changsha
"beijing"
127.0.0.1:6379> get location
"changsha"

string 字符串的使用场景

string 类型的使用场景非常多,如下列举一些:

  • 统计多个单位的数量
  • 对象缓存存储
  • 分数,粉丝数,点赞量 等等

List 是基本数据类型,即列表

image-20210818201443260

在 redis 的 List 里面,咱们可以模拟栈,队列,阻塞队列等等

  • LPUSH key element [element ...]

从左边插入数据到 key 中,这个 key 是有个list , list 类型的指令都是 l 开头

  • RPUSH key element [element ...]

    从右边插入数据到 key 中

  • LRANGE key start stop

查看 list 的范围,

LRANGE key 0 1 查看当前 list 的全部值

127.0.0.1:6379> LPUSH mylist k1
(integer) 1
127.0.0.1:6379> LPUSH mylist k2
(integer) 2
127.0.0.1:6379> LPUSH mylist k3
(integer) 3
127.0.0.1:6379> LRANGE 0 -1
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> LRANGE mylist 0 1
1) "k3"
2) "k2"
127.0.0.1:6379> RPUSH mylist 4
(integer) 4
127.0.0.1:6379> RPUSH mylist 5
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "k3"
2) "k2"
3) "k1"
4) "4"
5) "5"
  • LPOP key [count]

从 list 的左边移除数据,默认是 1 个 ,即为移除 list 的第一个元素

  • RPOP key [count]

从 list 的右边移除数据 , 即为移除 list 的最后一个元素

127.0.0.1:6379> LPOP mylist
"k3"
127.0.0.1:6379> LPOP mylist 2
1) "k2"
2) "k1"
127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "5"
127.0.0.1:6379> RPOP mylist
"5"
127.0.0.1:6379> lrange mylist 0 -1
1) "4"
  • LINDEX key index

查看 list 中第 index 个值,从 0 开始

127.0.0.1:6379> keys *
1) "mylist"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "4"
127.0.0.1:6379> LINDEX mylist 1
(nil)
127.0.0.1:6379> LINDEX mylist 0
"4"
  • LLEN key

查看 list 的长度

127.0.0.1:6379> LLEN mylist
(integer) 1
127.0.0.1:6379> LPUSH mylist k6
(integer) 2
127.0.0.1:6379> LPUSH mylist k7
(integer) 3
127.0.0.1:6379> LLEN mylist
(integer) 3
  • LREM key count element

删除 list 中指定的元素,可以指定删除多少个

127.0.0.1:6379> lpush mylist one two three four five
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "five"
2) "four"
3) "three"
4) "two"
5) "one"
127.0.0.1:6379> LREM mylist 1 five
(integer) 1
127.0.0.1:6379> LRANGE mylist 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lpush mylist one
(integer) 5
127.0.0.1:6379> LRANGE mylist 0 -1
1) "one"
2) "four"
3) "three"
4) "two"
5) "one"
127.0.0.1:6379> LREM mylist 2 one
(integer) 2
127.0.0.1:6379> LRANGE mylist 0 -1
1) "four"
2) "three"
3) "two"
127.0.0.1:6379> LREM mylist 4 ll
(integer) 0

LREM 删除 list 中不存在的数据,返回 0 ,0 为失败,

LREM 删除 list 中存在的数据,若期望删除 5 个,实际上只有 2 个,那么redis 会返回 2 ,删除成功

  • LTRIM key start stop

裁剪,剪枝,获取 list 的某一段,并裁剪下来

127.0.0.1:6379> LRANGE mylist 0 -1
1) "k5"
2) "k4"
3) "k3"
4) "k2"
5) "k1"
6) "four"
7) "three"
8) "two"
127.0.0.1:6379> LTRIM mylist 3 5
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "k2"
2) "k1"
3) "four"
  • RPOPLPUSH source destination

从源 list 中的右边取出数据,从目的 list 的左边加入数据

127.0.0.1:6379> LRANGE mylist 0 -1
1) "k2"
2) "k1"
3) "four"
127.0.0.1:6379> RPOPLPUSH mylist newlist
"four"
127.0.0.1:6379>
127.0.0.1:6379> lrange newlist 0 -1
1) "four"
  • LSET key index element

将 list 中的对应索引的数据,替换成 element ,如果索引本没有数据,则会报错

127.0.0.1:6379> lrange mylist  0 -1
1) "k2"
2) "k1"
127.0.0.1:6379> LSET mylist 1 hello
OK
127.0.0.1:6379> lrange mylist  0 -1
1) "k2"
2) "hello"
127.0.0.1:6379> LSET mylist 10 world
(error) ERR index out of range
  • LINSERT key BEFORE|AFTER pivot element

    list 中在指定元素的前面或者后面添加数据

127.0.0.1:6379> lrange mylist  0 -1
1) "k2"
2) "hello"
127.0.0.1:6379> LINSERT mylist before hello xiaozhu
(integer) 3
127.0.0.1:6379> lrange mylist  0 -1
1) "k2"
2) "xiaozhu"
3) "hello"
127.0.0.1:6379> LINSERT mylist after hello bottom
(integer) 4
127.0.0.1:6379> lrange mylist  0 -1
1) "k2"
2) "xiaozhu"
3) "hello"
4) "bottom"
  • list 实际是一个链表,before node , after node ,left ,right 都是可以插入数据的
  • 如果 key 不存在,会创建新的 key ,即创建新的链表
  • 如果 key 存在,正常加入数据
  • 如果移除了所有的值,那么 key 就不存在了
  • 在 list 的两边插入和删除数据效率最高,从中间操作数据,效率相对较低

list 列表的应用场景:

list 可以做消息队列(FIFO),也可以做栈(FILO)

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK