认识NoSQL数据库

NoSQL一般有四种类型:

  1. 键值类型(redis)
  2. 文档类型(MongoDB)
  3. 列类型(HBase)
  4. Graph类型(Neo4j)

关系型数据库和非关系型数据库的区别

SQL NoSQL
数据结构 结构化 非结构化
数据关联 关联的 无关联的
查询方式 SQL查询 非SQL
事务特性 ACID BASE
存储方式 磁盘 内存
扩展性 垂直 水平
使用场景 数据结构稳定,相关业务对数据安全性一致性要求较高 数据结构不固定,对一致性,安全性要求不高,对性能要求

初识Redis

redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NoSQL数据库

特征

  • 键值型,value(值)支持多种不同数据结构,功能丰富
  • 单线程,每个命令具备原子性
  • 低延迟,速度快(基于内存,IO多路复用,良好的编码)。
  • 支持数据持久化
  • redis支持主从集群,分片集群
  • 支持多语言客户端

小插曲:redis 6.0版本已经是多线程了,但是单线程为啥还是他的特征,原因是redis6.0的多线程仅仅是对网络请求这块,核心的依旧是单线程

安装Redis

注意:基于rocky9系统版本

安装redis依赖

1
yum install -y gcc tcl

上传redis6.2.6.tar.gz压缩包

解压并进入redis目录

1
2
3
make && make install

# 安装成功后会在/usr/local/bin目录

启动

默认启动

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
5993:C 14 Apr 2023 17:02:21.419 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5993:C 14 Apr 2023 17:02:21.419 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=5993, just started
5993:C 14 Apr 2023 17:02:21.419 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
5993:M 14 Apr 2023 17:02:21.420 * Increased maximum number of open files to 10032 (it was originally set to 1024).
5993:M 14 Apr 2023 17:02:21.420 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.2.6 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 5993
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

5993:M 14 Apr 2023 17:02:21.421 # Server initialized
5993:M 14 Apr 2023 17:02:21.421 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
5993:M 14 Apr 2023 17:02:21.421 * Ready to accept connections

这种启动属于前台启动,会阻塞整个会话窗口,窗口关闭或者按下ctrl + c则redis停止,不推荐使用

指定配置启动

如果要让redis以后台方式启动,则必须修改redis的配置文件

备份一次原配置文件

1
cp redis.conf{,.bak}

然后修改redis.conf文件中的一些配置

1
2
3
4
5
6
7
8
9
10
11
# 监听地址,默认是127.0.0.1,只能在本地访问,修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0

bind 0.0.0.0

# 守护进程,默认是no,修改为yes后即可后台运行

daemonize yes

# 密码,设置后用户访问redis必须输入密码

requirepass 123456

redis的其他配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 监听端口
port 6379
# 工作目录,默认是当前目录,也就是执行redis-server时的命令,日志,持久化等文件会保存在这个目录
dir .

# 数据库数量,设置为1,代表只使用一个库,默认存在16个库,编号是0-15个

# 设置redis能够使用的最大内存

maxmemory 512mb

# 日志文件,默认为空,可以指定日志文件名

logfile "redis.log"

设置完成后启动redis

1
2
3
4
5
[root@redis redis-6.2.6]# redis-server redis.conf
[root@redis redis-6.2.6]# ps -ef |grep redis
root 1414 1 0 09:12 ? 00:00:00 redis-server 127.0.0.1:6379
root 1420 1333 0 09:12 pts/0 00:00:00 grep --color=auto redis

1
2
停止redis
kill -9 进程ID号

开机自启动

自己编写一个redis的系统服务配置文件。

首先,新建一个系统服务配置文件:

1
vi /etc/systemd/system/redis.service

内容如下

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /root/redis-6.2.6/redis.conf
PrivateTmp=true

# 这里和我看的教程不符,可能是系统版本问题,需要添加如下,不能在enable的时候报错
[Install]
WantedBy=multi-user.target

然后重载系统服务

1
2
3
4
5
systemctl daemon-reload

systemctl start redis

systemctl enable redis

客户端

安装完并启动redis。我们就可以操作redis,实现crud了

这里因为使用习惯问题,只写了命令行客户端

redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下:

1
redis-cli [options] [commonds]

其中常见的options有:

  • -h 指定要连接的redis节点的IP地址,默认为127.0.0.1
  • -p 指定要连接redis节点的端口,默认是6379
  • -a 指定redis的访问密码

其中的commonds就是redis的操作命令,例如

ping 与redis服务做心跳测试,服务端正常会返回pong

1
2
[root@redis redis-6.2.6]# redis-cli -p 6379 ping
PONG

不指定commonds时,会进入redis-cli的交互控制台

数据类型

Redis是一个key-value的数据库,key一般是string类型,不过value的类型多种多样

redis为了方便学习,将操作不同数据类型的命令也做了分组,在官网Rdis官方文档可以查看到不同的命令,redis的命令是分组的,学习的时候按照分组去学习。

在redis的命令行也可以获取到帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> help
redis-cli 6.2.6
To get help about Redis commands type:
"help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit

To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
127.0.0.1:6379> help @string

APPEND key value
summary: Append a value to a key
since: 2.0.0

BITCOUNT key [start end]

通用命令

通用命令是部分数据类型的,都可以使用的命令

通过命令行help查看通用命令

1
help @generic

常见的命令有:

