• Redis 数据类型


    Redis 系列之 API 的使用

    通用命令

    ####1-keys 
    #打印出所有key
    keys * 
    #打印出所有以he开头的key
    keys he*
    #打印出所有以he开头,第三个字母是h到l的范围
    keys he[h-l]
    #三位长度,以he开头,?表示任意一位
    keys he?
    #keys命令一般不在生产环境中使用,生产环境key很多,时间复杂度为o(n),用scan命令
    
    ####2-dbsize   计算key的总数
    dbsize #redis内置了计数器,插入删除值该计数器会更改,所以可以在生产环境使用,时间复杂度是o(1)
    
    ###3-exists key 时间复杂度o(1)
    #设置a
    set a b
    #查看a是否存在
    exists a
    (integer) 1
    #存在返回1 不存在返回0
    
    ###4-del key  时间复杂度o(1)
    删除成功返回1,
    
    ###5-expire key seconds  时间复杂度o(1)
    expire name 3 #3s 过期
    ttl name  #查看name还有多长时间过期
    persist name #去掉name的过期时间
    
    ###6-type key  时间复杂度o(1)
    type name #查看name类型,返回string
    

    数据结构和内部编码

    image-20191224110401405

    单线程架构

    一个瞬间只会执行一条命令

    image-20191224111010657

    单线程为什么这么快

    1 纯内存

    2 非阻塞 IO(epoll),自身实现了事件处理,不在网络 IO 上浪费过多时间

    3 避免线程间切换和竞太消耗

    注意

    1 一次值运行一条命令

    2 拒绝长慢命令

    ​ keys,flushall,flushdb,慢的lua脚本,mutil/exec,operate,big value

    3 其实不是单线程(在做持久化是另外的线程)

    ​ -fysnc file descriptor

    ​ -close file descriptor

    Redis 数据类型

    数据操作:字符串、列表、哈希(字典)、无序集合、有序(排序)集合

    有序集合:游戏排行榜

    字符串

    一、字符串String ----String Key-Value
    
      字符串是Redis中最常用的类型,是一个由字节组成的序列,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据。
    Value最多可以容纳的数据长度为512MB。
    set key value 
    往key中存入一个值(value)
    get key 
    获取键为key的值
      注意:redis中的Key和Value时区分大小写的,命令不区分大小写, redis是单线程 不适合存储大容量的数据
      incr key   ---对应的value 自增1,如果没有这个key值 自动给你创建创建 并赋值为1
      decr key   ---对应的value 自减1
       注意:自增的value是可以转成数字的
       
       
    字符串:
    	set key value
    	get key
    	mset k1 v1 k2 v2 ...
    	mget k1 k2 ...
    	setex key exp value
    	incrby key increment
    

    常用命令

    ###1---基本使用get,set,del
    get name       #时间复杂度 o(1)
    set name lqz   #时间复杂度 o(1)
    del name       #时间复杂度 o(1)
    
    ###2---其他使用incr,decr,incrby,decrby
    incr age  #对age这个key的value值自增1
    decr age  #对age这个key的value值自减1
    incrby age 10  #对age这个key的value值增加10
    decrby age 10  #对age这个key的value值减10
    #统计网站访问量(单线程无竞争,天然适合做计数器)
    #缓存mysql的信息(json格式)
    #分布式id生成(多个机器同时并发着生成,不会重复)
    
    ###3---set,setnx,setxx
    set name lqz  #不管key是否存在,都设置 
    setnx name lqz #key不存在时才设置(新增操作)
    set name lqz nx #同上
    set name lqz xx #key存在,才设置(更新操作)
    
    ###4---mget mset
    mget key1 key2 key3     #批量获取key1,key2.。。时间复杂度o(n)
    mset key1 value1 key2 value2 key3 value3    #批量设置时间复杂度o(n)
    #n次get和mget的区别
    #n次get时间=n次命令时间+n次网络时间
    #mget时间=1次网络时间+n次命令时间
    
    ###5---其他:getset,append,strlen
    getset name lqznb #设置新值并返回旧值 时间复杂度o(1)
    append name 666 #将value追加到旧的value 时间复杂度o(1)
    strlen name  #计算字符串长度(注意中文)  时间复杂度o(1)
    
    ###6---其他:incrybyfloat,getrange,setrange
    increbyfloat age 3.5  #为age自增3.5,传负值表示自减 时间复杂度o(1)
    getrange key start end #获取字符串制定下标所有的值  时间复杂度o(1)
    setrange key index value #从指定index开始设置value值  时间复杂度o(1)
    

    列表

    二、列表 List
    Redis的列表允许用户从序列的两端推入或者弹出元素,列表由多个字符串值组成的有序可重复的序列,是链表结构,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。
    这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。List中可以包含的最大元素数量是4294967295。
    
    应用场景:
    1.最新消息排行榜。
    2.消息队列,以完成多程序之间的消息交换。可以用push操作将任务存在list中(生产者),然后线程在用pop操作将任务取出进行执行。(消费者)
    
    List有顺序可重复
    
    
    列表:
    	rpush key value1 value2 ...
    	lpush key value1 value2 ...
    	lrange key bindex eindex
    	lindex key index
    	lpop key | rpop key
    	 key before|after old_value new_value
    

    有序队列,可以从左侧添加,右侧添加,可以重复,可以从左右两边弹出

    API操作

    插入操作

    #rpush 从右侧插入
    rpush key value1 value2 ...valueN  #时间复杂度为o(1~n)
    #lpush 从左侧插入
    #linsert
    linsert key befort|after value newValue   #从元素value的前或后插入newValue 时间复杂度o(n) ,需要便利列表
    linsert listkey before b java
    linsert listkey after b php
    

    删除操作

    lpop key #从列表左侧弹出一个item 时间复杂度o(1)
    
    rpop key #从列表右侧弹出一个item 时间复杂度o(1)
    
    lrem key count value
    #根据count值,从列表中删除所有value相同的项 时间复杂度o(n)
    1 count>0 从左到右,删除最多count个value相等的项
    2 count<0 从右向左,删除最多 Math.abs(count)个value相等的项
    3 count=0 删除所有value相等的项
    lrem listkey 0 a #删除列表中所有值a
    lrem listkey -1 c #从右侧删除1个c
    
    ltrim key start end #按照索引范围修剪列表 o(n)
    ltrim listkey 1 4 #只保留下表1--4的元素
    

    查询操作

    lrange key start end #包含end获取列表指定索引范围所有item  o(n)
    lrange listkey 0 2
    lrange listkey 1 -1 #获取第一个位置到倒数第一个位置的元素
    
    lindex key index #获取列表指定索引的item  o(n)
    lindex listkey 0
    lindex listkey -1
    
    llen key #获取列表长度
    

    修改操作

    lset key index newValue #设置列表指定索引值为newValue o(n)
    lset listkey 2 ppp #把第二个位置设为ppp
    

    其他操作

    blpop key timeout #lpop的阻塞版,timeout是阻塞超时时间,timeout=0为拥有不阻塞 o(1)
    brpop key timeout #rpop的阻塞版,timeout是阻塞超时时间,timeout=0为拥有不阻塞 o(1)
    
    #要实现栈的功能
    lpush+lpop
    #实现队列功能
    lpush+rpop
    #固定大小的列表
    lpush+ltrim
    #消息队列
    lpush+brpop
    

    哈希

    三、哈希 Hash
    相当于是一个key中存在多个map。
    Redis中的散列可以看成具有String key和String value的map容器,
    可以将多个key-value存储到一个key中。每一个Hash可以存储4294967295个键值对。
    
    
    哈希:
    	hset key field value
    	hget key field
    	hmset key field1 value1 field2 value2 ...
    	hmget key field1 field2
    	hkeys key
    	hvals key
    	hdel key field
    

    image-20191224121323414

    重要 API

    ###1---hget,hset,hdel
    hget key field  #获取hash key对应的field的value 时间复杂度为 o(1)
    hset key field value #设置hash key对应的field的value值 时间复杂度为 o(1)
    hdel key field #删除hash key对应的field的值 时间复杂度为 o(1)
    #测试
    hset user:1:info age 23
    hget user:1:info ag
    hset user:1:info name lqz
    hgetall user:1:info
    hdel user:1:info age
            
    ###2---hexists,hlen
    hexists key field  #判断hash key 是否存在field 时间复杂度为 o(1)
    hlen key   #获取hash key field的数量  时间复杂度为 o(1)
    hexists user:1:info name
    hlen user:1:info  #返回数量
            
    ###3---hmget,hmset
    hmget key field1 field2 ...fieldN  #批量获取hash key 的一批field对应的值  时间复杂度是o(n)
    hmset key field1 value1 field2 value2  #批量设置hash key的一批field value 时间复杂度是o(n)
    
    ###4--hgetall,hvals,hkeys
    hgetall key  #返回hash key 对应的所有field和value  时间复杂度是o(n)
    hvals key   #返回hash key 对应的所有field的value  时间复杂度是o(n)
    hkeys key   #返回hash key对应的所有field  时间复杂度是o(n)
    ###小心使用hgetall
    ##1 计算网站每个用户主页的访问量
    hincrby user:1:info pageview count
    ##2 缓存mysql的信息,直接设置hash格式
    

    hash vs string

    相似的api

    get hget
    set /sentnx hset hsetnx
    del hdel
    incr incrby dear decrby hincrby
    mset hmset
    mget hmget

    缓存三种方案

    直接json格式字符串

    每个字段一个key

    使用hash操作

    ##其他操作 hsetnx,hincrby,hincrbyfloat
    hestnx key field value #设置hash key对应field的value(如果field已存在,则失败),时间复杂度o(1)
    hincrby key field intCounter #hash key 对英的field的value自增intCounter 时间复杂度o(1)
    hincrbyfloat key field floatCounter #hincrby 浮点数 时间复杂度o(1)
    
    

    集合

    四、集合 Set
    Redis的集合是无序不可重复的,此处的无序是数据不能重复。
    和列表一样,在执行插入和删除以及判断是否存在某元素时,效率是很高的。
    集合最大的优势在于可以进行交集并集差集操作。
    Set可包含的最大元素数量是4294967295。
    
    应用场景:
    1.利用交集求共同好友。
    2.利用唯一性,可以统计访问网站的所有独立IP。
    3.好友推荐的时候根据tag求交集,大于某个threshold(临界值的)就可以推荐。
    4.标签,社交
    
    
    集合:
    	sadd key member1 member2 ...
    	sdiff key1 key2 ...差集,我有你没有
    	sdiffstore newkey key1 key2 ...保存差集,对称差集
    	sinter key1 key2 ...交集,都有的
    	sunion key1 key2 ...并集,所有加起来
    	smembers key  查看所有成员
    	spop key	删除
    

    无序,无重复,集合间操作(交叉并补)

    API 操作

    sadd key element #向集合key添加element(如果element存在,添加失败) o(1)
    
    srem key element #从集合中的element移除掉 o(1)
    
    scard key #计算集合大小
    
    sismember key element #判断element是否在集合中
    
    srandmember key count #从集合中随机取出count个元素,不会破坏集合中的元素
    
    spop key #从集合中随机弹出一个元素
    
    smembers key #获取集合中所有元素 ,无序,小心使用,会阻塞住 
    
    sdiff user:1:follow user:2:follow  #计算user:1:follow和user:2:follow的差集
    
    sinter user:1:follow user:2:follow  #计算user:1:follow和user:2:follow的交集
              
    sunion user:1:follow user:2:follow  #计算user:1:follow和user:2:follow的并集
                    
    sdiff|sinter|suion + store destkey... #将差集,交集,并集结果保存在destkey集合中
    

    sadd:可以做标签相关

    spop/srandmember:可以做随机数相关

    sadd/sinter:社交相关

    有序集合

    五、有序集合 SortedSet(zSet)
    
    有顺序,不能重复!!此处的不能重复是索引为唯一的,分数却可以重复。
    和Set很像,都是字符串的集合,都不允许重复的成员出现在一个set中。
    他们之间差别在于有序集合中每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。
    尽管有序集合中的成员必须是唯一的,但是分数(score)却可以重复。
    
    应用场景:可以用于一个大型在线游戏的积分排行榜,每当玩家的分数发生变化时,可以执行zadd更新玩家分数(score),此后在通过zrange获取几分top ten的用户信息。
    
    适合做排行榜,排序需要一个分数属性
    排行榜,社交
    
    
    有序集合:
    	zadd key 9 kai 9 santa 8 leti ... # 添加
    	zincrby key 10 kai  # kai 的分数加 10
    	zrange key 0 3   # 后三名
    	zrevrange key 0 3   # 前三名
    

    特点

    #有一个分值字段,来保证顺序
    key                  score                value
    user:ranking           1                   lqz
    user:ranking           99                  lqz2
    user:ranking           88                  lqz3
        
    #集合有序集合
    集合:无重复元素,无序,element
    有序集合:无重复元素,有序,element+score
    
    #列表和有序集合
    列表:可以重复,有序,element
    有序集合:无重复元素,有序,element+score
    

    API 使用

    zadd key score element #score可以重复,可以多个同时添加,element不能重复 o(logN) 
    
    zrem key element #删除元素,可以多个同时删除 o(1)
    
    zscore key element #获取元素的分数 o(1)
    
    zincrby key increScore element #增加或减少元素的分数  o(1)
    
    zcard key #返回元素总个数 o(1)
    
    zrank key element #返回element元素的排名(从小到大排)
    
    zrange key 0 -1 #返回排名,不带分数  o(log(n)+m) n是元素个数,m是要获取的值
    zrange player:rank 0 -1 withscores #返回排名,带分数
    
    zrangebyscore key minScore maxScore #返回指定分数范围内的升序元素 o(log(n)+m) n是元素个数,m是要获取的值
    zrangebyscore user:1:ranking 90 210 withscores #获取90分到210分的元素
    
    zcount key minScore maxScore #返回有序集合内在指定分数范围内的个数 o(log(n)+m)
    
    zremrangebyrank key start end #删除指定排名内的升序元素 o(log(n)+m)
    zremrangebyrank user:1:rangking 1 2 #删除升序排名中1到2的元素
            
    zremrangebyscore key minScore maxScore #删除指定分数内的升序元素 o(log(n)+m)
    zremrangebyscore user:1:ranking 90 210 #删除分数90到210之间的元素
    
    

    其他操作

    zrevrank #从高到低排序
    zrevrange #从高到低排序取一定范围
    zrevrangebyscore #返回指定分数范围内的降序元素
    zinterstore #对两个有序集合交集
    zunionstore #对两个有序集合求并集
    
    操作类型 命令
    基本操作 zadd/ zrem/ zcard/ zincrby/ zscore
    范围操作 zrange/ zrangebyscore/ zcount/ zremrangebyrank
    集合操作 zunionstore/ zinterstore
  • 相关阅读:
    day 46
    day 45 JavaScript 下 函数
    day 42 css 样式
    44 JavaScript
    41 前端
    40 协程 i/0多路复用
    39 线程池 同一进程间的队列
    38 线程 锁 事件 信号量 利用线程实现socket 定时器
    37 生产者消费者模型 管道 进程间的数据共享 进程池
    演示使用string对象
  • 原文地址:https://www.cnblogs.com/kai-/p/12403103.html
Copyright © 2020-2023  润新知