Redis数据类型

news2025/7/9 20:04:14

1.String(字符串)

在任何一种编程语言中,字符串都是最基础的数据结构,在Redis中String是可以修改的称之为:动态字符串(简称SDS)

Redis的内存分配机制:

        - 当字符串的长度小于1MB时,每次扩容都是加倍现有的空间

        - 如果字符串长度超过1MB时,每次扩容时只会扩展1MB空间

ps:这样既保证了内存空间够用,也不会造成内存的浪费,字符串最大长度为512MB

import redis

conn = redis.Redis()
# 1  set(name, value, ex=None, px=None, nx=False, xx=False)
#      ex,过期时间(秒)
#      px,过期时间(毫秒)
#      nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
#      xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值

# conn.set('name','abc') # value 只能是字符串或byte格式
# conn.set('name','abc',ex=3) # ex 是过期时间,到3s过期,数据就没了
# conn.set('name','abc',px=3000) # px 是过期时间,到3s过期,数据就没了
# conn.set('age',18,nx=True) # redis 实现分布式锁
# conn.set('hobby', '足球', xx=False) # hobby存在操作


# 2 setnx(name, value)   就是:set nx=True
# conn.setnx('hobby1','橄榄球')


# 3 psetex(name, time_ms, value)  本质就是 set px设置时间
# conn.psetex('name',3000,'abc')

# 4 mset(*args, **kwargs)  传字典批量设置
# conn.mset({'name':'xxx','age':19})


# 5 get(name)  获取值,取到是bytes格式   ,指定:decode_responses=True,就完成转换
# print(conn.get('name'))
# print(str(conn.get('name')[:3],encoding='utf-8'))

# 5 mget(keys, *args)  #批量获取
# res=conn.mget('name','age')
# res=conn.mget(['name','age'])
# print(res)

# 6 getset(name, value)  # 先获取,再设置
# res=conn.getset('name','cba')
# print(res)


# 7 getrange(key, start, end) # 取的是字节,前闭后闭区间
# res=conn.getrange('name',0,1)
# print(res)

# 8 setrange(name, offset, value)  # 从某个起始位置开始替换字符串
# conn.setrange('name', 1, 'xxx')

# 9 setbit(name, offset, value)
# conn.setbit('name',1,0)   #  00000000   00000000   00000000
# res=conn.get('name')
# print(res)


# 10 getbit(name, offset)
# res=conn.getbit('name',1)
# print(res)


# 11 bitcount(key, start=None, end=None)
# print(conn.bitcount('name',0,3))  # 3 指的是3个字符

# 12 strlen(name)  # 统计字节长度
# print(conn.strlen('name'))
# print(len('abc胡'))  # len 统计字符长度

# 13 incr(self, name, amount=1)  # 计数器
# conn.incr('age',amount=3)


# 14 incrbyfloat(self, name, amount=1.0)

# 15 decr(self, name, amount=1)
# conn.decr('age')

# 16 append(key, value) # 在后面追加
# conn.append('name','nb')
conn.close()

2.list(列表)

Redis的list和java中的LinkedLIst很像,底层都是一种链表结构,list的插入和删除操作非常快,时间复杂度为0(1),不像数组结构插入、删除操作需要移动数据

当数据量较少的时候它的底层存储结构为一块连续内存,称之为ziplist(压缩列表),它将所有的元素紧挨着存储,分配的是一块连续的内存;当数据量较多的时候将会变成quicklist(快速链表)结构

redis3.2之后就改用ziplist+链表的混合结构,称之为quicklist(快速链表)

\bullet list应用场景它是按照插入顺序排序的列表:

        - 消息队列:lpop和rpush或者lpush和rpop能实现队列的功能

        - 朋友圈的点赞列表、评论列表、排行榜:lpush命令和lrange命令能实现最新列表的功能,每一次通过push命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表

import redis

conn = redis.Redis(decode_responses=True)

# 1 lpush(name,values)   从左侧插入  [小明 小红 小张 小鹏]
# conn.lpush('girls','小红')
# conn.lpush('girls','小明')
# conn.rpush('girls','小张') # 从右侧插入
# conn.rpush('girls','小鹏')  


# 2 lpushx(name,value) 只有name已经存在时,值添加到列表的最左边
# conn.lpushx('girls','小丽')
# conn.lpushx('boys','小刚')


# 3 rpushx(name, value) 表示从右向左操作


# 4 llen(name)
# res=conn.llen('girls')
# print(res)


# 5 linsert(name, where, refvalue, value))
# conn.linsert('girls', where='after', refvalue='小红', value='李清照')
# conn.linsert('girls', where='before', refvalue='小红', value='李清照')

