数据库基础之Redis学习 part one

Posted by OuterCyrex on August 30, 2024

环境配置

1.windows环境

windows环境仅用于学习使用,项目中请使用Linux环境

参考文章:Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)

下载链接:https://github.com/tporadowski/redis/releases (版本有点低)

下载完成后解压文件,在Redis所在文件夹中使用cmd,输入:

1
redis-server.exe redis.windows.conf

来启动redis程序。

之后可以选择将Redis路径加入系统环境变量里的Path变量中,之后测试

通过下述命令行打开redis客户端:

1
redis-cli.exe -h 127.0.0.1 -p 6379

可以通过ping来测试,如果返回了pong则表明连接成功。

如果出现Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝,无法连接。

请保持redis运行再重试。

2.linux环境

待开坑………..

一.数据类型

本文档的// value注释表示同一代码块中代码的返回值,多个返回值之间用分号;隔开,或数据过长则用换行隔开。

Redis中的数据类型有:

数据类型 名称
String 字符串
List 列表
Hash 哈希表
Set 集合
Sorted Set / Zset 有序集合
Geospatial / GEO 地理空间
HyperLogLog 基数统计
bitmap 位图
bitfield 位域
Stream

指令查询:https://redis.io/commands


此处先介绍一下Redis的基础查询:

KeysRedis最常用的查询指令,其中常用的Keys指令有

Keys指令 查询内容
keys * 查询当前库中所有key
exists key 查询某个Key是否存在于当前库,并返回对应的数量,可传入多个Key
type key 查询某个Key的类型
del key 删除某个Key,可传入多个Key
unlink key 非阻塞删除,防止线程阻塞
ttl key 查看某个key还有多少秒过期,-1表示永不过期,-2表示已过期
expire key 为给定的key设置过期时间
move key dbindex 将当前数据库的key移动到给定数据库中,redis默认有16个库,编号为 0 ~ 15
dbsize 当前数据库的key的数量
flushdb 清空当前库
flushall 通杀全部库

Redis的命令是大小写不敏感的,而key大小写敏感的,大小写不同而字母相同的key会被视为不同的key。


一.String

1.Set命令

字符串的常规指令格式为

1
SET key value [NX | XX] EX number

其中,NX为创建新key,而EX为更新对应key的值。若不填该项则是二者兼有,即没有则创建,有则更改

EX number则是为对应key的值设置过期时间EX即为expire的缩写。

此外,可以通过MSET来批量的进行SET指令:

1
2
3
4
MSET K1 V1 K2 V2 K3 V3

//带入NX作用的MSET
MSETNX K1 V1 K2 V2

此外,还有MGET来实现批量查询,如:

1
MGET K1 K2 K3

此外,存在SETEX指令可以将SETEXPIRE两个指令合为一个原子指令。但该指令之后被SET ... EX ...替代了。

1
SETEX key number value

GETSET指令可以先实现GET指令,再通过SET更改其值。

1
2
3
4
5
set k1 origin
getset k1 outer
get k1

// value : origin ; outer

2.Range命令

RANGE命令分为GETRANGESETRANGE,其中GETRANGE用于返回索引范围内的字符串切片

1
2
3
4
SET K1 0123456789
GETRANGE K1 0 6

// VALUE : 0123456

SETRANGE则可以根据索引替换对应的字符串内容

1
2
3
4
SET K1 0123456789
SETRANGE K1 0 abcde
get K1
// VALUE : abcde56789

3.数值增减

INCR指令可以将对应keyvalue自增并返回其值

1
2
3
4
5
SET k1 100
INCR k1
INCR k1

// VALUE : 102

同理,DECR则是自减并返回。

如果应用于非整数类型,则会报错:ERR value is not an integer or out of range

4.字符串操作

STRLEN返回字符串的长度,APPEND在字符串最后附加内容。

1
2
3
4
5
6
7
SET K1 100
STRLEN k1
APPEND k1 ABC
STRLEN K1
get k1

// VALUE : 3 ; 6 ; 100ABC

二.List

List的底层为双向链表

1.Push命令

Redis中,定义List需要使用Push指令,存在lpushrpush,分别为从左向右压入从右往左压入

1
2
3
4
5
6
7
8
9
10
11
12
lpush l1 1 2 3 4 5
rpush l2 1 2 3 4 5

type l1

lrange l1 0 -1
lrange l2 0 -1

// value : 
list
5 4 3 2 1
1 2 3 4 5

