美文网首页
Python 数据库骚操作 -- Redis

Python 数据库骚操作 -- Redis

作者: 天善智能 | 来源:发表于2019-02-20 10:50 被阅读5次

    欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

    对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

    作者: 一只爱折腾的后端攻城狮

    知乎专栏|后端攻城狮:
    https://zhuanlan.zhihu.com/c_1011199533304410112
    个人公众号:zone7

    目录

  1. 前言

  2. Redis GUI 工具

  3. Redis 遇上 Docker

  4. Redis string

  5. Redis hash

  6. Redis list

  7. Redis set

  8. Redis zset

  9. 后记

  10. 前言

    前面一篇文章《

    Python数据库骚操作MongoDB

    》介绍了 MongoDB 的库,我把 MySQL 放在了最后面,这篇文章继续介绍 Redis 的操作。Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。接下来会简单介绍一下,Python 与 Redis 的化学反应。全文有点长,难免会有疏漏,若有错误还烦请指出。

    Redis GUI 工具

    首先介绍一款 Redis 的 GUI 工具 Medis,初学 Redis 用这个来查看数据真的很爽。可以即时看到数据的增删改查,不用操作命令行来查看。

    ## Redis 遇上 Docker
    关注我的人都知道,我的简介上面写着我的公众号会涉及 Docker 相关的知识,但最近的文章也没怎么涉及,所以后面的文章中,能跟 Docker 扯上关系的,我都会粗略地说一下。这里主要贴一贴配置代码,docker-compose 代码如下。

    version: '3'
    services:
      redis_container:
        image: redis
        command: redis-server --requirepass yourpassword # 配置 Redis 密码
        ports:
          - "6378:6379" # 映射端口
        volumes:
          - /your/path/data:/data 

    启动命令

    docker-compose up -d

    Redis string

    install

    pip install redis

    连接

    # 普通连接
    r = redis.StrictRedis(host='localhost', port=6379, db=0)
    r = redis.StrictRedis(host='localhost', port=6379, password="your password", db=0)

    # 连接池
    """
    redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池,这样就可以实现多个 Redis 实例共享一个连接池
    """
    # host 是 redis 服务 ip,默认端口是6379
    pool = redis.ConnectionPool(host='localhost', port=6379,decode_responses=True)  
    r = redis.Redis(connection_pool=pool)

    增加

    set(name, value, ex=None, px=None, nx=False, xx=False)

    在Redis中设置值,默认,不存在则创建,存在则修改
    参数:
    ex,过期时间(秒)
    px,过期时间(毫秒)
    nx,如果设置为True,则只有name不存在时,当前set操作才执行
    xx,如果设置为True,则只有name存在时,当前set操作才执行
    # 设置过期时间为 1 秒
    r.set('foo', 'zone', ex=1)
    # 效果同上
    r.setex('foo', 'zone', 1)
    # 效果同上
    r.psetex('foo', 1000, 'zone')

    print(r.get('foo'))

    # 休眠两秒后,再打印输出
    time.sleep(2)
    print(r.get('foo'))

    查找

    get(key)
    普通查找
    print(r.get('foo'))
    mget(keys, *args)
    批量查找
    # 批量获取
    print(r.mget("k1", "k2"))  # 一次取出多个键对应的值
    print(r.mget("k1"))

    获取子序列

    getrange(key, start, end)
    获取子序列(根据字节获取,非字符)
    参数:
    name,Redis 的 name
    start,起始位置(字节)
    end,结束位置(字节)
    # 一个汉字3个字节 1个字母一个字节
    r.set("name", "zonezone")
    print(r.getrange('name', 0, 3))
    # 获取所有字节
    print(r.getrange('name', 0, -1))

    获取结果

    修改

    原始值 zonezone ,修改后变为 zone is a boy

    setrange(name, offset, value)
    修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
    参数:
    offset,字符串的索引,字节(一个汉字三个字节)
    value,要设置的值
    r.set("name", "zonezone")
    r.setrange("name", 4, " is a boy")
    print(r.get("name")) 

    修字符串成功

    返回相应 key 的字符串长度

    r.set("name", "zonezone")
    print(r.strlen("name"))

    自增 name 对应的值(int)

    incr(self, name, amount=1)
    自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
    参数:
    name,Redis的name
    amount,自增数(必须是整数)
    r.set("age", 123)
    print(r.get("age"))
    r.incr("age", amount=1)
    print(r.get("age"))

    自增成功

    自增 name 对应的值(float)

    incrbyfloat(self, name, amount=1.0)
    自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
    参数:
    name,Redis的name
    amount,自增数(浮点型)
    r.set("age", 123.0)
    print(r.get("age"))
    r.incrbyfloat("age", amount=0.2)
    print(r.get("age"))

    自减 name 对应的值

    r.set("age", 123)
    r.decr("age", amount=1) # 递减1
    print(r.mget("foo1", "foo4"))

    追加内容

    append(key, value)
    在redis name对应的值后面追加内容
    参数:
    key, redis的name
    value, 要追加的字符串
    r.set("name", "关注 ")
    print(r.get("name"))
    r.append("name","公众号【zone7】")
    print(r.get("name"))

    Redis hash

    增加

    hset(name, key, value)
    name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
    参数:
    name,redis的name
    key,name对应的hash中的key
    value,name对应的hash中的value
    注:
    hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)
    r.hset("hash1", "k1", "v1")
    r.hset("hash1", "k2", "v2")
    # 取hash中所有的key
    print(r.hkeys("hash1")) 
    # 单个取hash的key对应的值
    print(r.hget("hash1", "k1"))    
    # 多个取hash的key对应的值
    print(r.hmget("hash1", "k1", "k2")) 
    r.hsetnx("hash1", "k2", "v3")
    print(r.hget("hash1", "k2"))

    批量增加与批量获取

    # 批量增加
    r.hmset("hash2", {"k1": "v1", "k2": "v2"})
    # 批量获取
    print(r.hmget("hash2", "k1", "k2"))

    获取所有 hash 键值对

    print(r.hgetall("hash1"))

    获取 hash长度

    hlen(name)
    获取name对应的hash中键值对的个数
    print(r.hlen("hash1"))

    获取所有的keys(类似字典的取所有keys)

    hkeys(name)
    获取name对应的hash中所有的key的值
    print(r.hkeys("hash1"))

    获取所有的value(类似字典的取所有value)

    hvals(name)
    获取name对应的hash中所有的value的值
    print(r.hvals("hash1"))

    判断成员是否存在(类似字典的in)

    hexists(name, key)
    检查name对应的hash是否存在当前传入的key
    print(r.hexists("hash1", "k1")) 

    删除

    hdel(name,*keys)
    将name对应的hash中指定key的键值对删除
    r.hset("hash1", "name", "zone")
    print(r.hget("hash1", "name"))
    r.hdel("hash1", "name")
    print(r.hget("hash1", "name"))

    自增自减(int)

    hincrby(name, key, amount=1)
    自增name对应的hash中的指定key的值,不存在则创建key=amount
    参数:
    name,redis中的name
    key, hash对应的key
    amount,自增数(整数)
    r.hset("hash1", "age", 123)
    r.hincrby("hash1", "age", amount=-1)
    print(r.hget("hash1", "age"))
    r.hincrby("hash1", "age", amount=1)  # 不存在的话,value默认就是1
    print(r.hget("hash1", "age"))

    自增自减(float)

    hincrbyfloat(name, key, amount=1.0)
    自增name对应的hash中的指定key的值,不存在则创建key=amount
    参数:
    name,redis中的name
    key, hash对应的key
    amount,自增数(浮点数)
    自增name对应的hash中的指定key的值,不存在则创建key=amount
    r.hset("hash1", "age", 123.0)
    r.hincrbyfloat("hash1", "age", amount=-0.3)
    print(r.hget("hash1", "age"))
    r.hincrbyfloat("hash1", "age", amount=0.5)  # 不存在的话,value默认就是1
    print(r.hget("hash1", "age"))

    Redis list

    增加(不存在会自动创建)

    lpush(name,values)
    在name对应的list中添加元素,每个新的元素都添加到列表的最左边
    rpush(name,values)
    在name对应的list中添加元素,每个新的元素都添加到列表的最右边
    r.lpush("left_list", 11, 22, 33)
    print(r.lrange('left_list', 0, -1))

    r.rpush("right_list", 11, 22, 33)
    print(r.lrange("right_list", 0, 3))

    print(r.llen("right_list"))  # 列表长度

    添加(不存在不会自动创建)

    lpushx(name,value)
    在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边。不存在时,不会自动创建。
    r.lpushx("left_list", 2222)
    print(r.lrange('left_list', 0, -1))

    r.rpushx("right_list", 1111)
    print(r.lrange('right_list', 0, -1))

    有两个 2222 是因为我手抖,多运行了一遍

    新增

    新增(固定索引号位置插入元素)
    linsert(name, where, refvalue, value))
    在name对应的列表的某一个值前或后插入一个新值
    参数:
    name,redis的name
    where,BEFORE或AFTER
    refvalue,标杆值,即:在它前后插入数据
    value,要插入的数据
    # 往列表中左边第一个出现的元素"11"前插入元素"00"
    r.linsert("left_list", "before", "11", "00") 
    print(r.lrange("left_list", 0, -1))

    修改

    修改(指定索引号进行修改)
    r.lset(name, index, value)
    对name对应的list中的某一个索引位置重新赋值
    参数:
    name,redis的name
    index,list的索引位置
    value,要设置的值
    # 把索引号是0的元素修改成 关注公众号【zone7】
    r.lset("left_list", 0, "关注公众号【zone7】")    
    print(r.lrange("left_list", 0, -1))

    删除

    删除(指定值进行删除)
    r.lrem(name, value, num)
    在name对应的list中删除指定的值
    参数:
    name,redis的name
    value,要删除的值
    num, num=0,删除列表中所有的指定值;
    num=2,从前到后,删除2个; num=1,从前到后,删除左边第1个
    num=-2,从后向前,删除2个
    # 将列表中左边第一次出现的"33"删除
    r.lrem("left_list", "33", 1)   
    print(r.lrange("left_list", 0, -1))

    删除 33

    删除并返回

    lpop(name)
    在 name 对应的列表的左边获取第一个元素并在列表中移除,返回值则是第一个元素
    rpop(name)
    在 name 对应的列表的右边获取第一个元素并在列表中移除,返回值则是第一个元素
    print(r.lpop("left_list"))
    print(r.lrange("list2", 0, -1))

    Redis set

    增加

    sadd(name,values)
    添加元素
    r.sadd("set1", 1, 2, 3, 4)
    # 获取集合长度
    print(r.scard("set1"))  
    # 获取集合中所有元素
    print(r.smembers("set1")) 

    删除

    # 普通删除
    srem(name, values)
    在name对应的集合中删除某些值
     # 从集合中删除指定值 1
    print(r.srem("set1", 1))  
    print(r.smembers("set1"))

    删除了值 1

    # 随机删除并返回被删除值
    spop(name)
    从集合移除一个成员,并将其返回,说明一下,集合是无序的,所有是随机删除的
    # 这个删除的值是随机删除的,集合是无序的
    print(r.spop("set2"))   
    print(r.smembers("set2"))

    查找

    # 普通获取
    smembers(name)
    获取name对应的集合的所有成员
    # 获取集合中所有的成员
    print(r.smembers("set1"))   
    # 以元组形式获取集合
    sscan(name, cursor=0, match=None, count=None)
    print(r.sscan("set1"))
    # 以迭代器的方式获取集合
    sscan_iter(name, match=None, count=None)
    同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
    for i in r.sscan_iter("set1"):
        print(i)

    交集

    sinter(keys, *args)
    获取多个 name 对应集合的交集
    r.sadd("set2", 1, 2, 3, 4)
    r.sadd("set3", 3, 4, 5, 6)
    print(r.sinter("set2", "set3"))

    交集为 3、4

    sinterstore(dest, keys, *args)
    获取多个 name 对应集合的并集,再将并集加入到 dest(目标集合) 中
    r.sadd("set2", 1, 2, 3, 4)
    r.sadd("set3", 3, 4, 5, 6)
    print(r.sinterstore("set4", "set2", "set3"))
    print(r.smembers("set4"))

    交集为 3、4

    移动

    smove(src, dst, value)
    将某个成员从一个集合中移动到另外一个集合
    r.smove("set2", "set3", 3)
    print(r.smembers("set2"))
    print(r.smembers("set3"))

    将 set2 中的元素 3 移动至 set3

    判断集合中是否有某元素

    sismember(name, value)
    检查value是否是name对应的集合的成员,结果为True和False
    print(r.sismember("set2", 3))
    print(r.sismember("set3", 1))

    并集

    sunion(keys, *args)
    获取多个name对应的集合的并集
    r.sadd("set2", 1, 2, 3, 4)
    r.sadd("set3", 3, 4, 5, 6)
    print(r.sunion("set2", "set3"))

    无序集

    并集--并集存在一个新的集合
    sunionstore(dest,keys, *args)
    获取多个name对应的集合的并集,并将结果保存到dest对应的集合中
    r.sadd("set2", 1, 2, 3, 4)
    r.sadd("set3", 3, 4, 5, 6)
    print(r.sunionstore("set4", "set2", "set3")) # 取2个集合的并集
    print(r.smembers("set4"))

    无序集

    Redis zset

    set 就是无序,不允许重复的列表

    增加

    zadd(name, *args, **kwargs)
    在name对应的有序集合中添加元素
    r.zadd("zset1", n1=123, n2=234)
    print(r.zrange("zset1", 0, -1))   # 获取有序集合中所有元素
    # 效果同上
    r.zadd("zset1", 'n1', 123, 'n2', 234)

    删除

    zrem(name, values)
    删除name对应的有序集合中值是values的成员
    # 删除 n2
    r.zrem("zset2", "n2")
    print(r.zrange("zset2", 0, -1))

    n2 已被删除

    zremrangebyrank(name, min, max)
    根据索引删除
    # 根据索引删除
    r.zremrangebyrank("zset2", 0, 1)
    print(r.zrange("zset2", 0, -1))

    删除索引为 0、1 的值,即删除 n3、n4

    zscore(name, value)
    获取name对应有序集合中 value 对应的分数
    # 查找 n5 的值
    print(r.zscore("zset2", "n5"))

    获取 set 的长度

    print(r.zcard("zset1")) 

    获取有序集合的所有元素

    r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
    按照索引范围获取name对应的有序集合的元素
    参数:
    name,redis的name
    start,有序集合索引起始位置(非分数)
    end,有序集合索引结束位置(非分数)
    desc,排序规则,默认按照分数从小到大排序
    withscores,是否获取元素的分数,默认只获取元素的值
    score_cast_func,对分数进行数据转换的函数

    # 获取所有元素
    print(r.zrange("zset1", 0, -1))  

    从大到小排序(同zrange,集合是从大到小排序的)

    zrevrange(name, start, end, withscores=False, score_cast_func=float)

    # 只获取元素,不显示分数
    print(r.zrevrange("zset1", 0, -1))    
    # 获取有序集合中所有元素和分数,分数倒序
    print(r.zrevrange("zset1", 0, -1, withscores=True))

    统计范围内元素个数

    zcount(name, min, max)
    获取name对应的有序集合中分数 在 [min,max] 之间的个数
    for i in range(1, 30):
        key = 'n' + str(i)
        r.zadd("zset2", key, i)
    print(r.zrange("zset2", 0, -1, withscores=True))
    print(r.zcount("zset2", 1, 9))

    太长了,我截取了部分

    自增

    zincrby(name, value, amount)
    自增name对应的有序集合的 name 对应的分数
    # 每次将n1的分数自增5
    r.zincrby("zset2", "n2", amount=5)
    print(r.zrange("zset2", 0, -1, withscores=True))

    n1 已增加 5

    获取值的索引号

    zrank(name, value)
    获取某个值在 name对应的有序集合中的索引(从 0 开始)
    # 获取 n2 的索引号
    print(r.zrank("zset2", "n2"))

    后记

    在微信公众号后台回复「Redis」获取源码。Redis 的骚操作就介绍到这里,后面会继续写 MySQL 的骚操作。尽请期待。

    Python的爱好者社区历史文章大合集

    2018年Python爱好者社区历史文章合集(作者篇)

    2018年Python爱好者社区历史文章合集(类型篇)

    关注后在公众号内回复“ 课程 ”即可获取:

    小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】

    小编的Python的入门免费视频课程

    小编的Python的快速上手matplotlib可视化库!

    崔老师爬虫实战案例免费学习视频。

    陈老师数据分析报告扩展制作免费学习视频。

    玩转大数据分析!Spark2.X + Python精华实战课程免费学习视频。

    相关文章

      网友评论

          本文标题:Python 数据库骚操作 -- Redis

          本文链接:https://www.haomeiwen.com/subject/irvcyqtx.html