注意:所有的命令帮助都可以使用help查询用法,如help keys,help del

keys:查看符合模块的所有key,不建议在生产设备环境上使用

1
2
3
4
5
# 查询所有的key
keys *

# 模糊匹配查询
keys a*

del:删除一个指定的key

1
del key

exists:判断一个key是否存在

1
2
3
4
5
6
# 不存在返回0
127.0.0.1:6379> exists yyt
(integer) 0
# 存在返回1
127.0.0.1:6379> exists name
(integer) 1

expire:给key设置有效期,有效期到期key会被自动删除

ttl:查看一个key的有效期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 添加一个key值是yyt
127.0.0.1:6379> set name yyt
OK

# 模糊查询所有key
127.0.0.1:6379> keys *
1) "name"

# 当查询的key返回值为-2时表示这个key不存在,或者有效期已过
127.0.0.1:6379> ttl yyt
(integer) -2

# 当返回值为-1的时候表示这个key永久有效
127.0.0.1:6379> ttl name
(integer) -1

String类型

String类型常见命令

string类型,也就是字符串类型,是redis中最简单的存储类型

其value(值)是字符串,不过根据字符串的格式不同,又可以分为三类:

  • string:普通字符串
  • int:整数类型,可以做自增,自减操作
  • float:浮点类型,可以做自增,自减操作
key value
msg hello world
num 10
score 92.5

常见的string命令有:

  • set 添加或修改已经存在的string类型的键值对

  • get 根据key获取它的值

  • mset 批量添加多个string类型的键值对

  • mget 根据多个key获取多个string类型的值

  • incr 让一个整型的key自增1(每执行一次让他的值加一)

  • incrby 让一个整数类型的key自增,可以指定步长比如incrby age 2或自减-2

  • incrbyfloat 让一个浮点数自动增长,必须指定步长

  • setnx 添加一个字符类型的key,前提这个类型不存在,否则不执行

  • setex 添加一个string类型的键值对,并且指定有效期

综合联习

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
# 批量添加key
127.0.0.1:6379> mset name1 yyt name2 douzhiyong name3 wangguanghao
OK
127.0.0.1:6379> keys *
1) "name3"
2) "name1"
3) "name2"

# 批量查询key的值
127.0.0.1:6379> mget name1 name2 name3
1) "yyt"
2) "douzhiyong"
3) "wangguanghao"

# 添加或修改一个key
127.0.0.1:6379> set age 18
OK

# incr让一个整数类型的key自增1
127.0.0.1:6379> incr age
(integer) 19
127.0.0.1:6379> get age
"19"
127.0.0.1:6379> incr age
(integer) 20
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> incr age
(integer) 22

# 让一个整数类型的key自增并设定步长为3
127.0.0.1:6379> incrby age 3
(integer) 25
127.0.0.1:6379> incrby age 3
(integer) 28
127.0.0.1:6379> incrby age 3
(integer) 31

# 添加一个浮点类型的key
127.0.0.1:6379> set score 10.1
OK

# incrbyfloat让一个浮点数自动增长步长是1
127.0.0.1:6379> incrbyfloat score 1
"11.1"
127.0.0.1:6379> incrbyfloat score 1
"12.1"
127.0.0.1:6379> incrbyfloat score 1
"13.1"

#查询所有的key
127.0.0.1:6379> keys *
1) "name2"
2) "name1"
3) "name3"
4) "age"
5) "score"

#批量查询key的值
127.0.0.1:6379> mget name1 name2 name3 age score
1) "yyt"
2) "douzhiyong"
3) "wangguanghao"
4) "22"
5) "13.1"

#添加一个key,前提是这个key不存在,如果存在则不执行
127.0.0.1:6379> setnx name1 dzy
(integer) 0
127.0.0.1:6379> get name1
"yyt"
127.0.0.1:6379> setnx name4 mnb
(integer) 1
127.0.0.1:6379> keys *
1) "name2"
2) "name1"
3) "name3"
4) "age"
5) "score"
6) "name4"

# 添加一个key并且设置它的有效期为10
# 注意语法格式 setex key 有效期 值
127.0.0.1:6379> setex name4 5 yyt
OK
127.0.0.1:6379> get name4
"yyt"
127.0.0.1:6379> ttl name4
(integer) 3
127.0.0.1:6379> ttl name4
(integer) 2
127.0.0.1:6379> ttl name4
(integer) 1
127.0.0.1:6379> ttl name4
(integer) -2

Key的层级结构

Redis11键值类型的数据库,他的键有一个要求就是必须唯一

Redis的结构

Redis的key允许有多个单词形成层级结构,多个单词之间用”:”隔开,语法格式:

1
项目名:业务名:类型:id

格式不是固定的,也可以根据自己的需求来删除或添加词条

例如我们的项目名称叫yyt,有user和product两种不同类型的数据,我们可以这样定义key:

  • user相关的key:yyt:user:1
  • product相关的key:yyt:product:1

总结

string类型的三种格式

  • 字符串
  • int
  • float

Redis的key的格式:

  • [项目名]冒号[业务名]冒号[类型]冒号:[id]

Hash类型

hash类型,也叫散列,其value是一个无序列表。

String结构是将对象序列化为json字符串后存储,当需要修改对象某个字段时很不方便:

Hash结构可以将对象中的,每个字段独立存储,可以针对单个字段做crud: