本文最后更新于 319 天前,其中的信息可能已经过时,如有错误请发送邮件到wuxianglongblog@163.com
Redis的字典(hash)数据类型的应用场
一.字典的新增指令
1.使用"HSET"指令每次为字典数据类型的KEY新增1个字段并赋值,若字段已经存在,则会覆盖原字段存储的值
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 --raw -n 10
127.0.0.1:6379[10]> KEYS *
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HSET student id 001 # 创建一个字典类型名为student的KEY,并指定id字段的值为"001"
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> KEYS *
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HSET student name "Jason Yin" # 如果KEY已经存在,我们依旧可以为字典数据类型新增一个"name"字段并指定该字段的值为"Jason Yin"
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> TYPE student
hash
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student id
001
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student name
Jason Yin
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HSET student name "oldboyedu" # 如果name字段已经存在了,则此次新增会覆盖原字段存储的值哟~
0
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student name
oldboyedu
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
2.使用"HMSET"指令为字典数据类型的KEY同时新增多个字段
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 --raw -n 10
127.0.0.1:6379[10]> KEYS *
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HMSET phone brand Iphone memory 4G disk 128G
OK
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HMGET phone brand memory disk # 同时获取名为phone的KEY的brand,memory,disk多个字段信息
Iphone
4G
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone # 查看名为phone的KEY所有字段及其值。
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
3.使用"HSETNX"指令如果为KEY不存在的字段赋值,则会新增字段;如果为KEY已经存在的字段赋值,则赋值会失败!
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 --raw -n 10
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL student
id
001
name
oldboyedu
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HSETNX student name "Jason Yin" # 如果为KEY已经存在的字段赋值,则赋值会失败!
0
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student name
oldboyedu
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HSETNX student address "BeiJing" # 如果为KEY不存在的字段赋值,则会新增字段
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student address
BeiJing
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL student
id
001
name
oldboyedu
address
BeiJing
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
二.字典的查找指令
1.使用"HGETALL"指令查看字典类型KEY的所有字段名称及其值
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone # 查看名为phone的KEY所有的字段名称及其存储的数据。
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
2.使用"HKEYS"指令查看字典类型KEY的所有字段名称
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HKEYS phone
brand
memory
disk
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
3.使用"HVALS"指令查看字典类型KEY的所有字段存储的值
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HVALS phone
Iphone
4G
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
4.使用"HMGET"指令查看字典类型KEY的多个字段
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HMGET phone brand disk
Iphone
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
5.使用"HEXISTS"指令查看字典类型KEY的是否有某个字段,若存在指定的字段则返回1,若不存在指定的字段则返回0
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HEXISTS phone brand # 我们的phone中是存在brand字段的,因此返回值为1
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HEXISTS phone memory
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HEXISTS phone price # 我们的phone中是不存在price字段的,因此返回值为0
0
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
6.使用"HLEN"指令查看某个KEY的字段数量
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HKEYS phone
brand
memory
disk
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HLEN phone
3
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
7.使用"HGET"指令查看某个字典类型KEY的brand字段存储的数据
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGETALL phone
brand
Iphone
memory
4G
disk
128G
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET phone brand # 查看某个字典类型KEY的brand字段存储的数据。
Iphone
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
三.字典的修改指令
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HKEYS student # 我们发现名为student的KEY是不存在"age"字段的
id
name
address
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HINCRBY student age 1 # 如果我们给不存在的字段增加1,则会创建该字段并将字段的初始值设置为0,加1后其值为1。
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HKEYS student # 注意观察,不难发现名为student的KEY多了一个age字段
id
name
address
age
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student age
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HINCRBY student age 18
19
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HGET student age
19
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
四.字典的删除指令
1.使用"HDEL"指令删除指定KEY存在的一个或者多个字段
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HKEYS student
id
name
address
age
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HDEL student address age # 我们可以删除某个KEY的一个或者多个字段。
2
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> HKEYS student
id
name
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
2.使用"DEL"指令删除指定KEY
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 10 --raw
127.0.0.1:6379[10]> KEYS *
phone
student
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> DEL student
1
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> KEYS *
phone
127.0.0.1:6379[10]>
127.0.0.1:6379[10]> QUIT
[root@redis201.oldboyedu.com ~]#
五.字典的应用场景
1.手工方式模拟MySQL的热点数据灌入到Redis的hash数据类型进行缓存,手工导入数据并不是特别安全,生产环境中建议编写代码来实现,这样逻辑更为严谨!(本案例只是导入3000条数据就有导入数据丢失的现象!)
(1)自行导入MySQL官方的测试数据库(world)
[root@redis201.oldboyedu.com ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.31 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| world |
+--------------------+
5 rows in set (0.00 sec)
mysql>
mysql> SHOW TABLES FROM world;
+-----------------+
| Tables_in_world |
+-----------------+
| city |
| country |
| countrylanguage |
+-----------------+
3 rows in set (0.00 sec)
mysql>
mysql> SELECT * FROM world.city LIMIT 10; # 查看MySQL的数据,先不要看下面的SQL语句,请将其转换为Redis的语法来存储数据。
+----+----------------+-------------+---------------+------------+
| ID | Name | CountryCode | District | Population |
+----+----------------+-------------+---------------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 2 | Qandahar | AFG | Qandahar | 237500 |
| 3 | Herat | AFG | Herat | 186800 |
| 4 | Mazar-e-Sharif | AFG | Balkh | 127800 |
| 5 | Amsterdam | NLD | Noord-Holland | 731200 |
| 6 | Rotterdam | NLD | Zuid-Holland | 593321 |
| 7 | Haag | NLD | Zuid-Holland | 440900 |
| 8 | Utrecht | NLD | Utrecht | 234323 |
| 9 | Eindhoven | NLD | Noord-Brabant | 201843 |
| 10 | Tilburg | NLD | Noord-Brabant | 193238 |
+----+----------------+-------------+---------------+------------+
10 rows in set (0.00 sec)
mysql>
mysql> SELECT
-> CONCAT("HMSET city_",ID," id ",ID," Name ",Name," CountryCode ",CountryCode," District ",District," Population ",Population)
-> FROM
-> world.city
-> LIMIT
-> 10;
+------------------------------------------------------------------------------------------------------------------------------+
| CONCAT("HMSET city_",ID," id ",ID," Name ",Name," CountryCode ",CountryCode," District ",District," Population ",Population) |
+------------------------------------------------------------------------------------------------------------------------------+
| HMSET city_1 id 1 Name Kabul CountryCode AFG District Kabol Population 1780000 |
| HMSET city_2 id 2 Name Qandahar CountryCode AFG District Qandahar Population 237500 |
| HMSET city_3 id 3 Name Herat CountryCode AFG District Herat Population 186800 |
| HMSET city_4 id 4 Name Mazar-e-Sharif CountryCode AFG District Balkh Population 127800 |
| HMSET city_5 id 5 Name Amsterdam CountryCode NLD District Noord-Holland Population 731200 |
| HMSET city_6 id 6 Name Rotterdam CountryCode NLD District Zuid-Holland Population 593321 |
| HMSET city_7 id 7 Name Haag CountryCode NLD District Zuid-Holland Population 440900 |
| HMSET city_8 id 8 Name Utrecht CountryCode NLD District Utrecht Population 234323 |
| HMSET city_9 id 9 Name Eindhoven CountryCode NLD District Noord-Brabant Population 201843 |
| HMSET city_10 id 10 Name Tilburg CountryCode NLD District Noord-Brabant Population 193238 |
+------------------------------------------------------------------------------------------------------------------------------+
10 rows in set (0.01 sec)
mysql>
(2)将MySQL的数据导出到文件中,但注意导出时要符合Redis数据库的HASH数据类型语法
[root@redis201.oldboyedu.com ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.31-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql>SELECT
-> CONCAT("HMSET city_",ID," id ",ID," Name ",Name," CountryCode ",CountryCode," District ",District," Population ",Population)
-> FROM
-> world.city
-> LIMIT
-> 3000
-> INTO
-> OUTFILE "/tmp/redis.sql";
Query OK, 3000 rows affected (0.01 sec)
mysql>
mysql>QUIT
Bye
[root@redis201.oldboyedu.com ~]#
[root@redis201.oldboyedu.com ~]# ll /tmp/redis.sql
-rw-rw-rw- 1 mysql mysql 273109 2月 28 17:58 /tmp/redis.sql
[root@redis201.oldboyedu.com ~]#
[root@redis201.oldboyedu.com ~]# wc -l /tmp/redis.sql
3000 /tmp/redis.sql
[root@redis201.oldboyedu.com ~]#
(3)将MySQL导出的语句转换为Redis中的数据
[root@redis201.oldboyedu.com ~]# cat /tmp/redis.sql | redis-cli -a oldboyedu2021 &> /tmp/load_mysql2redis.log
[root@redis201.oldboyedu.com ~]#
[root@redis201.oldboyedu.com ~]# wc -l /tmp/load_mysql2redis.log # 发现行数大于3000,说明此次导入肯定是有错误的信息!
3801 /tmp/load_mysql2redis.log
[root@redis201.oldboyedu.com ~]#
(4)验证数据
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021
127.0.0.1:6379> KEYS * # 生产环境中千万别用"KEYS *",因为Redis中可能存储了很多的数据,我这里是实验方便,很明显并没有成功导入3000条数据,因为只有2199条数据,这意味着我们手工导入数据不是特别安全!
...
2186) "city_1970"
2187) "city_491"
2188) "city_2249"
2189) "city_325"
2190) "city_1411"
2191) "city_2049"
2192) "city_374"
2193) "city_946"
2194) "city_212"
2195) "city_1735"
2196) "city_2643"
2197) "city_1683"
2198) "city_1469"
2199) "city_2763"
127.0.0.1:6379>
(5)粗略验证数据
[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021
127.0.0.1:6379> HGETALL city_1
1) "id"
2) "1"
3) "Name"
4) "Kabul"
5) "CountryCode"
6) "AFG"
7) "District"
8) "Kabol"
9) "Population"
10) "1780000"
127.0.0.1:6379>
127.0.0.1:6379> HGETALL city_2
1) "id"
2) "2"
3) "Name"
4) "Qandahar"
5) "CountryCode"
6) "AFG"
7) "District"
8) "Qandahar"
9) "Population"
10) "237500"
127.0.0.1:6379>
127.0.0.1:6379> HGETALL city_3
1) "id"
2) "3"
3) "Name"
4) "Herat"
5) "CountryCode"
6) "AFG"
7) "District"
8) "Herat"
9) "Population"
10) "186800"
127.0.0.1:6379>
127.0.0.1:6379> HGETALL city_2763
1) "id"
2) "2763"
3) "Name"
4) "Oyo"
5) "CountryCode"
6) "NGA"
7) "District"
8) "Oyo"
9) "&"
10) "Osun"
11) "Population"
12) "256400"
127.0.0.1:6379>
2.hash的应用场景总结
(1)存储部分变更的数据,如学生信息,手机信息,用户信息等。
(2)当然,字典数据类型是最接近mysql表结构的一种类型,因此是可以做数据库缓存。
温馨提示:
如果想要将MySQL的数据导入到Redis数据库,我们可以参考上面手动导入的思路使用代码实现。当然,也可以借助第三方工具,比如阿里巴巴开源的"canal"工具就不错!
推荐阅读:
https://github.com/alibaba/canal