linux-Redis学习

1.Redis的介绍

  • Redis是一种非关系型数据库 ,是一个高性能的key-value数据库 ,设置的值也是以键值对存在的
  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis还支持数据备份
  • Redis的所有操作都是原子性的
  • Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted
    set:有序集合)。

2.Redis的基本使用

01.启动和关闭

reids端口:6379

  1. 启动服务器

    redis-server

  2. 启动客户端

    本地登录:

    redis-cli

    远程登陆:

    ​ redis-cli -h 127.0.0.1 -p 6379

    查看连接状况:

    ​ ping

  3. 多数据库

    Redis默认支持16个数据库,从0开始的递增数字命名:0-15

    select来选择使用哪个数据库:select 1

  4. 关闭

    redis-cli shutdown

    断开连接: quit

3.基本命令

01.设置键和值

SET key values # 设置单个

MSET key values key values # 可以同时设置多个

02.获取符合规则的键名列表

通过KEYS patten 来获取key所对应的value

keys * # 获取所有键

get bar # 存在返回对应的value,没有则返回nil,表示空的意思

mget bar1 bar2 # 同时获取多个值

key m*

key m?

03.判断一个键是否存在

exists bar # 键存在返回1,否则返回0

04.键的重命名

rename key new_key

符号含义
?匹配一个字符
*匹配任意个(包括0个)字符
[]匹配括号间的任一字符,可以使用“-”符号表示一个范围,如a[b-d],可以匹配:ab,ac,ad
\x匹配字符x,用于转义字符。如要匹配“?”就需要使用?

05.设置key过期时间

1.设置:

​ expire key seconds

expire key value ex seconds

​ setex key secondes value 将值value关联到key,并将key的过期时间设置为secondes(以秒为单位)

例子:

​ set bar abc

expire bar 10000

set bar 123 ex 2000

setex name 5 “panlifu”

2.获取key还剩余的时间,-1表示永久,-2表示不存在

ttl bar

3.让键重新变成永久,成功返回1,否则返回0,表示键不存在或着本身就是永久的

persist bar

06.获取键的数据类型-适用5种数据类型

type key # Redis中有5中数据类型

07.删除键

del key [key …] 可以删除一个或多个键,返回值是删除的键的个数

del命令的参数不支持通配符,但可以结合linux的管道和xargs命令自己实现删除所有符合规则的键。

比如要出上所有以user开头的键:

​ redis-cli keys “user*” | xargs redis-cli del

另外用于del命令支持多个键作为参数,这个性能更好:

​ redis-cli del redis-cli keys “user*”

08.清空所有数据

Redis数据库之间并不是完全隔离的,比如flushall命令可以清空一个Redis实例中所有数据库中的数据

4.数据类型

01.string-字符串

  1. 设置

    set num 123

    mset num1 123 num2 123

    getset key value # 将给定key的值设为value,并返回key的旧值(old value)

    setex key secondes value # 将值value关联到key,并将key的过期时间设置为secondes(以秒为单位)

    set name panlifu ex 6

    setnx key value # 只有在key不存在时设置key的值

    setrange key offset value # 用value参数覆写给定key所存储的字符串值,从偏移量offset开始

    mset key value [key value] # 同时设置一个或者多个key -value对

  2. 获取

    get num

    mget num1 num2

    getrange key start end # 返回key中字符串的子字符,类似python中的切片功能,不同在于redis顾头顾尾

    strlen key # 返回 key 所储存的字符串值的长度

  3. 增加

    incr num # 加1

    incrby num 20.5 # 指定加

    incrbyfloat num 1.4

    append num abcd # 字符串追加

  4. 减少

    decr num #减1

    decrby num 20 # 指定减

总结:

key前面有m一般都指 可以设置多个 键值对。 键后面带nx 一般表示 只有当key不存在时,才能设置该key。

当键以ex结尾时,一般表示设置 key的过期时间,单位为秒。当键前面有p且后面有ex时,也表示设置key过期时间,单位为毫秒

