• Redis —— 基础篇


    Redis —— 基础篇


    1、简介

    ​  Redis(Remote Dictionary Server,远程字典服务)是一个开源的 使用 ANSI C语言 编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

    ​  Redis 的主要用途如下:

    • 缓存:是实现分布式缓存的首选中间件
    • 数据库:实现诸如点赞、关注、排行等对性能要求极高的互联网需求
    • 计算工具:统计诸如PV/UV、用户在线天数等数据
    • 其他的使用场景:可以实现分布式锁,可以作为消息队列使用

    扩展:Redis 和 传统的关系型数据库 的区别

    • 存储方式:

      1、Redis是一种基于键值对的NoSQL数据库,而键值对的值是由多种数据结构和算法组成的。

      2、关系型数据库是基于二维数据表来存储数据的,它的数据格式更为严谨,并支持关系查询。

    • 存储区域:

      1、Redis的数据都存储于内存中,因此它的速度惊人,读写性能可达10万/秒,远超关系型数据库。

      2、关系型数据库的数据存储于磁盘上,可以存放海量的数据,但性能远不如Redis。




    2、基础知识

    2.1、Redis 数据库

    ​  Redis 有16个数据库(DB0 ~ DB15),默认使用第 0 个,可以使用 select n 切换到 DB n,dbsize 可以查看当前数据库的大小(与 key 数量相关)。


    相关命令:

    • keys * :查看当前数据库中所有的key。

    • flushdb:清空当前数据库中的键值对。

    • flushall:清空所有数据库的键值对


    2.2、Redis 数据类型

    1、Redis 支持5种核心的数据类型: 字符串、哈希、列表、集合、有序集合;

    2、Redis 还提供了 Bitmap、HyperLogLog、Geo 类型,但这些类型都是基于上述核心数据类型实现的;

    3、 Redis 在5.0新增加了 Streams 数据类型,它是一个功能强大的、支持多播的、可持久化的 消息队列。


    2.3、Redis-key

    ​  在 Redis 中无论什么数据类型,在数据库中都是以 key-value 形式保存,通过对 Redis-key 的操作,来完成对数据库中数据的操作。


    相关命令:

    • exists key:判断键是否存在
    • del key:删除键值对
    • move key db:将键值对移动到指定数据库
    • expire key second:设置键值对的过期时间
    • type key:查看value的数据类型

    补充:TTL 命令(返回 key 的过期时间,语法为 ttl key

    1. 当前 key 没有设置过期时间,会返回 -1
    2. 当前 key 有设置过期时间 且 key 已过期,会返回 -2
    3. 当前 key 有设置过期时间 且 key 未过期,返回 key 剩余时间



    3、五大数据类型

    3.1、String(字符串)

    相关命令:

    • set [key] [value]:添加元素
    • get [key] :获取元素
    # 语法
    set [key] [value]	# 添加元素
    get [key] 			# 获取元素
    
    
    127.0.0.1:6379> set name hong 
    OK
    127.0.0.1:6379> get name
    "hong"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.2、List(列表)

    • List 是 线性有序 的数据结构,内部元素 可以重复 并 按照 插入顺序排序

    • List 实际上是一个 双向链表,可以向 List 中的任何位置 插入元素

    • 一个 List 最多可以包含 2^32 - 1 个元素


    相关命令:

    • lpushx/rpushx key value: 添加元素
    • lpush/rpush key value [value...]:添加一个或多个元素
    • lrange key start stop:查询元素
    • linsert key BEFORE|AFTER pivot value:插入元素
    • llen key:获取列表长度
    • lindex key index:获取指定索引的值(从 0 开始)
    • lset key index value:改变列表某个位置的值
    • lpop/rpop key:弹出元素
    • rpoplpush source destination:从当前列表弹出 压入到新的列表
    • ltrim key start stop:截取列表
    • lrem key count value:移除元素
    • blpop/brpop key [key ...] timeout:弹出元素,若列表为空则进入阻塞状态

    注:命令无特殊说明的话,l 代表 List 。

    # 添加 (l 代表从左边插入,r代表从右边插入)
    lpushx/rpushx key value					# 添加一个元素
    lpush/rpush key value [value...]		# 添加一个或多个元素
    
    # 查询
    lrange key start stop					
    
    127.0.0.1:6379> lpush myList 1 2 3
    (integer) 3
    127.0.0.1:6379> lrange myList 0 -1		# 0 -1  代表查询所有值
    1) "3"
    2) "2"
    3) "1"
    
    # 插入
    linsert key BEFORE|AFTER pivot value
    
    127.0.0.1:6379> linsert myList after 3 three
    (integer) 4
    127.0.0.1:6379> lrange myList 0 -1
    1) "3"
    2) "three"
    3) "2"
    4) "1"
    
    # 获取列表长度
    llen key
    
    127.0.0.1:6379> llen myList
    (integer) 4
    
    # 获取指定索引的值(从 0 开始)
    lindex key index
    
    127.0.0.1:6379> lindex myList 1
    "three"
    
    # 改变列表某个位置的值
    lset key index value
    
    127.0.0.1:6379> lset myList 1 four
    OK
    127.0.0.1:6379> lrange myList 0 -1
    1) "3"
    2) "four"
    3) "2"
    4) "1"
    
    # 弹出 (l 代表从左边插入,r代表从右边插入)
    lpop/rpop key
    
    127.0.0.1:6379> rpop myList
    OK
    127.0.0.1:6379> lrange myList 0 -1
    1) "3"
    2) "four"
    3) "2"
    
    # 从当前列表弹出 压入到新的列表 
    rpoplpush source destination
    
    127.0.0.1:6379> rpoplpush myList newList
    "2"
    127.0.0.1:6379> lrange myList 0 -1
    1) "3"
    2) "four"
    127.0.0.1:6379> lrange newList 0 -1
    1) "2"
    
    # 截取列表
    ltrim key start stop					# [start, stop],从 0 开始
    
    127.0.0.1:6379> ltrim myList 0 0
    OK
    127.0.0.1:6379>  lrange myList 0 -1
    1) "3"
    
    # 移除元素
    lrem key count value					# 当 count = -x,代表移除全部
    
    127.0.0.1:6379> lrem myList -1 3
    (integer) 1
    127.0.0.1:6379> lrange myList 0 -1
    (empty list or set)
    
    # 弹出,若列表为空则进入阻塞状态 (l 代表从左边插入,r代表从右边插入)
    blpop/brpop key [key ...] timeout		# timeout 超时时间,单位为秒
    
    127.0.0.1:6379> blpop myList 5
    (nil)
    (5.04s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    3.3、Set(集合)

    • Set 是 String 类型 的无序集合,内部元素 不重复
    • Set 是通过 哈希表 实现的,添加、删除、查找的复杂度都是 O(1)
    • 一个 Set 最多可以包含 2^32 - 1 个元素

    相关命令:

    • sadd key value :添加元素
    • smembers key:查询元素
    • scard key:获取集合长度
    • sismember key value:查询元素是否存在
    • srandmember key count:随机返回 count 个元素
    • spop key count:随机移除 count 个元素
    • smove key otherkey value:移动元素
    • srem key value [value...]:移除元素
    • sdiff key1 [key2...]:查询集合的差集
    • sinter key1 [key2...]:查询集合的交集
    • sunion key1 [key2...]:查询集合的并集

    注:命令无特殊说明的话,s 代表 Set 。

    # 添加
    sadd key value 
    
    # 查询
    smembers key
    
    127.0.0.1:6379> sadd mySet 1 2 3 4 5
    (integer) 5
    127.0.0.1:6379> smembers mySet
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    
    # 获取集合长度
    scard key
    
    127.0.0.1:6379> scard mySet
    (integer) 5
    
    # 查询元素是否存在
    sismember key value
    
    127.0.0.1:6379> sismember mySet 5
    (integer) 1
    127.0.0.1:6379> sismember mySet 6
    (integer) 0
    
    # 随机返回 count 个元素
    srandmember key count
    
    127.0.0.1:6379> srandmember mySet 3
    1) "2"
    2) "4"
    3) "1"
    
    # 随机移除 count 个元素
    spop key count
    
    127.0.0.1:6379> spop mySet 2
    1) "1"
    2) "3"
    127.0.0.1:6379> smembers mySet
    1) "2"
    2) "4"
    3) "5"
    
    # 移动元素
    smove key otherkey value
    
    127.0.0.1:6379> smove mySet newSet 2
    (integer) 1
    127.0.0.1:6379> smembers mySet
    1) "4"
    2) "5"
    127.0.0.1:6379> smembers newSet
    1) "2"
    
    # 移除元素
    srem key value [value...]
    
    127.0.0.1:6379> srem mySet 4
    (integer) 1
    127.0.0.1:6379> smembers mySet
    1) "5"
    
    127.0.0.1:6379> sadd mySet 1 2 7 8
    (integer) 4
    127.0.0.1:6379> sadd newSet 7 8 0 9
    (integer) 4
    127.0.0.1:6379> smembers mySet
    1) "1"
    2) "2"
    3) "5"
    4) "7"
    5) "8"
    127.0.0.1:6379> smembers newSet
    1) "0"
    2) "2"
    3) "7"
    4) "8"
    5) "9"
    
    # 查询集合的差集
    sdiff key1 [key2...]
    
    127.0.0.1:6379> sdiff mySet newSet
    1) "1"
    2) "5"
    
    # 查询集合的交集
    sinter key1 [key2...]
    127.0.0.1:6379> sinter mySet newSet
    1) "2"
    2) "7"
    3) "8"
    
    # 查询集合的并集
    sunion key1 [key2...]
    127.0.0.1:6379> sunion mySet newSet
    1) "0"
    2) "1"
    3) "2"
    4) "5"
    5) "7"
    6) "8"
    7) "9"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    3.4、Hash(哈希)

    • Hash 是一个 String 类型 的 field 和 value 的映射表,适合存储对象

    相关命令:

    • hset key field value:添加元素
    • hget key field:查询元素
    • hgetall key:获取全部的元素
    • hdel key field1 [field2...]:删除元素
    • hlen key:获取元素数量
    • hexists key field:判断 hash 中 指定元素 是否存在
    • hincrby key field increment:增加元素字段的值(字段值为数字)
    • hsetnx key field value:判断元素是否存在,如果不存在就新增该元素,存在就不作改变

    命令无特殊说明的话,h 代表 Hash 。

    # 添加 
    hset key field value
    
    # 查询 
    hget key field
    
    127.0.0.1:6379> hset myHash name yu
    (integer) 1
    127.0.0.1:6379> hget myHash name
    "yu"
    127.0.0.1:6379> hset myHash count 100
    (integer) 1
    127.0.0.1:6379> hget myHash count
    "100"
    
    # 获取全部的元素
    hgetall key
    
    127.0.0.1:6379> hgetall myHash
    1) "name"
    2) "yu"
    3) "count"
    4) "100"
    
    # 删除元素
    hdel key field1 [field2...]
    
    127.0.0.1:6379> hdel myHash count
    (integer) 1
    127.0.0.1:6379> hgetall myHash
    1) "name"
    2) "yu"
    
    # 获取 hash 的元素数量
    hlen key
    
    127.0.0.1:6379> hlen myHash
    (integer) 1
    
    # 判断 hash 中指定元素是否存在
    hexists key field
    
    127.0.0.1:6379> hexists myHash name
    (integer) 1
    127.0.0.1:6379> hexists myHash count
    (integer) 0
    
    127.0.0.1:6379> hset myHash count 100
    (integer) 1
    127.0.0.1:6379> hget myHash count
    "100"
    
    # 增加元素字段的值(字段值为数字)
    hincrby key field increment
    
    127.0.0.1:6379> hincrby myHash count 100
    (integer) 200
    127.0.0.1:6379> hget myHash count
    "200"
    
    # 判断元素是否存在,如果不存在就新增该元素,存在就不作改变
    hsetnx key field value
    
    127.0.0.1:6379> hsetnx myHash color blue
    (integer) 1
    127.0.0.1:6379> hget myHash color
    "blue"
    127.0.0.1:6379>  hsetnx myHash color green
    (integer) 0
    127.0.0.1:6379> hget myHash color
    "blue"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    3.5、Zset(有序集合)

    • Zset 中 不同的元素都会关联一个不同的、double类型的分数(score),Zset 正是通过分数来为集合中的元素进行从小到大的排序
    • score 相同:按字典顺序排序
    • Zset 元素唯一,但元素的分数(score)可以重复

    相关命令:

    • zadd key score value [score value ...]:添加元素
    • zrange key start end:查询元素
    • zrangebyscore key min max [withscores]:元素升序
    • zrevrange key start end:元素降序
    • zcard key:获取元素数量
    • zcount key min max :获取指定区间的元素数量
    • zrem key member:移除元素

    命令无特殊说明的话,Z 代表 Zset 。

    # 添加
    zadd key score value [score value ...]
    
    # 查询
    zrange key start end
    
    127.0.0.1:6379> zadd myZset 1 first
    (integer) 1
    127.0.0.1:6379> zrange myZset 0 -1
    1) "first"
    
    127.0.0.1:6379> zadd myZset 2 secord
    (integer) 1
    127.0.0.1:6379> zadd myZset 3 third
    (integer) 1
    127.0.0.1:6379> zadd myZset 0 four
    (integer) 1
    127.0.0.1:6379> zrange myZset 0 -1
    1) "four"
    2) "first"
    3) "secord"
    4) "third"
    
    # 排序
    ## 升序
    zrangebyscore key min max [withscores]
    
    127.0.0.1:6379> zrangebyscore myZset 0 3
    1) "four"
    2) "first"
    3) "secord"
    4) "third"
    127.0.0.1:6379> zrangebyscore myZset 0 3 withscores
    1) "four"
    2) "0"
    3) "first"
    4) "1"
    5) "secord"
    6) "2"
    7) "third"
    8) "3
    
    ## 降序
    zrevrange key start end
    
    127.0.0.1:6379> zrevrange myZset 0 -1
    1) "third"
    2) "secord"
    3) "first"
    4) "four"
    
    # 获取 Zset 中元素的数量
    zcard key
    
    127.0.0.1:6379> zcard myZset
    (integer) 4
    
    # 获取指定区间的成员数量
    zcount key min max 
    
    127.0.0.1:6379> zcount myZset 0 2
    (integer) 3
    
    # 移除Zset中的元素
    zrem key member
    
    127.0.0.1:6379> zrem myZset first
    (integer) 1
    127.0.0.1:6379> zrange myZset 0 -1
    1) "four"
    2) "secord"
    3) "third"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72


    4、三种特殊数据类型

    4.1、geospatial (地理位置)

    相关命令:

    • geoadd key 经度 纬度 value:添加地理位置
    • geodist key value1 value2 [m/km/mi/ft]:获取指定城市的经度和纬度
    • georadius key 经度 纬度 半径 [m/km/mi/ft] [withcoord] [withdist] [WITHHASH] [count number](限定数量):通过半径来查询附近的城市
    • geohash key member:将二维的经纬度转换为一维的字符串
    # 添加地理位置
    # 规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!
    # 有效经纬度:
    	# 有效的经度从 -180度 到 180度
    	# 有效的纬度从 -85.05112878度 到 85.05112878度
    geoadd key 经度 纬度 value
    
    # 获取指定城市的经度和纬度
    geopos key value
    
    # 获取两座城市的直线距离
    	# mi 英里
    	# ft 英尺
    geodist key value1 value2 [m/km/mi/ft]
    
    # 通过半径来查询附近的城市
    georadius key 经度 纬度 半径 [m/km/mi/ft] [withcoord] [withdist] [WITHHASH] [count number](限定数量)
    
    georadiusbymember key member radius 
    
    # 将二维的经纬度转换为一维的字符串
    geohash key member
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注:geo 底层实现原理 是 Zset

    127.0.0.1:6379> zrange china:city 0 -1   # 查看地图中全部元素
    1) "chongqi"
    2) "xian"
    3) "shenzhen"
    4) "hangzhou"
    5) "shanghai"
    6) "beijing"
    127.0.0.1:6379> zrem china:city chongqi  # 移除指定元素!
    (integer) 1
    127.0.0.1:6379> zrange china:city 0 -1
    1) "xian"
    2) "shenzhen"
    3) "hangzhou"
    4) "shanghai"
    5) "beijing"
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.2、Hyperloglog(基数统计)

    • 基数统计算法

    • 占用的内存是固定的,存放 2^64 不同的元素,只需要12KB的内存

    • 存在 0.81% 的错误率


    相关命令:

    • pfadd key value:添加元素
    • pfcount key:计数
    • pfmerge destkey sourcekey [sourceky...]:合并
    # 添加元素
    pfadd key value
    
    # 计数
    pfcount key
    
    # 合并 key
    pfmerge destkey sourcekey [sourceky...]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.3、Bitmaps(位图)

    • 操作二进制位来进行记录,只有 0 和 1 两个状态

    相关命令:

    • setbit key offset value:添加元素

    • bitcount key:位统计

    # 添加
    setbit key offset value ( value => [0,1] )
    
    
    • 1
    • 2
    • 3

    应用:使用 Bitmaps 来记录 周一 到 周日 的打卡

    127.0.0.1:6379> setbit sign 0 1
    (integer) 0
    127.0.0.1:6379> setbit sign 1 0
    (integer) 0
    127.0.0.1:6379> setbit sign 2 0
    (integer) 0
    127.0.0.1:6379> setbit sign 3 1
    (integer) 0
    127.0.0.1:6379> setbit sign 4 1
    (integer) 0
    127.0.0.1:6379> setbit sign 5 0
    (integer) 0
    127.0.0.1:6379> setbit sign 6 1
    (integer) 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    查看某一天是否有打卡

    127.0.0.1:6379> getbit sign 3
    (integer) 1
    127.0.0.1:6379> getbit sign 5
    (integer) 0
    
    • 1
    • 2
    • 3
    • 4

    统计打卡的天数

    127.0.0.1:6379> bitcount sign	# 统计这周的打卡记录
    (integer) 4
    
    • 1
    • 2
  • 相关阅读:
    DDD--战略设计和战术设计
    ESP8266远程控制电子门
    保护基团的作用(四类基团的保护方法有哪些)--渝偲医药
    Web3:数字身份与隐私保护的新篇章
    打包报错JavaScript heap out of memory
    基于.Net+SWEBUI开发的开源WMS仓库管理系统
    R语言卡方检验最全总结
    windows下VS配置NISwGSP
    【Educoder数据挖掘实训】异常值检测-箱线图
    C语言:详解gcc驱动程序完成编译、汇编、链接的过程
  • 原文地址:https://blog.csdn.net/weixin_51123079/article/details/126031987