Redis入门

redis 数据类型

redis的数据类型一共有 8种 分别是 5 种基本数据类型和 3 种特殊数据类型

基本数据类型

  • String 字符串
    • string类型是Redis最基本的数据类型,一个键最大能存储512MB
  • Hash 哈希
    • hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
  • List 列表
  • Set 集合
    • 该普通Set集合是无序且唯一的
  • ZSet 有序集合
    • 该Set添加时需要多添加一个score数值来进行排序 该数值可以重复,但是元素还是唯一的

特殊数据类型:

  • Bitmap
  • HyperLogLog
  • geo

基础入门

在不修改配置文件的情况下,redis默认提供16个数据库 下标为0-15

基础命令

切换数据库命令: select 下标

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> 

清空当前数据库的数据:flushdb

127.0.0.1:6379[1]> set name xf
OK
127.0.0.1:6379[1]> get name
"xf"
127.0.0.1:6379[1]> flushdb
OK
127.0.0.1:6379[1]> get name
(nil)

清空所有数据库的数据:flushall

127.0.0.1:6379[1]> get name
"xf"
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get name
(nil)

获取某个键是否存在:exists {key}

127.0.0.1:6379> exists name
(integer) 0
127.0.0.1:6379> set name xf
OK
127.0.0.1:6379> exists name
(integer) 1
#后面可以跟多个key 返回的数值就是有多少个key是存在的
127.0.0.1:6379> exists name name1
(integer) 1
127.0.0.1:6379> 

移动某个键值对到其他数据库:move {key} {db}

127.0.0.1:6379>  keys *
1) "name"
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get name
"xf"
127.0.0.1:6379[1]> 

设置某个键值对的过期时间:expire {key} {seconds}

127.0.0.1:6379> get name
"xf_1"
127.0.0.1:6379> expire name 1
(integer) 1
127.0.0.1:6379> get name
(nil)
# 过期后这个值就被删除了 
127.0.0.1:6379> 

获得某个键值对将要到期的时间(单位:秒):ttl {key}

127.0.0.1:6379> get name
"xf_10"
127.0.0.1:6379> expire name 10
(integer) 1
# ttl 返回的数值就是要到期的秒数
127.0.0.1:6379> ttl name
(integer) 9
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> ttl name
(integer) 7
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> ttl name
(integer) -2
# 到期后被删除
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> 

查看某个值的类型:type {key}

127.0.0.1:6379> get name
"xf"
127.0.0.1:6379> type name
string
127.0.0.1:6379> 

基础概念

Redis在4.0以前是单线程的

  • 为什么使用单线程?

    • redis是基于内存进行操作的,cpu的性能并不是redis的瓶颈,而线程解决的问题是cpu的使用效率,所以多线程对redis的提升并不算大,线程切换的时候反而会影响redis

    • 多线程要考虑到线程安全等因素,所以会需要加入锁,但是加锁解锁也会影响其性能,甚至可能会出现死锁情况,所以使用的是单线程

  • Redis为什么单线程还这么快

    • 误区1:高性能服务器一定是多线程的?
    • 误区2:多线程一定比单线程快?
      • 在多线程中,CPU会对多个上下文进行切换,切换也有一定的时间。
  • 核心

    • redis将全部数据是放在了内存(RAM)中的,所以说使用单线程是最高效的。

Redis可以干什么?

  • Redis是一个基于内存的 数据结构存储系统 它可以作用于:
    • 数据库
    • 缓存
    • 消息中间件

五大基本数据类型