string数据类型中的数据,value的数据类型都是string类型。只要string全为数字,即可使用incr键

02.list-列表

  1. 添加元素

    # lpush 左边添加(栈 先进后出)

    lpush key value [value …] # 将一个或多个值插入到列表头部

    #rpush 右边添加(队列 先进先出)

    rpush key value [value …] # 在列表中添加一个或多个值

    rpushx key value # 为已存在的列表添加值

    # 插入

    linsert key before|after pivot value 在列表的指定元素前或者后插入元素

    lpushx key value # 将一个值插入到已存在的列表头部

    #替换

    lset key index value # 通过索引设置列表元素的值

  2. 获取列表长度

    llen myli

  3. 查看指定位置元素

    lindex myli 3

  4. 获取列表片段: -1表示最后一个

    lrange key start stop # 获取列表指定范围内的元素

  5. 删除(弹出)元素

    lpop key # 移出并获取列表的第一个元素

    rpop key # 移除列表的最后一个元素,返回值为移除的元素。

    lrem key count value

    lrem myli 2 1 # 当count>0时lrem命令会从列表左边开始删除前count个值为value的元素

    lrem myli -1 2 # 当count<0时lrem命令会从列表右边开始删除前|count|个值为value的元素

    lrem myli 0 4 # 当count=0时lrem命令会删除所有值为value的元素

    ltrim key start stop #对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

    rpoplpush source destination # 移除列表的最后一个元素,并将该元素添加到另一个列表并返回

总结:以x结尾都是判断 key是否存在,不存在就不能设置,存在才能设置。

03.hash-哈希类型

Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

  1. 设置

    hset key field value # 设置存储在哈希表中指定字段的值(只能存储一个)

    hmset key field value [field value …] # 设置hash多个字段和值

    hsetnx key field value # 只有在字段 field 不存在时,设置哈希表字段的值。

  2. 获取

    hget key field # 获取存储在哈希表中指定字段的值

    hmget key field [field …] # 获取哈希表中某个字段的值

    hgetall key # 获取哈表表中所有字段的值及字段

    hkeys key # 获取所有哈希表中的字段

    hvals key # 获取哈希表中所有值

    hlen key # 获取哈希表中字段的数量

  3. 判断字段是否存在

    hexists key field # 查看哈希表中,指定的字段是否存在,存在返回1,不存在(哈希表或指定字段不存在)返回0

  4. 增加数字

    hincrby key field increment # 为哈希表 key 中的指定字段的整数值加上增量 increment

    hincrbyfloat key field increment # 为哈希表 key 中的指定字段的浮点数值加上增量 increment

  5. 删除字段

    hdel key field [field …] # 删除一个或多个哈希表字段

    del key # 删除key

  6. 迭代

    HSCAN key cursor [MATCH pattern] [COUNT count] # 迭代哈希表中的键值对。

    # 1. 查看hash表pms:1中有多少条记录
    127.0.0.1:6379[1]> hgetall pms:1
     1) "stock"
     2) "12"
     3) "freeze"
     4) "10"
     5) "stock:1"
     6) "11"
     7) "stock:2"
     8) "23"
     9) "stock:freeze:1"
    10) "111"
    11) "stock:5"
    12) "1212"
    
    # 2. 模糊查看pms:1下的键
    127.0.0.1:6379[1]> hscan pms:1 0 match stock:* count 100
    1) "0"
    2) 1) "stock:1"
       2) "11"
       3) "stock:2"
       4) "23"
       5) "stock:freeze:1"
       6) "111"
       7) "stock:5"
       8) "1212"
       
    # 3. 模糊查看pms:1下的键
    127.0.0.1:6379[1]> hscan pms:1 0 match stock* count 100
    1) "0"
    2)  1) "stock"
        2) "12"
        3) "stock:1"
        4) "11"
        5) "stock:2"
        6) "23"
        7) "stock:freeze:1"
        8) "111"
        9) "stock:5"
       10) "1212"
       
    # 4. 模糊查看pms:1下的键
    127.0.0.1:6379[1]> hscan pms:1 0 match stock:freeze:* count 100
    1) "0"
    2) 1) "stock:freeze:1"
       2) "111"
    
    # 5. 查看有多少个键
    127.0.0.1:6379[1]> keys *                                 
     1) "pms:1"                                               
     2) "pms:freeze:21"                                       
     3) "pms:10"                                              
     4) "pms:11"                                              
     5) "pms:9"                                               
     6) "pms:4"                                               
     7) "name"                                                
     8) "pms:5"                                               
     9) "pms:8"                                               
    10) "pms:7"                                               
    11) "pms:2"                                               
    12) "go:123"                                              
    13) "pms:3"                                               
    14) "pms:6"
    
    # 6. 模糊查找pms:*的键
    127.0.0.1:6379[1]> scan 0 match pms:* count 10            
    1) "3"                                                    
    2) 1) "pms:1"                                             
       2) "pms:8"                                             
       3) "pms:freeze:21"                                     
       4) "pms:5"                                             
       5) "pms:11"                                            
       6) "pms:9"                                             
       7) "pms:4"                                             
       8) "pms:3"                                             
       9) "pms:6"
       
    # 7. 模糊查找pms:*的键,游标从3开始
    127.0.0.1:6379[1]> scan 3 match pms:* count 10            
    1) "0"                                                    
    2) 1) "pms:10"                                            
       2) "pms:7"                                             
       3) "pms:2
    

