redis五种数据类型学习笔记

Redis内存数据库

查询发生全量i/o
内存和磁盘读写速度相差五到十万倍

GBK 中一个汉字占两个字节
UTF-8中的一个汉字占三个字节


Set key1 中
STRLEN key1 3

Set key2 123
STRLEN key2 3


Redis2.8单机安装,3.0以后的版本才支持集群安装
  • 编译安装:
    • yum -y install gcc tcl -y
    • tar xf redis-2.8.18.tar.gz
    • make
    • make PREFIX=/opt/sxt/redis install
    • export REDIS_HOME=/opt/sxt/redis
    • export PATH=$PATH:$REDIS_HOME/bin
  • utils目录:
    • ./install_server.sh
  • 启动:
    • 程序+配置:不同的配置产生多个实例程序
    • 端口号,持久化数据目录

  • Redis key 值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如”foo”的简单字符串到一个JPEG文件的内容都可以。空字符串也是有效key值
  • Key取值原则
键值不需要太长,消耗内存,且在数据中查找这类键值的计算成本较高
键值不宜过短,可读性较差


String:
  • String:(strlen)
    • 基本操作是字符串操作,追加,截取
      • set,get,apend。。。。。。
    • 数值类型计算
    • 位图
  • 字符串是一种最基本的Redis值类型。Redis字符串是二进制安全的,这意味着一个Redis字符串能包含任意类型的数据
例如: 一张JPEG格式的图片或者一个序列化的Ruby对象
  • 一个字符串类型的值最多能存储512M字节的内容
  • key : string
  • value: string
登录客户端后,获取帮助
Help
Help <tab>
Help set
Help @string


  • 设置字符串值 set get
    • SET key value [EX seconds] [PX milliseconds] [NX|XX]
      • EX 设置过期时间,秒,等同于SETEX key seconds value
      • PX 设置过期时间,毫秒,等同于PSETEX key milliseconds value
      • NX 键不存在,才能设置,等同于SETNX key value
      • XX 键存在时,才能设置
  • 设置多个键的字符串值
    • MSET key value [key value ...] mget
  • 键不存在时,设置字符串值
    • MSETNX key value [key value ...]
    • 注意:这是原子操作


事例: set s1 abc
set s2 12
set se abc ex 15
mset s3 3 s4 4 s5 5
msetnx s5 A5 s6 6

  • 过期
    • Redis中可以给Key设置一个生存时间(秒或毫秒),当达到这个时长后,这些键值将会被自动删除
  • 设置多少秒或者毫秒后过期
    • EXPIRE key seconds
    • get key
    • set key val ex 10
    • PEXPIRE key milliseconds
  • 设置在指定Unix时间戳过期
    • EXPIREAT key timestamp
    • PEXPIREAT key milliseconds-timestamp
  • 删除过期
    • PERSIST key
  • 生存时间
    • Time To Live,Key的剩余生存时间
  • 查看剩余生存时间
    • TTL key
    • PTTL key
    • key存在但没有设置TTL,返回-1
    • key存在,但还在生存期内,返回剩余的秒或者毫秒
    • key曾经存在,但已经消亡,返回-2(2.8版本之前返回-1)

事例:set se abc ex 15
ttl s6
expire s6 60
pttl s6
persist s6
pttl s6
EXPIREAT cache 1355292000
PEXPIREAT mykey 1555555555005

  • 查找键
    • KEYS pattern
    • pattern取值
    • * 任意长度字符
    • ? 任意一个字符
    • [] 字符集合,表示可以是集合中的任意一个
