이 문서에서는 몇 가지 일반적인 Redis 데이터 구조와 몇 가지 일반적인 지침을 정리하고 공유할 것입니다. 모든 사람에게 도움이 되기를 바랍니다.
Java 배경 지식이 있는 사람은 배열, 큐, 스택 등과 같이 일반적으로 사용되는 몇 가지 데이터 구조를 알아야 합니다. 그러면 Redis의 데이터 구조와 Java의 데이터 구조의 차이점은 무엇입니까? 대답은 '예'입니다. Map에 대해 알고 있는 친구들은 Map에 Key 값과 Value 값이 있다는 것을 알고 있습니다. Redis의 데이터 구조도 이와 같습니다.
Redis 데이터 구조: String, List, Hash 및 Set은 모두 키 값과 값 값을 갖습니다.
Key 값은 이름이고 Value 값은 데이터입니다. 이 두 가지는 서로 결합되어 있으며 키 값은 값 값에 해당합니다. 이를 키-값 쌍이라고 합니다. [관련 권장 사항: Redis 동영상 튜토리얼]
Redis에서는 다양한 시나리오에서 다양한 명령이 사용됩니다. 하지만 모든 명령을 기억할 필요는 없나요? 아니요, 가장 일반적으로 사용되는 명령에 익숙해지면 됩니다. 덜 일반적으로 사용되는 명령을 사용해야 하는 경우 공식 문서를 확인하세요. 다음은 Redis에서 일반적으로 사용되는 몇 가지 명령입니다.
1.# exists(判断key值是否存在):如果存在返回1,反之返回0 例子: exists name(name为key) 2.# del(删除key): 删除成功返回1,反之返回0 3.# type(判断key的类型) 4.ttl(查看key存活时间
더 많은 명령을 알고 싶다면 중국어 문서로 이동하여 쿼리할 수 있습니다. http://www.redis.cn/
문자열 유형이 가장 기본입니다. Redis 유형의 데이터는 Redis에서 광범위한 애플리케이션 시나리오를 갖습니다. 하나의 키는 하나의 값에 해당합니다.
Redis' String은 동적 문자열이며 수정 가능한 문자열입니다. 내부 구조는 사전 할당된 중복 공간을 사용하여 메모리 할당을 줄이는 Java의 ArrayList와 유사합니다.
문자열 유형은 바이너리 안전하므로 Redis 문자열에는 모든 데이터가 포함될 수 있습니다. 예: 숫자, 문자열, 그림 등
문자열 유형 응용 시나리오: 인증 코드, 카운터, 반복 주문 제출, 사용자 로그인 정보, 제품 세부 정보 구현
1.# set/get 设置和获取key-value 注意中间一定要加空格 例子: set xxx(key) xxx(value) get xxx(key) 2.# mget/mset 批量设置或获取多个key的值 mset user:name jack user:age 2 mget user:name user:age 3.# incr incr对key对应的值进行加1操作,并返回新的值 incr video:uv:1 4. # incrby 将key对应的数字加increment.如果key不存在,操作之前,key就会被置为0 incrby video:uv:1 10 5.# setex 设置key对应字符串value,并且设置key在给定的seconds时间之后超时过期操作 setex code 20 778899 (设置一个key为code value为778899 20秒后过期)4 6. # setnx 将key设置值为value,如果存在该key那么什么都不做,如果不存在key那么等同于set命令 setnx name xdclass.net 7. # getset 设置key的值,并返回key旧的值 get name uuuuu (这时会返回xdclass.net,重新在get一下会获得重新设置的值uuuuu)
참고: 값 길이는 512MB를 초과할 수 없으며 주요 명명 규칙을 따릅니다. 비즈니스 이름: 표시: ID(너무 길지 않고 콜론으로 구분)
C 언어는 다음과 같습니다. Redis에서는 사용되지 않음 전통적인 문자열을 표현하는 대신 SDS(Simple Dynamic String)라는 추상 유형이 구성됩니다. Redis가 C 언어에서 문자열을 직접 사용하는 대신 자체 구축 SDS를 사용하는 이유는 무엇입니까? 그 이유는 실제로 Redis 작업의 성능을 향상시키기 위한 매우 간단합니다.
문자열 길이를 얻기 위한 지속적인 복잡성: C 언어가 길이를 얻으려면 전체 문자열을 순회해야 합니다. len 속성을 통해 SDS 문자열 길이를 얻는 SDS의 시간 복잡도가 O(N)에서 O(1)로 변경되어 문자열 길이를 얻는 것이 Redis의 성능 병목 현상이 되지 않도록 합니다.
수정으로 인한 메모리 재할당 횟수 줄이기: 메모리 재할당은 문자열을 수정할 때 메모리 공간이 부족하거나 과도하여 메모리 재할당 작업을 수행해야 함을 의미합니다. 이 작업에는 메모리가 관련되므로 시간이 걸립니다. 비용이 높으므로 메모리 재할당을 피해야 합니다. SDS에는 len과 free라는 두 가지 속성이 있으며 최적화 전략을 사용하여 메모리 재할당 수를 줄일 수 있습니다.
직접 말하면 List 유형은 연결 리스트입니다, 요소를 삽입한 후 순서대로 정렬되고 값이 반복될 수 있으며, 해당 첨자 값을 통해 해당 값을 얻을 수 있으며, 연결된 목록의 양쪽에 데이터를 삽입하고 삭제할 수 있습니다. 삽입하는 동안 키가 존재하지 않으면 Redis는 해당 키에 대한 새 연결 목록을 생성합니다. 반대로 연결리스트의 모든 요소가 삭제되면 키도 삭제됩니다.
응용 시나리오: 단순 대기열, 최신 댓글 목록, 비실시간 순위 목록: 휴대폰 일일 판매 목록과 같은 순위 목록 예약 계산
1. # lpush 将一个或多个值插入到列表头部 lpush phone:rank:daily iphone6 2. # rpop 移除并获取列表的最后一个元素 rpor phone:rank:daily 3. # llen 获取列表长度 llen phone:rank:daily 4. # lrange 获取key对应的list的指定下标范围元素,其中0表示列表的第一个元素,-1表示获取列表的所有元素 lrange phone:rank:daily 0 -1 5. # rpush 在key对应的list尾部添加一个元素 rpush phone:rank:daily xiaodi 6. # lpop 从key对应的List的尾部删除一个元素,并返回该元素 lpop phone:rank:daily 7. # bropo 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 brpop phone:rank:daily 20 8. # lrem 移除元素 lrem phone:rank:daily 2 a
지금까지 List의 일반적인 명령어 사용법을 배웠습니다. 이제 List의 기본 구조를 살펴보겠습니다.
List에는 두 가지 구현 방법이 있습니다
압축 연결 목록(ziplist): Redis에서 메모리 공간을 절약하기 위해 개발했습니다. 특수하게 인코딩된 연속 메모리 블록으로 구성된 순차 데이터 구조입니다. , 그 초점은 메모리 연속성입니다!
双端链表:使用prev和next这两个指针,是可以从前向后也可以从后向前来实现lpush和rpush这些指令。因为是链表,所以也导致了lindex指令获取某个元素需要遍历链表才能获取得到。时间复杂度O(n)。
当列表的对象同时满足下述两个条件时,列表对象采用压缩链表编码:
(1)列表对象保存的所有元素长度都小于64个字节;
(2)列表元素所保存的元素个数小于512个
在Redis3.2之后,采用的是快速链表-quicklist。quicklist是一个双向链表,并且它还是一个有ziplist特性的双向链表,就是说quicklist每个节点都是ziplist。这个快速链表结合了两者的优点。
Redis中的Hash类型是一个String类型的field和value的映射表,Hash特别适合用于存储对象,Hash类似于Map结构。因为在Redis里,Hash又是另外的一种键值对结构,而Redis本身就是key-value类型,所以这个Hash结构是套在了Redis下的value里。
下面说说Hash的底层数据结构:
一种是ziplist , 当存储的数据超过所配置的数量大小时就是转成Hashtable这种结构。这种转换会比较消耗性能,所以尽量少用这种转换操作。
另一种就是hashtable , 这种结构的时间复杂度为O(1),但是会比较消耗内存空间。
对于Hash在Redis中的应用场景:购物车、用户个人信息、商品详情的实现
1. # hset 设置key指定的哈希集指定字段的值 hset product:detail:1 title iphone11 2. # hget 返回key指定的哈希集中该字段所关联的值 hget product:detail:1 title 3. # hgetall 返回key指定的哈希集中所有的字段和值 hegetall product:detail:1 4. # hdel 从key指定的哈希集中移除指定的域 hdel product:detail:1 title 5. # hexists 返回hash里面的field是否存在 hexists product:detail:1 title (存在返回1,不存在返回0) 6. # hincrby 增加key指定的哈希集中的指定字段的数值,如果是-1则是递减 hincrby product:detail:1 key 1 (对key里的value值进行递增或递减) 7. # hmset 设置key指定的哈希集中指定字段的值 hmset product:detail:2 title xiaomi price 1000 stock 10 8. # hmget 返回key指定的哈希集中指定字段的值 hmget product:detail:2 title price
注意: 每个Hash可以存储232-1键值对
Redis中的Set类型是一个集合,集合的概念是一堆不重复的组合。利用Redis提供的Set数据结构可以存储一些集合性的数据。因为Redis很友好的为集合提供了求集、并集、差集等操作( PS:不懂的同学可以问下以前的数学老师哦~哈哈哈哈),那么就可以非常方便的实现共同关注、共同喜好等功能。对上面的集合操作,你还可以使用不同的命令选择奖结果返回给客户端还是存集合到一个新的集合中。
Redis中Set应用场景:去重、社交应用关注(粉丝,共同好友)、统计网站PV(UV、IP)大数据里面的用户画像标签集合
1. # sadd 添加一个或多个指定的元素到集合中,如果指定的元素已经在集合key中则忽略 sadd user:tags female sadd user:tags bmw 2. # scard 返回集合存储的key的基数(集合元素的数量) scard user:tags 3. # sdiff 返回的集合元素是第一个key集合与后面所有key集合的差集 sdiff user:tags:1 user:tags:2 4. # sinter 返回指定所有的集合的成员的交集 sinter user:tags:1 user:tags:2 5. # sismember 返回成员是否有存储的集合key的成员 sismember user:tags:1 bmw 6. # srem 在集合中移除指定的元素,如果指定元素不是key集合中的则忽略 srem user:tags:1 bmw 7. # sunion 返回给定的多个集合的并集所有的成员 sunion user:tags:1 user:tags:2
和Set相比,SortedSet是将Set中的元素增加了一个权重参数score,使得集合中的元素能够按 score进行有序排序,比如存储一个存储班上同学成绩的SortedSet集合,该集合value可以设为同学的学号,然而score就可以是考试成绩。这样才插入数据的时候,就已经为数据进行了排序。另外,SortedSet还可以用来做带权重的队列。
应用场景:实时排行榜、优先级任务(队列)、朋友圈(文章)点赞-取消
跳跃表实则是一个链表,在传统的链表中想要查找一个元素就要从最原始的地方开始查找,直到查找到该元素。在跳跃表中呢,它会把链表进行抽层,抽层的时候会隔几个元素分为一个节点,抽层之后也是一条链表,节点会变少了。如下图所示,当要寻找元素78时,如果是寻常的链表就会从左往右挨个查询,这时查询了8次才能找带该元素。当使用跳跃表后,从第二层的开始出发,当查询到79这个节点时发现没有78,则返回到57这个节点再返回第一层去寻找该元素。
1.# zadd 向有序集合里添加一个或者多个成员,或者更新已存在成员的分数 zadd video:rank 90 springcloud zadd video:rank 80 springboot zadd video:rank 50 redis 2.# zcard 获取有序集合的成员数 zcard video:rank 3.# zcount 计算在有序集合中指定的区间分数的成员数 zcount video:rank 0 60 4.# zincrby 在有序集合中对指定成员的分数加上增量 zincrby video:rank 2 springcloud 5.# zrange 通过索引区间返回有序集合指定内的成员,成员位置分数按(从小到大排序) zrange voideo:rank 0 -1 zrange voideo:rank 0 -1 withscores(返回分数) 6.# zrevrange 通过索引集合中指定成员的排名,其中有序集合成员按score值递增(从大到小排序) zrevrange voideo:rank 0 -1 7.# zrevrank 返回有序集合中指定的成员排名,有序集合成员按分数递减(从大到小排序) zrevrank voideo:rank springcloud 8.# zrank 返回有序集key中成员member的排名,其中有序集成员按score值递增(从小到大排序) zrank voideo:rank 9.# zrem 移除有序集合中的一个或者多个成员 zrem voideo:rank redis 10.# zscore 返回有序集合中的成员分数值 zscore voideo:rank springcloud
好啦Redis的数据类型都整理好了,如果文章对你有帮助的话记得点点赞哈,可以的话也点点关注哦。求求各位大哥啦。
更多编程相关知识,请访问:编程入门!!
위 내용은 몇 가지 일반적인 Redis 데이터 구조 구성(요약)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!