04.Set-无序集合

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

  1. 增加

    sadd key member [member …] # 向集合添加一个或多个成员

  2. 获取

    smembers key # 获取一个key对应的集合元素

    scard key # 获取集合的成员数

    srangemember key [count] # 返回集合中一个或多个随机数

  3. 判断

    sismember key member # 判断 member 元素是否是集合 key 的成员

  4. 移动元素到另一个集合中

    smove source destination member # 将 member 元素从 source 集合移动到 destination 集合

  5. 删除元素

    spop key # 移除并返回集合中的一个随机元素

    spop key num # 移除并返回集合中的num个随机元素

    srem key member1 [member2] # 移除集合中一个或多个成员

  6. 交集

    sinter key1 [key2] # 返回给定所有集合的交集

    sinterstore destination key1 [key2] # 返回给定所有集合的交集并存储在 destination 中

  7. 并集

    sunion key1 [key2] # 返回所有给定集合的并集

    sunionstore destination key1 [key2] # 所有给定集合的并集存储在 destination 集合中

  8. 差集

    sdiff key1 [key2] # 返回给定所有集合的差集

    sdiffstore destination key1 [key2] # 返回给定所有集合的差集并存储在 destination 中

  9. 迭代

    sscan key cursor [MATCH pattern] [COUNT count] # 迭代集合中的元素

    redis 127.0.0.1:6379> SADD myset1 "hello"
    (integer) 1
    redis 127.0.0.1:6379> SADD myset1 "hi"
    (integer) 1
    redis 127.0.0.1:6379> SADD myset1 "bar"
    (integer) 1
    redis 127.0.0.1:6379> sscan myset1 0 match h*
    1) "0"
    2) 1) "hello"
       2) "h1"
    

05.zset-有序集合

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

存–ZADD key [NX|XX] [CH] [INCR] score member [score member …]
  • XX: 仅仅更新存在的成员,不添加新成员。
  • NX: 不更新存在的成员。只添加新成员。
  • CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。
  • INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。