事例: keys s*
keys s?
keys s[13]
keys *
keys ??

  • 键类型
    • TYPE key
    • object encoding key
  • 键是否存在
    • EXISTS key
  • 键重命名
    • RENAME key newkey
    • RENAMENX key newkey
  • 键删除
    • DEL key [key ...]

  • 获取值
    • GET key
  • 获取多个给定的键的值
    • MGET key [key ...]
  • 返回旧值并设置新值
    • GETSET key value
    • 如果键不存在,就创建并赋值
  • 字符串长度
    • STRLEN key

  • object encoding key > val 底层存储的数据结构类型

  • 追加字符串
    • APPEND key value
    • 如果键存在就追加;如果不存在就等同于SET key value
  • 获取子字符串 索引
    • GETRANGE key start end
    • 0 3
    • 索引值从0开始,负数表示从字符串右边向左数起,-1表示最有一个字符
    • 01234
    • 1a2a3a
    • -5 -4 -3 -2 -1
  • 覆盖字符串
    • SETRANGE key offset value

事例: APPEND s6 123
getrange s1 1 2
getrange s1 0 -1
getrange s1 -2 -1
getrange s1 0 10000
SETRANGE s6 3 e
SETRANGE s6 3 efghijk
SETRANGE newkey 5 hello
SETRANGE s6 3 efghijk

  • 步长1的增减
    • INCR key
    • DECR key
    • 字符串值会被解释成64位有符号的十进制整数来操作,结果依然转成字符串
  • 步长增减 float
    • INCRBY key decrement
    • DECRBY key decrement
    • 字符串值会被解释成64位有符号的十进制整数来操作,结果依然转成字符串


位图bitmap 【字节数组】
  • 位图不是真正的数据类型,它是定义在字符串类型中
  • 一个字符串类型的值最多能存储512M字节的内容
  • 位上限:2^(9+10+10+3)=2^32b
  • 设置某一位上的值
    • SETBIT key offset value 0/1
    • offset偏移量,从0开始
  • 获取某一位上的值
    • GETBIT key offset
  • 返回指定值0或者1在指定区间上第一次出现的位置
    • BITPOS key bit [start] [end]
    • 0 1 0 0 0 0 0 1 A
    • 0 1 0 0 0 0 1 0 B