String (字符串)

  • append {key} {value} 追加字符串

    127.0.0.1:6379> get name
    "xf"
    # 返回的是追加后的字符串长度
    127.0.0.1:6379> append name 123
    (integer) 5
    # 追加后字符串
    127.0.0.1:6379> get name
    "xf123"
    
    • 如果当前 {key} 不存在 就相当于 set {key}

  • strlen {key} 获取字符串长度

    # 获取当前字符串长度
    127.0.0.1:6379> strlen name
    (integer) 5
    127.0.0.1:6379> get name
    "xf123"
    
  • incr {key} 自增1

    • incyby {key} step 自增自定义步长

  • decr {key} 自减1

    • decrby {key} step 自减自定义步长

  • getrange {key} {start} {end} 截取(包括) {start} 到 {end} 的字符串

    127.0.0.1:6379> get name
    "xf123"
    #0123  
    127.0.0.1:6379> getrange name 0 3
    "xf12"
    127.0.0.1:6379> getrange name 0 -1 # -1是查看全部的字符串
    "xf123"
    127.0.0.1:6379>
    
  • setrange {key} {index} {text} 将值下标为 {index} 的字符替换成 {text}

    • 替换长度根据 {text} 长度决定
    127.0.0.1:6379> get name
    "xf123"
    127.0.0.1:6379> setrange name 1 ff
    (integer) 5
    127.0.0.1:6379> get name
    "xff23"
    127.0.0.1:6379> 
    
  • setex {key} {second} {value} 设置值并设置过期时间

    • 等价于set {key} {value}expire {key} {second} 同时输入
    127.0.0.1:6379> setex name 10 xf
    OK
    127.0.0.1:6379> ttl name
    (integer) 8
    127.0.0.1:6379> ttl name
    (integer) 7
    127.0.0.1:6379>
    
  • setnx {key} {value} 如果当前{key}不存在 则设置为 {value} 存在则不变

    • 分布式锁中常常使用
    127.0.0.1:6379> get name
    (nil)
    127.0.0.1:6379> setnx name xf
    (integer) 1
    127.0.0.1:6379> get name
    "xf"
    127.0.0.1:6379> setnx name xufan
    (integer) 0
    127.0.0.1:6379> get name
    "xf"
    127.0.0.1:6379>
    
  • mset {key} {value} [key value ...] 可以一次性设置多个值

    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
    OK
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k2"
    3) "k1"
    127.0.0.1:6379> 
    
  • mget {key} [key key ...] 可以一次性获取多个字(按顺序获取)

    127.0.0.1:6379> mget k1 k2 k3
    1) "v1"
    2) "v2"
    3) "v3"
    127.0.0.1:6379> mget k2 k1 k3
    1) "v2"
    2) "v1"
    3) "v3"
    127.0.0.1:6379> 
    
  • msetnx 同上 setnx 命令 多个一块设置

    • 但是msetnx 是原子性操作: 要么都成功 要么都失败 无关参数先后
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k2"
    3) "k1"
    127.0.0.1:6379> msetnx k4 v4 k1 v1
    (integer) 0
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k2"
    3) "k1"
    127.0.0.1:6379> 
    
  • getset {key} {value} 该命令先获取值后立马更新值

    127.0.0.1:6379> get user:1
    "{name:zhangsan,age:10}"
    127.0.0.1:6379>  getset user:1 xf
    "{name:zhangsan,age:10}"
    127.0.0.1:6379> get user:1
    "xf"
    127.0.0.1:6379> 
    

小技巧

string类型来存储字符串可以使用json格式 也可以用一种很巧妙的形式

如将他的一些json中的key再放入 key中

  • # json方式
    127.0.0.1:6379> set user:1 {name:zhangsan,age:10}
    OK
    127.0.0.1:6379> get user:1
    "{name:zhangsan,age:10}"
    127.0.0.1:6379> 
    
    
    # other
    127.0.0.1:6379> mset user:1:name zhangsan user:1:age 10
    OK
    127.0.0.1:6379> mget user:1:name user:1:age
    1) "zhangsan"
    2) "10"
    127.0.0.1:6379> 
    

可以将他的属性名也存入在 key 中 有点类似mysql中的联合主键吧