其中lrange是依据索引范围从左向右遍历

2.Pop命令

lpoprpop分别为从左向右从右向左弹出第一个元素。

此处只演示lpoprpop与之同理。

1
2
3
4
5
lpop l1
LRANGE l1 0 -1

// value :
4 3 2 1

rpoplpush能将第一个数组的最右边元素从左边压入第二个数组

1
2
3
4
5
6
7
8
9
rpush l1 0 1 2 3
rpush l2 4 5 6 7
RPOPLPUSH l1 l2
lrange l2 0 -1
lrange l1 0 -1

// value :
l1 : 0 1 2
l2 : 3 4 5 6

如上述代码,其将l1的最右侧元素3弹出后,从左侧压入了l2

3.其余命令

此处介绍常用的List从左到右操作:LindexLlenLremLtirmLsetLinsert

LINDEX命令通过从左到右的索引获取对应的值:

1
2
3
4
rpush l2 0 1 2 3 4 5
lindex l2 3

// value : 3

LLEN可以获取列表中元素的个数,实际上lpushrpush的返回值便是LLEN

LREM可以从左到右删除给定数量给定元素,通常用于去重操作,如:

1
2
3
4
5
rpush l3 1 1 1 1 1 2 3 4 5
lrem l3 4 1
lrange l3 0 -1

// value : 1 2 3 4 5

LTRIM用于获取索引范围内的列表切片 (此处是比喻,Redis并没有切片类型)

1
2
3
4
5
rpush l2 0 1 2 3 4 5
ltrim l2 1 4
lrange l2 0 -1

// value : 1 2 3 4

LSET用于从左向右根据索引来设置某一元素的值。

1
2
3
4
5
rpush l1 0 1 2 3 4 5
lset l1 1 a
lrange l1 0 -1

// value : 0 a 2 3 4 5

LINSERT通过名称检索元素,并选择在该元素之前还是之后插入某个新元素,语法为LINSERT list [BEFORE | AFTER] old new,其中old为已存在的元素,new为要插入的新元素

1
2
3
4
5
6
rpush l1 gin gorm grpc gozero casbin
LINSERT l1 before gozero redis
lrange l1 0 -1

// value : 
gin gorm grpc redis gozero casbin

三.Hash

Hash数据类型可以理解为map[String]Object

1.Set/Get命令

Hash类型只需要hsethget即可进行设置和查询

1
2
3
4
hset user1 id 1 name Outer age 19
hget user1 name

// value : Outer

同理,还有HMSETHMGET来处理多个参数的情况。

HMSETHSET效果一致,已弃用,此处不再展示。

1
2
3
4
5
HSET user1 id 1 name Outer age 19
HMGET user1 id name age

// value : 
1 ; Outer ; 19

我们也可以直接通过HGETALL来获取全部的字段,其会遍历并返回所有的字段。

与其效果类似的有HKEYHVALSHKEY会返回所有KEY,即字段名,而HVALS则会返回所有VALUE值,即字段对应的值。

HSETNXHSETNX版本,若字段不存在则创建,若已存在则不会进行更改。

2.其余命令

此处介绍HLENHEXISTSHINCRBY

指令 作用
HLEN 可以返回当前Hash的键值对数量
HEXISTS 判断一个字段是否存在
HINCRBY 给对应的字段的值增加特定的整数
HINCRBYFLOAT 给对应的字段的值增加特定的小数
1
2
3
4
5
6
HSET user1 id 1 name Outer age 19
HINCRBY user1 id 2
HGETALL user1

//  value : 
id 3 name Outer age 19

四.Set

Set用于记录一组元素,将相同的元素归为一类。

Set也是一种映射,其映射关系为map[string]int,如果出现重复元素则int值增加。

1.Set/Get命令

SADD用于向集合中添加元素。

SMEMBERS用于查看某一集合内的元素。

SIMEMBERS用于查看一个集合内是否存在某一元素。

SREM用于删除某一元素。

SCARD用于获取当前集合内某一元素的数量。

1
2
3
4
5
SADD SET1 1 1 1 2 2 2 3 4 5
SMEMBERS SET1
SISMEMBER SET1 X
SREM SET1 1
SCARD SET 2

2.其他指令

SRANDMEMEBR用于从集合中随机展现设置的数字个数元素(不会删除),该过程不会重复。

SPOP用于从集合中随机弹出一个元素(会删除)。