事例:
set str1 ab
setbit str1 6 1
setbit str1 7 0
get str1 结果为:bb

  • 位操作
        • 0 1 0 0 0 0 0 1
        • 1 1 1 0 0 0 0 1
        • 1 1 1 0 0 0 0 1
    • 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上
    • operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种
    • BITOP AND destkey key [key ...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey
    • BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey
    • BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey
    • BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey
    • 除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入
    • 当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0
空的 key 也被看作是包含 0 的字符串序列


  • 统计指定位区间上值为1的个数 字节
    • bitpos key bit(0/1) start end > start end bit位的索引
    • BITCOUNT key [start] [end] > start end Byte位的索引 正负方向
    • set k ab bitcount k 1 1
    • 从左向右从0开始,从右向左从-1开始,注意官方start、end是位,测试后是字节
    • BITCOUNT testkey 0 0表示从索引为0个字节到索引为0个字节,就是第一个字节的统计
    • BITCOUNT testkey 0 -1等同于BITCOUNT testkey
    • 最常用的就是 BITCOUNT testkey


事例: Redis的二进制位
set s1 ab
bitcount s1
bitcount s1 0 0
bitcount s1 1 1
set ch 中
bitcount ch
bitcount ch 2 2


  • 登录不同的库
    • redis-cli --help
    • redis-cli -n 2
  • 清除当前库数据
    • FLUSHDB
  • 清除所有库中的数据
    • FLUSHALL


位图事例:
  • 网站用户的上线次数统计(活跃用户)
用户ID为key,天作为offset,上线置为1 366> 000000000000000
366 /8 50Byte 16 50
key: sean value: 11 1 000000000000000000010000000000000000
ID为500的用户,今年的第1天上线、第30天上线
SETBIT u500 1 1 1 0 0 000 0 …….1 0 00 0 > 365 /8 46 Byte
SETBIT u500 30 1
BITCOUNT sean 0 -1
KYES u*

  • 按天统计网站活跃用户
天作为key,用户ID为offset,上线置为1
求一段时间内活跃用户数 500 / 8 366 * 63Byte
SETBIT 20160601 15 1 1 0 0 0 00 00 00 0 00 00 0
SETBIT 20160603 123 1 0 0 0 0 00 00 00 0 00 00 0
SETBIT 20160606 123 1 1 0 0 0 00 00 00 0 00 00 0
求6月1日到6月10日的活跃用户
BITOP OR aaa 20160601 20160602 20160603 20160610
BITCOUNT aaa 0 -1
结果为2



List列表 数组:
  • 基于Linked List实现
  • 元素是字符串类型
  • 列表头尾增删快,中间增删慢,增删元素是常态
  • 元素可以重复出现
  • 最多包含2^32-1元素

  • 列表的索引
  • 从左至右,从0开始
  • 从右至左,从-1开始
  • list:
    • 队列:L/R R/L
    • 栈: L/L R/R
    • 数组:LINDEX LSET
    • 阻塞:BL BR
  • 命令说明
    • B block 块,阻塞
    • L left 左
    • R right 右
    • X exist 存在
  • 左右或者头尾压入元素 string set key “abc”
    • LPUSH key value [value ...]
    • LPUSHX key value
    • RPUSH key value [value ...]
    • RPUSHX key value
  • 左右或者头尾弹出元素
    • LPOP key
    • RPOP key
  • 从一个列表尾部弹出元素压入到另一个列表的头部 string getset
    • RPOPLPUSH source destination
  • 返回列表中指定范围元素
    • LRANGE key start stop
    • LRANGE key 0 -1 表示返回所有元素
  • 获取指定位置的元素
    • LINDEX key index
  • 设置指定位置元素的值
    • LSET key index value
  • 列表长度,元素个数 string strlen
    • LLEN key LRANGE KEY 0 -1
  • 从列表头部开始删除值等于value的元素count次,LIST 可以重复出现
    • LREM key count value
    • count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count
    • count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值
    • count = 0 : 移除表中所有与 value 相等的值

  • 举例
    • RPUSH listkey c abc c ab 123 ab bj ab redis list
    • LREM listkey 2 ab
    • LRANGE listkey 0 -1

  • 去除指定范围 外 元素
    • LTRIM key start stop
  • 举例
    • RPUSH listkey c abc c ab 123 ab bj ab redis list
    • LTRIM listkey 0 -1
    • LTRIM listkey 1 -1
    • LTRIM listkey 1 10000
  • 微博的评论最后500条
    • LTRIM u1234:forumid:comments 0 499

  • 在列表中某个存在的值(pivot)前或后插入元素
    • LINSERT key BEFORE|AFTER pivot value
    • key和pivot不存在,不进行任何操作
  • 举例
    • RPUSH lst Clojure C Lua
    • LINSERT lst AFTER C Python
    • LINSERT lst BEFORE C Ruby

  • 阻塞
    • 如果弹出的列表不存在或者为空,就会阻塞
    • 超时时间设置为0,就是永久阻塞,直到有数据可以弹出
    • 如果多个客户端阻塞在同一个列表上,使用First In First Service原则,先到先服务
  • 左右或者头尾阻塞弹出元素
    • BLPOP key [key ...] timeout
    • BRPOP key [key ...] timeout
  • 从一个列表尾部阻塞弹出元素压入到另一个列表的头部
    • BRPOPLPUSH source destination timeout


Hash散列:
  • 由field和关联的value组成的map键值对
  • field和value是字符串类型
  • 一个hash中最多包含2^32-1键值对

  • 设置单个字段
    • HSET key field value
    • HSETNX key field value
      • key的filed不存在的情况下执行,key不存在直接创建
  • 设置多个字段
    • HMSET key field value [field value ...]
  • 返回字段个数
    • HLEN key
  • 判断字段是否存在
    • HEXISTS key field
    • key或者field不存在,返回0

  • 返回字段值
    • HGET key field
  • 返回多个字段值
    • HMGET key field [field ...]
  • 返回所有的键值对
    • HGETALL key
  • 返回所有字段名
    • HKEYS key
  • 返回所有值
    • HVALS key

  • 在字段对应的值上进行整数的增量计算
    • HINCRBY key field increment
  • 在字段对应的值上进行浮点数的增量计算
    • HINCRBYFLOAT key field increment
  • 删除指定的字段
    • HDEL key field [field ...]
  • 举例
    • HINCRBY numbers x 100
    • HINCRBY numbers x -50
    • HINCRBYFLOAT numbers x 3.14
    • HDEL numbers x

  • 节约内存空间
  • 每创建一个键,它都会为这个键储存一些附加的管理信息(比如这个键的类型,这个键最后一次被访问的时间等等)
  • 所以数据库里面的键越多,redis数据库服务器在储存附加管理信息方面耗费的内存就越多,花在管理数据库键上的CPU也会越多在字段对应的值上进行浮点数的增量计算

  • 不适合hash的情况
    • 使用二进制位操作命令:因为Redis目前支持对字符串键进行SETBIT、GETBIT、BITOP等操作,如果你想使用这些操作,那么只能使用字符串键,虽然散列也能保存二进制数据
    • 使用过期键功能:Redis的键过期功能目前只能对键进行过期操作,而不能对散列的字段进行过期操作,因此如果你要对键值对数据使用过期功能的话,那么只能把键值对储存在字符串里面

  • 事例:微博的好友关注
用户ID为key,Field为好友ID,Value为关注时间
user:1000 user:606 20150808
xz pl 2011 zs 1949
  • 用户维度统计
统计数包括:关注数、粉丝数、喜欢商品数、发帖数
用户为Key,不同维度为Field,Value为统计数
比如关注了5人
HSET user:100000 follow 5
HINCRBY user:100000 follow 1


Set集合
  • 无序的、去重的
  • 元素是字符串类型
  • 最多包含2^32-1元素

  • 增加一个或多个元素
    • SADD key member [member ...]
    • 如果元素已经存在,则自动忽略
  • 举例
    • SADD friends peter
    • SADD friends jack tom john
    • SADD friends may tom

  • 移除一个或者多个元素
    • SREM key member [member ...]
    • 元素不存在,自动忽略
  • 举例
    • SREM friends peter
    • SREM friends tom john

  • 返回集合包含的所有元素
    • SMEMBERS key
    • 如果集合元素过多,例如百万个,需要遍历,可能会造成服务器阻塞,生产环境应避免使用
  • 检查给定元素是否存在于集合中
    • SISMEMBER key member

  • 集合的无序性
    • SADD friendsnew "peter" "jack" "tom" "john" "may" "ben"
    • SADD anotherfriends "peter" "jack" "tom" "john" "may" "ben"
    • SMEMBERS friends
    • SMEMBERS anotherfriends
    • 注意, SMEMBERS 有可能返回不同的结果,所以,如果需要存储有序且不重复的数据使用有序集合,存储有序可重复的使用列表

  • 集合的无序性
    • SADD friendsnew "peter" "jack" "tom" "john" "may" "ben"
    • SADD anotherfriends "peter" "jack" "tom" "john" "may" "ben"
    • SMEMBERS friends
    • SMEMBERS anotherfriends
    • 注意, SMEMBERS 有可能返回不同的结果,所以,如果需要存储有序且不重复的数据使用有序集合,存储有序可重复的使用列表

  • 随机返回集合中指定个数的
    • SRANDMEMBER key [count]
    • 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合 最多返回整个集合 conut>=0
    • 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值 count < 0 长度为count绝对值,元素可能重复
    • 如果 count 为 0,返回空
    • 如果 count 不指定,随机返回一个元素
  • 举例
    • SADD friend "peter" "jack" "tom" "john" "may" "ben"
    • SRANDMEMBER friends 3
    • SRANDMEMBER friends -5

  • 返回集合中元素的个数
    • SCARD key
    • 键的结果会保存信息,集合长度就记录在里面,所以不需要遍历
  • 随机从集合中移除并返回这个被移除的元素
    • SPOP key
  • 把元素从源集合移动到目标集合
    • SMOVE source destination member

  • 差集
    • SDIFF key [key ...],从第一个key的集合中去除其他集合和自己的交集部分
    • SDIFFSTORE destination key [key ...],将差集结果存储在目标key中
  • 举例
    • SADD number1 123 456 789
    • SADD number2 123 456 999
    • SDIFF number1 number2

  • 交集
    • SINTER key [key ...],取所有集合交集部分
    • SINTERSTORE destination key [key ...],将交集结果存储在目标key中
  • 举例
    • SADD number1 123 456 789
    • SADD number2 123 456 999
    • SINTER number1 number2
  • 并集
    • SUNION key [key ...],取所有集合并集
    • SUNIONSTORE destination key [key ...],将并集结果存储在目标key中
  • 举例
    • SADD number1 123 456 789
    • SADD number2 123 456 999
    • SUNION number1 number2

事例:
新浪微博的共同关注
需求:当用户访问另一个用户的时候,会显示出两个用户共同关注哪些相同的用户
设计:将每个用户关注的用户放在集合中,求交集即可
实现如下:
peter={'john','jack','may'}
ben={'john','jack','tom'}
那么peter和ben的共同关注为:
SINTER peter ben 结果为 {'john','jack'}



SortedSet有序集合
  • 类似Set集合
  • 有序的、去重的
  • 元素是字符串类型
  • 每一个元素都关联着一个浮点数分值(Score),并按照分值从小到大的顺序排列集合中的元素。分值可以相同
  • 最多包含2^32-1元素
  • 增加一个或多个元素
    • ZADD key score member [score member ...]
    • 如果元素已经存在,则使用新的score
  • 举例
    • ZADD fruits 3.2 香蕉
    • ZADD fruits 2.0 西瓜
    • ZADD fruits 4.0 番石榴 7.0 梨 6.8 芒果
  • 移除一个或者多个元素
    • ZREM key member [member ...]
    • 元素不存在,自动忽略
  • 举例
    • ZREM fruits 番石榴 梨 芒果
    • ZREM fruits 西瓜
  • 显示分值
    • ZSCORE key member
  • 举例
    • ZSCORE fruits 芒果
    • ZSCORE fruits 西瓜
  • 增加或者减少分值
    • ZINCRBY key increment member
    • increment为负数就是减少
  • 举例
    • ZINCRBY fruits 1.5 西瓜
    • ZINCRBY fruits -0.8 香蕉


  • 返回元素的排名(索引)
    • ZRANK key member
  • 举例
    • ZRANK fruits 西瓜
    • ZRANK fruits 番石榴
    • ZRANK fruits 芒果

  • 返回元素的逆序排名
    • ZREVRANK key member
  • 举例
    • ZREVRANK fruits 西瓜
    • ZREVRANK fruits 番石榴
    • ZREVRANK fruits 芒果

  • 返回指定索引区间元素
    • ZRANGE key start stop [WITHSCORES]
    • 如果score相同,则按照字典序lexicographical order 排列
    • 默认按照score从小到大,如果需要score从大到小排列,使用ZREVRANGE
  • 举例
    • ZRANGE fruits 0 2
    • ZRANGE fruits -5 -4
  • 返回指定索引区间元素
    • ZREVRANGE key start stop [WITHSCORES]
    • 如果score相同,则按照字典序lexicographical order 的 逆序 排列
    • 默认按照score从大到小,如果需要score从小到大排列,使用ZRANGE
  • 举例
    • ZREVRANGE fruits 0 2
    • ZREVRANGE fruits -5 -4
  • 返回指定分值区间元素
    • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
    • 返回score默认属于[min,max]之间,元素按照score升序排列,score相同字典序
    • LIMIT中offset代表跳过多少个元素,count是返回几个。类似于Mysql
    • 使用小括号,修改区间为开区间,例如(5、(10、5)
    • -inf和+inf表示负无穷和正无穷
  • 举例
    • ZRANGEBYSCORE fruits 4.0 7.0
    • ZRANGEBYSCORE fruits (4 7
    • ZRANGEBYSCORE fruits -inf +inf

  • 移除指定排名范围的元素
    • ZREMRANGEBYRANK key start stop
  • 举例
    • ZREMRANGEBYRANK fruits 0 2
    • ZRANGE fruits 0 -1
  • 移除指定分值范围的元素
    • ZREMRANGEBYSCORE key min max
  • 举例
    • ZREMRANGEBYSCORE fruits 3.0 5.0
    • ZRANGE fruits 0 -1

  • 返回集合中元素个数
    • ZCARD key
  • 返回指定范围中元素的个数
    • ZCOUNT key min max
    • ZCOUNT fruits 4 7

  • 并集
    • ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
    • numkeys指定key的数量,必须
    • WEIGHTS选项,与前面设定的key对应,对应key中每一个score都要乘以这个权重
    • AGGREGATE选项,指定并集结果的聚合方式
    • SUM:将所有集合中某一个元素的score值之和作为结果集中该成员的score值
    • MIN:将所有集合中某一个元素的score值中最小值作为结果集中该成员的score值
    • MAX:将所有集合中某一个元素的score值中最大值作为结果集中该成员的score值

  • 举例
    • ZADD scores1 70 tom 80 peter 60 john
    • ZADD scores2 90 peter 60 ben
    • ZUNIONSTORE scores-all 2 scores1 scores2
    • ZUNIONSTORE scores-all1 2 scores1 scores2 AGGREGATE SUM
    • ZUNIONSTORE scores-all2 2 scores1 scores2 WEIGHTS 1 0.5 AGGREGATE SUM

  • 交集
    • ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
    • numkeys指定key的数量,必须
    • WEIGHTS选项,与前面设定的key对应,对应key中每一个score都要乘以这个权重
    • AGGREGATE选项,指定并集结果的聚合方式
    • SUM:将所有集合中某一个元素的score值之和作为结果集中该成员的score值
    • MIN:将所有集合中某一个元素的score值中最小值作为结果集中该成员的score值
    • MAX:将所有集合中某一个元素的score值中最大值作为结果集中该成员的score值

  • 事例:网易音乐排行榜
分析
每首歌的歌名作为元素(先不考虑重复)
每首歌的播放次数作为分值
ZREVRANGE来获取播放次数最多的歌曲(就是最多播放榜了,云音乐热歌榜,没有竞价,没有权重)


  • 新浪微博翻页
新闻网站、博客、论坛、搜索引擎,页面列表条目多,都需要分页
blog这个key中使用时间戳作为score
ZADD blog 1407000000 '今天天气不错'
ZADD blog 1450000000 '今天我们学习Redis'
ZADD blog 1560000000 '几个Redis使用示例'
ZREVRANGE blog 0 10
ZREVRANGE blog 11 20

  • 京东图书畅销榜
ZADD bookboard-001 1000 'java' 1500 'Redis' 2000 'haoop'
ZADD bookboard-002 1020 'java' 1500 'Redis' 2100 'haoop'
ZADD bookboard-003 1620 'java' 1510 'Redis' 3000 'haoop'
ZUNIONSTORE bookboard-001:003 3 bookboard-001 bookboard-002 bookboard-003 AGGREGATE MAX
并集,使用max
注意:参与并集运算的集合较多,会造成Redis服务器阻塞,因此最好放在空闲时间或者备用服务器上进行计算



猜你喜欢

转载自blog.csdn.net/manburoam/article/details/77685678