List (列表)

  • lpush {key} {value} 从左边添加一个新元素至{key} 该列表内

  • rpush {key} {value} 从右边 同上

    127.0.0.1:6379> lpush list v1
    (integer) 1
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    127.0.0.1:6379> 
    
  • lpop {key} 移除并获取左边第一个元素

  • rpop {key} 从右边 同上

    127.0.0.1:6379> LRANGE list 0 -1
    1) "v2"
    2) "v1"
    127.0.0.1:6379> lpop list
    "v2"
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    127.0.0.1:6379> 
    
  • lrange {key} {start_index} {end_index} 列表范围内的元素

    • lrange {key} 0 -1 则为获取 {key} 该列表的所有元素
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    127.0.0.1:6379> 
    
  • lindex {key} {index} 获取 {key} 该列表中下标为 {index} 的元素

    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1" # index:0
    2) "v2" # index:1
    3) "v3" # index:2
    127.0.0.1:6379> LINDEX list 1
    "v2"
    127.0.0.1:6379> 
    
  • llen {key} 获取列表长度

    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    2) "v2"
    3) "v3"
    127.0.0.1:6379> llen list
    (integer) 3
    127.0.0.1:6379>
    
  • lrem {key} {count} {element} 删除列表中 {count} 个 值为 {element} 的元素

    127.0.0.1:6379> LRANGE list 0 -1
    1) "v2"
    2) "v2.5"
    127.0.0.1:6379> lrem list 1 v2
    (integer) 1
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v2.5"
    127.0.0.1:6379>
    
  • Linsert {key} {before|after} {text} {insert_text}

    • 往 {key} 列表中的 {text} 元素之前 {before} 或之后 {after} 插入 {insert_text}
    127.0.0.1:6379> LINSERT list after v2 v2.5
    (integer) 5
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    2) "v2"
    3) "v2.5"
    4) "v3"
    5) "v4"
    127.0.0.1:6379> 
    
  • rpoplpush {原key} {新key} 将 原列表 中的最右边元素移至 新列表 的左边

    • 等价于 rpop {key} + lpush {key} {value}
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    2) "v2"
    3) "v2.5"
    4) "v3"
    5) "v4"
    127.0.0.1:6379> RPOPLPUSH list list_new
    "v4"
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1"
    2) "v2"
    3) "v2.5"
    4) "v3"
    127.0.0.1:6379> LRANGE list_new 0 -1
    1) "v4"
    
  • ltrim {key} {start} {end} 修剪 {key} 列表,只保留 [start,end] 中的元素 ,其他元素舍弃

    127.0.0.1:6379> LRANGE list 0 -1
    1) "v1" # index:0
    2) "v2" # index:1
    3) "v2.5" # index:2
    4) "v3" # index:3
    127.0.0.1:6379> LTRIM list 1 2
    OK
    127.0.0.1:6379> LRANGE list 0 -1
    1) "v2"
    2) "v2.5"
    127.0.0.1:6379>
    

Set (集合)

Set中的值是不能重复且无序的!

  • sadd {key} {value} 往 {key} 中添加 {value} 值

    127.0.0.1:6379> sadd set s1
    (integer) 1
    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    127.0.0.1:6379>
    
  • smembers {key} 查看指定 {key}

    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    127.0.0.1:6379>
    
  • sismember {key} {value} 判断 {key} 中是否存在 {value}

    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    127.0.0.1:6379> SISMEMBER set s1 # 存在返回1
    (integer) 1
    127.0.0.1:6379> SISMEMBER set s2 # 不存在返回0
    (integer) 0
    127.0.0.1:6379> 
    
  • scard {key} 获取 {key} 中元素个数

    • 类似llen {key}
    127.0.0.1:6379> SCARD set
    (integer) 1
    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    127.0.0.1:6379>
    
  • srem {key} {member} [members ...] 在 {key} 中移除单个或多个 {member} 元素

    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    2) "s"
    3) "s2"
    4) "s3"
    127.0.0.1:6379> SREM set s
    (integer) 1
    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    2) "s2"
    3) "s3"
    127.0.0.1:6379>
    
  • srandmember {key} [count] 在集合 {key} 中抽取 [count] 个随机元素

    • count默认为1
    127.0.0.1:6379> SRANDMEMBER set
    "s3"
    127.0.0.1:6379> SRANDMEMBER set
    "s2"
    127.0.0.1:6379> SRANDMEMBER set
    "s2"
    127.0.0.1:6379> SRANDMEMBER set
    "s2"
    127.0.0.1:6379>
    
  • spop {key} [count] 弹出 {key} 中随机选取的一个元素

    127.0.0.1:6379> spop set 
    "s2"
    127.0.0.1:6379> SMEMBERS set
    1) "s1"
    2) "s3"
    127.0.0.1:6379>
    
  • smove {key} {new_key} {source} 将 {key} 中的 {source} 移动到 {new_key} 中

    127.0.0.1:6379> smove set set_new s1
    (integer) 1
    127.0.0.1:6379> SMEMBERS set
    1) "s3"
    127.0.0.1:6379> SMEMBERS set_new
    1) "s1"
    127.0.0.1:6379>
    