SMOVE用于将一个集合中已存在的某个值赋给另一个集合。

1
2
3
4
5
SADD SET2 1 2 3 4 5 6 7 8
SRANDMEMBER SET2 7

// value :
8 7 6 2 4 5 3

如果SRANDMEMBER后传入的值等于Set内的元素数量,则其效果就与SMEMBER一致。

SPOPSRANDMEMBER效果一致,只是会删除元素。

SMOVE可以将第一个集合中的某个元素移到第二个集合中。

1
2
3
4
5
6
7
8
9
SADD SET1 1 2 3 4
SADD SET2 5 6 7 8
SMOVE SET1 SET2 4
SMEMBERS SET1
SMEMBERS SET2

// value :
1 2 3 ;
4 5 6 7 8 ;

上述语句中,SMOVESET1中的4移到了SET2中。

3.集合运算

SDIFFA - B,就是属于A而不属于B的元素。

SUNIONA ∪ B,即 A 和 B 的并集

SINTERA ∩ B,即 A 和 B 的交集

五.ZSet

ZSet是在Set的基础上,给每一个Key一个Score值,并通过Score进行排序。

ZSet的大部分操作与Set一致,此处只举例。

包括:ZADD ZCARD ZREM ZINCRBY

1
2
3
4
5
ZADD ZSET1 100 V1 200 V2 300 V3
ZRANGE ZSET1 0 -1 WITHSCORES

// value :
V1 100 V2 200 V3 300

ZRANGELRANGE效果一致,根据SCORE从小到大进行遍历,且可以通过增加WITHSCORES来设置是否显示分数

与之相反的是ZREVRANGE,其可以按从大到小的顺序遍历。

ZRANGEBYSCORE的语法较为复杂。

ZRANGEBYSCORE set [ ( ] min max [ ) ] [WITHSCORES] [LIMIT start end]

其中,加() 表示开区间,即不包含顶点。

LIMIT start end表示通过下标限制寻找的范围。

ZSCORE可以获取对应元素的SCORE值。

ZCOUNT可以获取指定分数范围内的元素个数。

ZRANK通过SCORE的大小进行排序,并获取其对应字段的排名。

1
2
3
4
ZADD ZSET1 100 V1 200 V2 300 V3
ZRANK ZSET1 V3

// value : 2

六.bitmap

bitmap的底层数据类型为String类型。

SETBIT可以指定更改对应位的比特值。

GETBIT可以获取对应位的比特值。

1
2
3
4
5
SETBIT K1 1 1
SETBIT K1 7 1
GET K1

// value : A (01000001 = 65)

STRLEN可以获得bitmap的字节数,不足一字节的会向上取整

BITCOUNT可以获取bitmap的为1的比特位总数。

BITOP可以对同一bitmap的两个比特位进行与或非操作

七.HyperLogLog

HyperLogLog用于大基数数据去重,用于统计基数

其对应的操作为PHADDPHCOUNT

1
2
3
4
PFADD HLL 1 2 3 4 5 5 5 5
PFCOUNT HLL

// value : 5

PFMERGE用于将两个HyperLogLog类型融合并返回一个新的HyperLogLog类型。

1
2
3
4
5
6
PFADD HLL 1 2 3 4 5 5 5 5
PFADD HLL1 2 3 4 4 6 7
PFMERGE NEWHLL HLL HLL1
PFCOUNT NEWHLL

// value : 7

八.GEO

GEO类型的底层数据类型为ZSET

通过GEOADD来增加新的数据,如果有乱码就添加-- raw,且作弊是以特殊的算法记录的,因此无法直接通过withscores来获取坐标。

1
2
3
4
5
6
GEOADD city 116 39 "天安门"
ZRANGE city 0 -1 withscores
GEOPOS city "天安门"

// value : 天安门 4069047624061615 ;
116.00000113248825073 38.99999918434559731 ;

很明显的浮点数误差

GEOHASH可以获取对应键的哈希表示。

GEODIST可以获取两个坐标之间的距离,并根据传入的参数来决定单位

1
2
3
4
GEOADD city 116 39 "天安门" 1 1 "北极"
GEODIST city "天安门" "北极" km

// value : 12068.7139

还有GEORADIUSGEORADIUSBYHMEMBER等操作,由于GEO数据类型应用范围实在有限,在此不作介绍。

九.Stream

应用场景有限,待开发…

十.bitfields

应用场景有限,待开发…