# 6 lset(name, index, value)
# conn.lset('girls',0,'xx')


# 7 lrem(name,count ,value)  # count放数字,可以写负数,表示从右往前删除  0 表示全删
# conn.lrem('girls',0,'李清照')


# 8 lpop(name)
# res=conn.lpop('girls')
# res=conn.rpop('girls')
# print(res)


# 9 lindex(name, index)
# res=conn.lindex('girls',2)
# print(res)


# 10 lrange(name, start, end)  前闭后闭
# res=conn.lrange('girls',0,2)
# print(res)

# 11 ltrim(name, start, end)  修建
# res=conn.ltrim('girls',1,2)

# 12 rpoplpush(src, dst)
# conn.rpoplpush('girls','boys')

# 13 blpop(keys, timeout)  阻塞式弹出,如果列表中没有值,会阻塞在这,直到有值,再弹出,它可以做消息队列,做分布式的系统
# res=conn.blpop('boys',timeout=3)
# print(res)

# 14 brpoplpush(src, dst, timeout=0)


# 15 自定义增量迭代
# res=conn.lrange('girls',0,conn.llen('girls'))
# print(res)


conn.close()

3.hash(字典)

Redis中的Hash和Java的HashMap更加相似,都是数组+链表的结构,当发送hash碰撞时将会把元素追加到链表上,要注意的是在Redis的Hash中value只能是字符串

Hash和String都可以用来存储用户信息,但不同的是Hash可以对用户信息的每个字典单独存储;

String存的是用户全部信息经过序列化后的字符串,如果想要修改某个用户字段必须将用户信息字符串全部查询出来,解析成响应的用户信息对象,修改完后在序列化成字符串存入

Hash可以只对某个字段修改,从而节约网络流量但是hash内存占用要大于String

\bullet 应用场景:

        - 购物车:hset[key] [field] [value],可以实现以用户id为field,商品数量为value,恰好构成了购物车的三要素

        - 存储对象:hash类型的(key,field,value)的结构与对象的(对象id,属性,值)的结构相似,也可以用来存储对象

import redis

conn = redis.Redis(decode_responses=True)
# 1 hset(name, key, value)
# conn.hset('userinfo', 'name', '彭于晏')
# conn.hset('userinfo', 'age', '32')
# conn.hset('xx',mapping={'name':'xxx','hobby':'篮球'})


# 2 hmset(name, mapping)   弃用了
# conn.hmset('yy',{'a':'a','b':'b'})


# 3 hget(name,key)
# res=conn.hget('userinfo','age')
# print(res)

# 4 hmget(name, keys, *args)
# res=conn.hmget('userinfo',['name','age'])
# print(res)

# 5 hgetall(name)    慎用,可能会造成 阻塞 尽量不要在生产代码中执行它
# res=conn.hgetall('userinfo')
# print(res)


# 6 hlen(name)
# res=conn.hlen('userinfo')
# print(res)


# 7 hkeys(name)
# res=conn.hkeys('userinfo')
# print(res)
# 8 hvals(name)
# res=conn.hvals('userinfo')
# print(res)

# 9 hexists(name, key)
# res=conn.hexists('userinfo','name')
# print(res)

# 10 hdel(name,*keys)
# conn.hdel('userinfo','age')


# 11 hincrby(name, key, amount=1)
# conn.hincrby('userinfo','age')

# 12 hincrbyfloat(name, key, amount=1.0)
# conn.hincrbyfloat('userinfo','age',5.44)

## 联合起来讲:不建议使用hgetall,分片取值
# 分批获取               生成器应用在哪了?
# 13 hscan(name, cursor=0, match=None, count=None)
# hash类型没有顺序---》python字典 之前没有顺序,3.6后有序了    python字段的底层实现
# for i in range(1000):
#     conn.hset('test_hash','key_%s'%i,'鸡蛋%s号'%i)

# count 是要取的条数,但是不准确,有点上下浮动
# 它一般步单独用
# res=conn.hscan('test_hash',cursor=0,count=19)
# print(res)
# print(res[0])
# print(res[1])
# print(len(res[1]))
# res=conn.hscan('test_hash',cursor=res[0],count=19)
# print(res)
# print(res[0])
# print(res[1])
# print(len(res[1]))


# 咱么用它比较多,它内部封装了hscan,做成了生成器,分批取hash类型所有数据
# 14 hscan_iter(name, match=None, count=None)  获取所有hash的数据
# res = conn.hscan_iter('test_hash',count=100)
# print(res)  # 生成器
# for item in res:
#     print(item)

conn.close()

4.set(集合)