取–ZRANGE key start stop [WITHSCORES]
  1. 增加/修改(更新)

    zadd key score1 member1 [score2 member2] # 向有序集合添加一个或多个成员,或者更新已存在成员的分数

  2. 修改分数

    zincrby key increment member # 有序集合中对指定成员的分数加上增量 increment

  3. 获取

    获取成员:

    zrange key start stop [WITHSCORES] # 通过索引区间返回有序集合成指定区间内的成员,0表示最前一个,-1表示最后一个

    ​ 例子:ZRANGE salary 0 -1 WITHSCORES # 显示整个有序集及成员的 score 值,# 递增排列

    zrangebylex key min max [LIMIT offset count] # 通过字典区间返回有序集合的成员

    ​ 例子:ZRANGEBYLEX myzset - [c

    ​ ZRANGEBYLEX myzset - (c

    ​ ZRANGEBYLEX myzset [aaa (g

    zrangebyscore key min max [WITHSCORES] [LIMIT] # 通过分数返回有序集合指定区间内的成员

    ​ 例子:ZRANGEBYSCORE salary -inf +inf # 显示整个有序集

    ​ ZRANGEBYSCORE salary (5000 400000 # 显示工资大于 5000 小于等于 400000 的成员

    zrevrange key start stop [WITHSCORES] # 返回有序集中指定区间内的成员,通过索引,分数从高到底

    ​ 例子:ZREVRANGE salary 0 -1 WITHSCORES # 递减排列

    zrevrangebyscore key max min [WITHSCORES] # 返回有序集中指定分数区间内的成员,分数从高到低排序

    获取成员数:

    zcard key # 获取有序集合的成员数

    zcount key min max # 计算在有序集合中指定区间分数的成员数

    zlexcount key min max # 在有序集合中计算指定字典区间内成员数量

    ​ 例子:zlexcount myzset - + # 返回全部成员数量

    zlexcount myzset [b [f # 返回切片闭区间[b,f]中的数量

    获取成员索引:

    zrank key member # 返回有序集合中指定成员的索引

    获取排名:

    zrevrank key member # 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

    获取分数值:

    zscore key member # 返回有序集中,成员的分数值

  4. 删除

    zrem key member [member …] # 移除有序集合中的一个或多个成员

    ZREM page_rank non-exists-element # 移除不存在元素

  5. 交集

    zinterstore destination numkeys key [key …] # 计算给定的numkeys个有序集的交集并将结果集存储在新的有序集合 key 中

    zremrangebylex key min max # 移除有序集合中给定的字典区间的所有成员: ZREMRANGEBYLEX myzset [alpha [omega

    zremrangebyrank key start stop # 移除有序集合中给定的排名区间的所有成员: 闭区间

    zremrangebyscore key min max 移除有序集合中给定的分数区间的所有成员: 闭区间

  6. 并集

    zunionstore destination numkeys key [key …] 计算给定的一个或多个有序集的并集,并存储在新的 key 中

  7. 迭代

    zscan key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成员和元素分值)

5.*列表类型与有序集合区别

有序集合类型在某些方面和列表类型有些相似。
(1)二者都是有序的。
(2)二者都可以获得某一范围的元素。

但是二者有着很大的区别,这使得它们的应用场景也是不同的。
(1)列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会较慢,所以它更加适合实现如“新鲜事”或“日志”这样很少访问中间元素的应用。
(2)有序集合类型是使用散列表和跳跃表(Skip list)实现的,所以即使读取位于中间部分的数据速度也很快(时间复杂度是O(log(N)))。
(3)列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)。
(4)有序集合要比列表类型更耗费内存。有序集合类型算得上是 Redis的5种数据类型中最高级的类型了,在学习时可以与列表类型和集合类型对照理解。

6.python与redis交互

01.redis模块的使用

1.安装模块

pip3 install redis -i https://pypi.douban.com/simple 

2.导入模块

import redis

3.连接方式

  • 严格连接模式:r=redis.StrictRedis(host="",port=)
  • 更Python化的连接模式:r=redis.Redis(host="",port=)
  • StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令
  • Redis与StrictRedis的区别是:Redis是StrictRedis的子类,用于向前兼容旧版本的redis-py,并且这个连接方式是更加"python化"的

4.连接池

​ 为了节省资源,减少多次连接损耗,连接池的作用相当于总揽多个客户端与服务端的连接,当新客户端需要连接时,只需要到连接池获取一个连接即可,实际上只是一个连接共享给多个客户端。

import redis

pool= redis.ConnectionPool(host='localhost',port=6379,decode_responses=True)

r=redis.Redis(connection_pool=pool)
r2=redis.Redis(connection_pool=pool)
r.set('apple','a')
print(r.get('apple'))
r2.set('banana','b')
print(r.get('banana'))

print(r.client_list())
print(r2.client_list())#可以看出两个连接的id是一致的,说明是一个客户端连接

5.操作

  • 值的设置和获取,可以参考redis的命令,redis模块中的对应功能的函数名基本与redis中的一致

  • 【注意默认情况下,设置的值或取得的值都为bytes类型,如果想改为str类型,需要在连接时添加上decode_responses=True】

  • 设置值:

    • redis中set() ==>r.set()
    • redis中setnx() ==>r.set()
    • redis中setex() ==>r.setex()
    • redis中setbit() ==>r.setbit()
    • redis中mset() == > r.mset()
    • redis中hset() ==>r.hset()
    • redis中sadd() == >r.sadd()
    • 其他。。。基本redis的命令名与redis模块中的函数名一致
  • 获取:

    • redis中get() ==》r.get()
    • redis中mget() ==》r.mget()
    • redis中getset() ==》r.getset()
    • redis中getrange() ==》r.getrange()
    • 其他。。。基本redis的命令名与redis模块中的函数名一致
import redis
r=redis.Redis(host='localhost',port=6379,decode_responses=True)
# r=redis.StrictRedis(host='localhost',port=6379)

r.set('key','value')
value=r.get('key')
# print(type(value))
print(value)
r.hset('info','name','lilei')
r.hset('info','age','18')
print(r.hgetall('info'))
r.sadd('course','math','english','chinese')
print(r.smembers('course'))

02.管道

一般情况下,执行一条命令后必须等待结果才能输入下一次命令,管道用于在一次请求中执行多个命令。

参数介绍:

  • transaction:指示是否所有的命令应该以原子方式执行。
import redis,time

r=redis.Redis(host="localhost",port=6379,decode_responses=True)

pipe=r.pipeline(transaction=True)

pipe.set('p1','v2')
pipe.set('p2','v3')
pipe.set('p3','v4')
time.sleep(5)
pipe.execute()

03.事务

python中可以使用管道来代替事务:

  • 补充:监视watch:pipe.watch()
import redis,time
import redis.exceptions
r=redis.Redis(host='localhost',port=6379,decode_responses=True)
pipe=r.pipeline()
print(r.get('a'))

try:
    # pipe.watch('a')
    pipe.multi()
    pipe.set('here', 'there')
    pipe.set('here1', 'there1')
    pipe.set('here2', 'there2')
    time.sleep(5)
    pipe.execute()

except redis.exceptions.WatchError as e:
    print("Error")

04.订阅/发布

  • 发布方:
import redis
r=redis.Redis(host="localhost",port=6379,decode_responses=True)

#发布使用publish(self, channel, message):Publish ``message`` on ``channel``.
Flag=True
while Flag:
    msg=input("主播请讲话>>:")
    if len(msg)==0:
        continue
    elif msg=='quit':
        break
    else:
        r.publish('cctv0',msg)
  • 订阅方:

    • 当订阅成功后,第一次接收返回的第一个消息是一个订阅确认消息:image
import redis
r=redis.Redis(host="localhost",port=6379,decode_responses=True)

#发布使用publish(self, channel, message):Publish ``message`` on ``channel``.
Flag=True
chan=r.pubsub()#返回一个发布/订阅对象
msg_reciver=chan.subscribe('cctv0')#订阅

msg=chan.parse_response()#第一次会返回订阅确认信息
print(msg)
print("订阅成功,开始接收------")
while Flag:
    msg=chan.parse_response()#接收消息
    print(">>:",msg[2])#此处的信息格式['消息类型', '频道', '消息'],所以使用[2]来获取
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值