集合运算

  • sinter {key} [keys ...] 交集运算

    • 交集是两个集合中都拥有的元素的新集合 如a:{1,2,3} b:{2,3,4} 那么他们的交集就是{2,3}
    127.0.0.1:6379> SMEMBERS set1
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    127.0.0.1:6379> SMEMBERS set2
    1) "2"
    2) "3"
    3) "5"
    127.0.0.1:6379> SINTER set1 set2
    1) "2"
    2) "3"
    127.0.0.1:6379>
    
  • sunion {key} [keys...] 并集运算

    • 并集将两个集合合并,去除重复项,包含了俩个集合所有的元素
    127.0.0.1:6379> SMEMBERS set1
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    127.0.0.1:6379> SMEMBERS set2
    1) "2"
    2) "3"
    3) "5"
    127.0.0.1:6379> SUNION set1 set2
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    127.0.0.1:6379>
    
  • sdiff {key} [keys...] 差集运算

    • 差集是在 {key} 集合中有 而 [keys] 集合中没有的元素
    127.0.0.1:6379> SDIff set1 set2
    1) "1"
    2) "4"
    127.0.0.1:6379>
    

Zset (有序集合)

zset是一种特殊的set类型 他相较于set类型的区别是有序的,但是也是不重复元素的类型

  • zadd {key} {score} {member} 添加新元素和{score}至{key}

    127.0.0.1:6379> zadd zset 1 one 2 two 3 three
    (integer) 3
    127.0.0.1:6379> ZRANGE zset 0 -1
    1) "one"
    2) "two"
    3) "three"
    127.0.0.1:6379>
    
  • zrange {key} {start} {end} 展示[start,end]的数据 同上list使用一样

    • zrange {key} 0 -1 为展示{key}中的全部数据
    127.0.0.1:6379> ZRANGE zset 0 -1
    1) "one"
    2) "two"
    3) "three"
    127.0.0.1:6379>
    
  • zrem {key} {member} 删除{key}中的指定元素

    127.0.0.1:6379> ZREM zset three
    (integer) 1
    127.0.0.1:6379> ZRANGE zset 0 -1
    1) "one"
    2) "two"
    127.0.0.1:6379>
    
  • zcard {key} 获取{key}的集合长度

    127.0.0.1:6379> ZCARD zset
    (integer) 2
    127.0.0.1:6379> 
    
  • zrangebyscore {key} {min} {max} [withscores] 取score在[min,max]范围内的所有元素并排序

    • 该命令为升序,如果改为降序需要使用 zrevrangebyscore 命令
    • {min}和{max} 可以用 -inf +inf 来代替
    • [withscores] 参数是是否需要显示元素的score值
    # 升序
    127.0.0.1:6379> ZRANGEBYSCORE zset -inf +inf 
    1) "one"
    2) "two"
    
    # 降序
    127.0.0.1:6379> ZrevRANGEBYSCORE zset +inf -inf  
    1) "two"
    2) "one"
    127.0.0.1:6379>
    
  • zcount {key} {min} {max} 获取{key}中score 在范围[min,max]中的成员数量

    127.0.0.1:6379> ZRANGE zset 0 -1
    1) "one"
    2) "two"
    3) "three"
    4) "four"
    127.0.0.1:6379> ZCOUNT zset 1 3
    (integer) 3
    127.0.0.1:6379>
    

该集合通常用于排名、排行榜之类的需要一定顺序和权重来排序,但是元素唯一的情况。

三种特殊数据类型

  • Geo 地理位置
    • 标记经纬度后可以计算距离
      • 两点之间距离
      • 方圆距离
    • 通常用在附近的人 、需要涉及距离等参数
  • Hyperloglog 基数统计
    • 类似于set 也是不重复的集合
      • 优势:可以存放 2^64 个元素 且内存使用极小,固定只有 12kb
      • 劣势:有一定错误率,官方表示约:**0.81% **错误
    • 一般是用于统计浏览量、播放量等需要筛选唯一值且可以接受一定错误情况下使用
  • Bitmaps 位存储
    • 只有 0 和 1 状态表示 可以用于只有俩种状态的情况 类似以下场景
      • 登录状态(已登录、未登录)
      • 打卡签到情况(签到、缺勤)
文章作者: 面具
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 MianJu —— 这只是一个 Title 而已~
Linux redis redis linux
喜欢就支持一下吧