字符串
首先Redis数据存储都会以key value 的形式进行存放, 所有的key都是字符串类型。此处所说的类型特指的是value中存放的类型。下文所讲的hash、列表都是基于value上进行讲解的。Redis会根据传入字符串类型规则进行判断,java培训并采取相应的内部编码进行存储。数值型会采用8个字节的长整型进行编码存储,小于等于39个字节的字符串采用emstr编码存储,大于39字节的字符串采用raw编码存储。如果需要查看该键对应值的存储类型可运行object encoding k1命令。
- 常用写命令
1// 1. 设置键:k1 值 v1
2set k1 v1
3// 2. 与上一个set k1 v1 命令一致,且k1的失效时间为10s
4set k1 v1 ex 10 nx( k1 不存在才能设置成功) 或 set k1 v1 ex 10 xx ( k1 存在才能设置成功 )
5**** k1 不存在才能设置成功的 另一种写法
6setnx k1 v1
7**** 设置k1 失效时间的另一种写法
8setex k1 10 v1
9// 3. 批量设置键值
10mset k1 v1 k2 v2 k3 v3
11// 4. 对k1中的数值进行自增操作,如果k1中的值类型不为数值类型将会返回错误,如果不存在键k1,会按照初始值0进行自增
12incr k1
13// 5. 对k1中的值按2的长度进行自增操作。
14incrby k1 2
- 常用读命令
1// 1. 获取键 k1 的 值
2get k1
3// 2. 批量获取 k1,k2,k3 的值
4mget k1 k2 k3 k4
注意:key一般我们都会采用业务名:对象名:属性名的方式进行命名。
哈希
哈希类型在Redis中value是以{{key,value},{key,value}}的形式存储,我们通过字符和哈希类型的存储模型图来更直观的认识它们两者之间的关系,如图1-1
图1-1
Redis对于哈希类型的存储会根据哈希类型个数(对应图中的field个数)采取不同编码进行存储。如果哈希类型个数小于hash-max-ziplist-entries(默认512个)且所有值的(对应图中的value)存储大小都小于hash-max-ziplist-value(默认64字节)那么会使用更加紧凑的ziplist编码进行存储。
当无法满足ziplist条件的时候会采用hashtable编码方式进行存储。因为在节省内存方面ziplist比hashtable更优秀,但如果数据量上来后检索效率不及hashtable。
- 常用写命令
1// 1. 给regsiter:user:1 添加一对field:value
2hset register:user:1 name zhangmj
3//2. 给register:user:1 field(age)的value 增加2
4hincrby register:user:1 age 2
5//3. 批量给regist:user:1 设置多个field-value
6hmset register:user:1 name 'zhangmoujiang' age 12
7//4. 删除 register:user:1 的name
8hdel register:user:1 name
- 常用读命令
1// 1. 获取 register:user:1 的name的value
2hget register:user:1 name
3// 2. 批量获取 register:user:1 多个field的value
4hmget register:user:1 name age
5// 3. 获取 register:user:1对应所有field
6hkeys register:user:1
7// 4. 获取 register:user:1 对应所有field的value
8hvals register:user:1
9// 5. 获取 register:user:1 所有 field 和value
10hgetall register:user:1
列表
Redis中列表类型的存储模型如图1-2:
图1-2
列表类型中value最多的存储元素为2^32-1个,可重复。value元素的内部编码根据元素个数和大小会采取ziplist和linkedlist两种编码方式进行存储。当value元素个数小于list-max-ziplist-entries(默认512),同时value中每个元素的大小小于list-max-ziplist-value(64字节)会采取ziplist进行编码。
当无法满足ziplist的条件会采取linkedlist编码。ziplist编码对数据进行压缩以减少内存,而linkedlist采用链表的数据结构来存储数据。据说Redis3.2 版本之后提供了一个更合理的内部编码 quicklist,它结合ziplist和linkedlist两者的优势。
- 常用写命令
为了行文方便 对于从左往右我们用此图标进行标记:➡️, 从右往左用此图标标记⬅️,列表都特指user:1:message
1//1. ⬅️给列表插入元素
2rpush user:1:message 'piaoliang' '帅气'
3//2. ⬅️给列表插入元素
4lpush user:1:message 'xx1' 'xx2'
5//3. 在元素xx2 之前插入 xx1.5
6linsert user:1:message before 'xx2' 'xx1.5'
7//4. 在元素xx2 之后插入 xx3
8linsert user:1:message after 'xx2' 'xx3'
9//5. 从列表左侧弹出元素
10lpop user:1:message
11//6. 从列表右侧弹出元素
12rpop user:1:message
13//7. 从左侧弹出元素,如果列表不为空立即弹出,如果列表为空将阻塞3s后返回。该命令的基本格式:blpop key [key] timeout ,如果当timeout设为0且列表为空时,客户端运行此命令将会一致阻塞等待下去。如果设置了多个key,只要有一个key列表中有元素会立即返回
14blpop user:1:message 3
15//8. 同brpop 只不过是 从右侧弹出元素
16brpop user:1:message 3
17
18
19// 9. 从左往右删除列表中等于xx2的2个元素
20// 该命令的基本格式为:lrem key count vlaue
21// 其中 count > 0 会从左往右删除count个等于value的元素
22// count < 0 则会从右往左删除count个等于value的元素
23// count =0 则会删除列表中所有等于value的元素
24lrem user:1:message 2 xx2
25// 10. 保留列表中第2个元素和第4个元素,其他全删除
26ltrim user:1:message 1 3
27// 11. 将列表中的第1个元素修改为xxx0
28lset user:1:message 0 xxx0
- 常用读命令
1//1. ➡️ 获取 第1个和第2个元素。
2lrange user:1:message 0 1
3//2. ⬅️获取第1个和第2个元素
4// 假设列表元素为 g,f,h,k ,那么会获取 h,k 的元素
5lrange user:1:message -1 -2
6//3. 获取列表中从右边数,第1个元素
7lindex user:1:message -1
8//4. 获取user:1:message列表元素的长度
9llen user:1:message
10// 其中➡️列表元素索引下标 [0,N-1] , ⬅️列表元素索引下标:【-1,-N】N 为列表元素个数
- 应用场景
- 通过lpush + brpop 命令 实现消息队列。
- 每个用户都有属于自己的文章列表,需要分页显示各个用户的文章列表。
集合
集合类型的元素是可以重复的,如图1-3为集合类型的存储模型图:
图1-3
集合类型的内部编码有两种:
- intset, 当集合类型为整数且数量小于set-max-inset-entries(默认512),会采取该编码方式
- 当无法满足intset编码的条件会采取hashtable
- 常用的写命令
1// 1.添加tag1 、tag2 元素
2sadd user:1 tag1 tag2
3// 2.删除tag2 元素,返回删除成功的个数
4srem user:1 tag2
5// 3.从集合中随机弹出一个元素 / 从集合 随机弹出 n 个元素
6spop user:1
7// 4. 将集合【user:1】和【user:2】交集结果存放到destination
8sinterstore destination user:1 user:2
9// 5. 集合【user:1】 和 集合【user:2】并集结果存放到destination
10sunionstore destination user:1 user:2
11// 6. 集合【user:1】 和 集合【user:2】差集结果存放到destination
12sdiffstore destination user:1 user:2
- 常用的读命令
1// 1.计算元素个数
2scard user:1
3// 2.集合中是否存在tag3元素
4sismember user:1 tag3
5// 3.从集合随机返回一个元素 / 从集合随机返回2个元素
6srandmember user:1 / srandmember user:1 2
7// 4.获取集合中的所有元素,返回的结果是无序的
8smembers user:1
9
10// 5.求 集合【user:1】 和 集合【user:2】的交集
11sinter user:1 user:2
12// 6.求 集合【user:1】 和 集合【user:2】的并集
13sunion user:1 user:2
14// 7.求集合间的差集,即:user:2 集合的元素不在user:1中
15sdiff user:2 user:1
注意:当集合的元素过多的时候,使用smembers命令会有损性能,建议使用sscan命令来完成。
有序集合
有序集合类型的存储模型如图1-4:
图1-4
它可以类比集合类型和哈希类型的组合,其中value中包含两个主要的字段score和member,member中元素的值不能够重复,而score中元素的类型为整型值能够重复。通过score中元素的值我们能够对member中的元素进行排序。
内部也采用了两种编码:
- ziplist (压缩列表)
- skiplist (跳跃表)
- 写操作命令
1// 1. 添加集合成员 ,(85 、 zmj)
2zadd users 85 zmj
3// 2. 添加集合成员 ,存在才能设置成功
4zadd users XX 87 zhangmoujiang
5// 3. 添加集合成员,不存在才能设置成功
6zadd users NX 87 zhangmoujiang
7// 4. 删除集合内成员 caonimei
8zrem users caonimei
9// 5. 给成员xunini增加 1分,如果没有成员会自动添加
10zincrby users 1 xuxnini
- 读操作命令
1// 1. 获取集合内成员数量
2zcard users
3// 2. 获取集合内zmj成员的分数
4zscore users zmj
5// 3. 获取集合内chenxiongshun成员分数的排名(分数从低到高)
6zrank users chenxiongshun
7// 4. 同zrank一样 (分数从高到低)
8zrevrank users chenxiongshun
9// 5. 返回指定排名的范围的成员(分数从低到高)
10zrange users 0 2 [withscores]
11// 6. 同zrange一样 (分数从高到低)
12zrevrange users 0 1 [withscores]
13// 7. 按照指定分数从低到高返回成员
14// 基本格式 zrangebyscore key min max [withscores] [limit offset count]
15zrangebyscore users 50 90
16// 8. 返回指定分数的范围内的成员个数
17zcount users 0 100
几个管理键的常用命令
1//1. 当前数据库的键数量
2dbsize
3//2. 随机返回当前数据的一个键
4randomkey
5//3. 设置键key1 20 秒过期,如果键不存在返回结果为0。某个键设置了过期时间,然后执行了set命令,那么该键的过期时间会被清除。
6expire key1 20
7//4. 查看key1键还剩几秒过去,返回数字的单位为秒。返回-2 表示已过期
8ttl key1
9//5. 移除键key1的过期时间
10persisit key1
11//6. 获取所有键,keys后面可接类正则的表达式来匹配键的名称
12keys *
13//7. 选择0号数据库,redis中默认有16个数据库 ,编号从0开始...
14select 0
15//8. 清除当前数据库数据
16flushdb
17//9. 清除所有数据库数据
18flushall