Redis中的set和java中的HashSet有些类似,它内部的键值对是无序的、唯一的,他的内部实现相当于一个特殊的字典,字典中所有的value都是一个值NULL,当集合中最后一个元素被移除之后数据结构被自动删除,内存被释放

\bullet 应用场景:

        - sinter命令可以获得A和B两个用户的共同好友

        - sismenber命令可以判断A是否是B的好友

        - scard命令可以获取好友数量

 redis是否支持事物

redis可以说支持事务也可以说不支持,redis事务机制可以保证一致性和隔离性,但是无法保证持久性,但是对于redis而言,本身是内存数据库,所以持久性不是必须属性,原子性需要自己进行检查,尽可能保证。

redis不像mysql一样事务的四大特性不能全部满足,但是能满足一部分,通过redis的管道实现的

redis本身不支持事务,但是可以通过管道实现部分事务

redis可以通过管道来保证命令要么都成功,要么都失败,完成事务的一致性,但是管道只能用在单实例,集群中不支持管道

 django中集成redis

方式一:直接使用

from user.POOL import pool
import redis
def index(request):
    conn = redis.Redis(connection_pool=pool)
    conn.incr('page_view')
    res = conn.get('page_view')
    return HttpResponse('被你看了%s次' % res)

方式二:使用第三方模块

# 下载第三方模块:django-redis
# 配置文件中配置
CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/0",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # "PASSWORD": "123",
            }
        }
    }
# 使用方式
from django_redis import get_redis_connection
def index(request):
    conn = get_redis_connection(alias="default") # 每次从池中取一个链接
    conn.incr('page_view')
    res = conn.get('page_view')
    return HttpResponse('执行了%s次' % res)

方式三:借助于dango的缓存使用

-如果配置文件中配置了 CACHES  ,以后django的缓存,数据直接放在redis中
-以后直接使用cache.set 设置值,可以传过期时间
-使用cache.get 获取值
-强大之处在于,可以直接缓存任意的python对象,底层使用pickle实现的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/6943.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

离散数学:图的基本概念

本帖子讨论图的基本概念,这一章,我们将利用有序对和二元关系的概念定义图。图分为了无向图和有向图,他们有共性也有区别,请大家注意体会,用联系和辩证的观点去认识。 1、无向图和有向图 注意无向图和有向图的表示&…

Servlet【 ServletAPI中的会话管理Cookie与Session】

Servlet【 ServletAPI中的会话管理Cookie与Session】🍒一.回顾Cookie与Session🍎1.1 Cookie🍎1.2 Session🍎1.3Cookie 和 Session 的区别🍒二.Servlet会话管理操作🍎2.1核心方法🍒三.常见案例实…

【服务器搭建】教程一:没钱买服务器怎么玩 进来看

前言: 最近看到有一些网上的大佬把自己的爱心网页(没领到的小伙伴看一下前几篇文章)部署到了自己的服务器上,使得可以直接通过链接就实现访问。属实不错! 自己内心就产生了这样一个想法:购买一台服务器&a…

Whisper论文阅读笔记

Whisper论文阅读笔记Robust Speech Recognition via Large-Scale Weak Supervision1. 引言2. 方法2.1 数据处理2.2 模型2.3 多任务设置2.4 训练细节3. 实验结果3.1 Zero-shot3.2 多语言语音识别3.3 多语言机器翻译3.4 语种检测3.5 对加性噪声的鲁棒性3.6 长语音转录3.7 人类基线…

基于向量加权平均值的高效优化算法(Matlab代码实现)

📝个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,…

学习 RabbitMQ 这一篇就够了

文章目录一、MQ相关概念二、RabbitMQ相关概念三、安装四、HelloWorld五、工作队列5.1、轮询分发消息5.2、消息应答5.2.1、自动应答5.2.2、手动应答5.2.3、消息自动重新入队5.2.4、消息手动应答代码5.3、持久化5.4、不公平分发(能者多劳)5.5、预取值5.6、…

读书笔记3|使用Python,networkx对卡勒德胡赛尼三部曲之——《群山回唱》人物关系图谱绘制

读书笔记3|《群山回唱》-卡勒德胡赛尼 踉跄前行中,你总能在他们身上找到丢失的那一部分记忆。 一度看不下去这本书,因为最开始的章节里太痛了,加上我也离开我的孩子,生活已经够苦,我需要一点糖。这次实在太无聊了&…

php-上传图片加水印(文字水印图片水印)

img.php <?php $img 1.jpg; //获取图片信息 $info getimagesize($img); //获取图片类型 $type image_type_to_extension($info[2],false); //在内容中创建一个和图片一模一样的图片 $ext "imagecreatefrom{$type}"; //图片复制到内存中 $image $ext($img);…

基于SpringBoot前后端分离的网吧管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目…

PICO《轻世界》体验:随心畅玩,洒脱创作,潜力无限

不少玩家应该还记得&#xff0c;PICO 4发布会上曾宣布将在VR运动健身、VR视频、VR娱乐、VR创造四大方向展开内容布局。而目前&#xff0c;前三个完成了基本部署&#xff0c;在创造方向上则依托于刚刚上线的《轻世界》这款应用。《轻世界》是一款3D内容UGC创作产品&#xff0c;目…

php宝塔部署实战thinkphp考试平台管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 有个朋友发消息跟我说&#xff0c;在网上下载了一套thinkphp考试管理系统的源码&#xff0c;在搭建的时候遇到问题一直部署不起来&#xff0c;让我帮他看看&#xff0c;我看了下代码&#xff0c;里面有些部分代码…

2022年11月华南师范大学自考本科网络工程-本科实践题目

《互联网及其应用&#xff08;03142&#xff09;&#xff08;实践&#xff09;》课程试卷 答卷提交说明&#xff1a;编程代码与输出结果截图&#xff0c;放到一个文件中&#xff0c;文件以“序号 姓名 课程名 ”命名&#xff0c;本试卷有三门课程&#xff0c;请根据不同的课程…

k8s训练营

一、linux命名空间和docker 1.linux的7大ns--------------ipc,net,pid,mnt.uts.user 查看linux的ns lsns查看不同类型的ns [rootmaster ~]# lsns -t netNS TYPE NPROCS PID USER COMMAND 4026531956 net 116 1 root /usr/lib/systemd/systemd --system --deserialize …

公司代码全局参数设置及其意义

在SAP中配置公司时&#xff0c;会配置公司的全局参数&#xff0c;但这些参数具体的意思是什么估计很多同学都搞不懂&#xff0c;我也找了下资料&#xff0c;贴出来供大家参考。 设置参数路径&#xff1a;IMG→财务会计→财务会计全局设置→公司代码的全球参数→输入全局参数 账…

C++Qt开发——Linguist语言家

Qt Linguist 简介 Qt提供了一款优秀的支持Qt C和Qt Quick应用程序的翻译工具。发布者、翻译者和开发者可以使用这款工具来完成他们的任务。 发布者&#xff1a;承担了全面发布应用程序的责任。通常&#xff0c;他们协调开发者和翻译者的工作&#xff0c;可以使用lupdate工具…

激光雷达的厮杀18年:西方“诸神黄昏”,东方“新王隐现”

鼻祖、发明家、神童、梦想家、特种兵和中国双星&#xff0c;激光雷达“诸神混战”&#xff0c;行业疯狂洗牌。 风云激荡中&#xff0c;每个人都在亲身见证历史。 2004年&#xff0c;美国发起DARPA挑战赛&#xff0c;无人车上路&#xff0c;汽车上首次出现激光雷达。 2010年之…

原型工具墨刀的使用

刚开始接触原型工具是大学时候了&#xff0c;大学参加大创的时候第一次接触并使用原型工具做了小程序项目原型。那时候是下载的客户端。 最近&#xff0c;又开始思考在用户沟通过程中为方便沟通&#xff0c;可以先自己用原型工具简单的设计一下先。 首先&#xff1a;网页版好用…

JavaScript流程控制-循环(循环(for 循环,双重 for 循环,while 循环,do while 循环,continue break))

目录 JavaScript流程控制-循环 循环 for 循环 执行过程&#xff1a; 断点调试&#xff1a; 案例一&#xff1a;求1-100之间所有整数的累加和 案例二&#xff1a;求1-100之间所有数的平均值 案例三&#xff1a;求1-100之间所有偶数和奇数的和 案例四&#xff1a;求1-10…

哈希(Hash) - 开散列/闭散列

文章目录&#xff1a;认识哈希哈希函数处理冲突的方法闭散列&#xff08;开放定址法&#xff09;开散列&#xff08;链地址法&#xff09;哈希表闭散列实现闭散列基本框架哈希表闭散列插入&#xff08;insert&#xff09;哈希表闭散列删除&#xff08;erase&#xff09;哈希表闭…

深度学习模型部署全流程-模型部署

往期回顾&#xff1a;模型训练 文章目录前言模型部署全流程1.推理框架2.onnx模型3.模型转换4.代码实现5.完整代码小结前言 在上一篇文章中详细讲述了模型训练的流程&#xff0c;这篇文章主要介绍模型部署的流程。模型部署通常指通过C/C语言能够把python框架训练好的模型跑起来…