从零开始Redis(二)
这一节笔者将介绍redis的五种存储结构
简介
redis一共有五种存储结构,分别为string(字符串),list(列表),hash(散列),set(集合),zset(有序集合)。大部分读者对string,list,hash感到熟悉,因为多种编程语言都有类似的语义。这五种结构分别有各自的命令也有共用的命令,如del,type,rename等,接下来对每种存储结构展开细谈。
Redis的Key的设计
项目中存储到redis的key的设计可以参考以下建议:
- 用:分割
- 把表名转换为key前缀, 比如: user:
- 第二段放置主键值
- 第三段放置列名
比如:用户表user, 转换为redis的key-value存储
userid | username | password | |
---|---|---|---|
9 | zhangf | 111111 | goudan@www.com |
username 的 key: user:9:username
{userid:9,username:zhangf}
email的key user:9:email
string
字符串类型,可以存储的值为字符串,整型,浮点型。可以对整个字符串或者部分字符串做操作,如果值为浮点型或者整型可以做自增,自减的操作。
最常用命令有三种:
get
获取一个key的value,如果对应的key没有值,则返回(nil) 即为null的意思
# 获取key为hello的值
127.0.0.1:6379> get hello
"world"
# 获取key为hello1的值,没有获取到
127.0.0.1:6379> get hello1
(nil)
set
给一个key赋值,如果key不存在,即创建, 否则替换其value
# 不能给key赋空值
127.0.0.1:6379> set hello1
(error) ERR wrong number of arguments for 'set' command
# 可以赋空字符串
127.0.0.1:6379> set hello1 ''“
OK
127.0.0.1:6379> get hello1
""
# 对已经存在的key赋值即替换其现有值
127.0.0.1:6379> set hello1 fire
OK
127.0.0.1:6379> get hello1
"fire"
del
删除一个key以及其对应的值(del属于通用命令)
# 删除一个key,value, 返回值为1即成功
127.0.0.1:6379> del hello1
(integer) 1
# 返回值为0即失败
127.0.0.1:6379> del hello1
(integer) 0
127.0.0.1:6379> get hello1
(nil)
应用场景:
1、key和命令是字符串
2、普通的赋值
3、incr用于乐观锁
incr:递增数字,可用于实现乐观锁 watch(事务)
4、setnx用于分布式锁
当value不存在时采用赋值,可用于实现分布式锁
其它常见使用命令
list
list是一个有序的可重复的链表,存储的值是string。获取头部或尾部附近的记录是极快的
list的元素个数最多为2^32-1个(40亿)
插入可以从表头或表尾插入。
最常用命令如下
lindex
获取list里面某个下标的具体值
# 获取list1 里面下标为2的值
127.0.0.1:6379> lindex list1 2
"item1"
# 如果获取的下标超过集合的长度,则返回null
127.0.0.1:6379> lindex list1 5
(nil)
# 获取不存在的list,返回null
127.0.0.1:6379> lindex list2 0
(nil)
lrange
获取list里指定长度的值
# 0 到-1表示获取list里的所有值
127.0.0.1:6379> lrange list1 0 -1
1) "item2"
2) "item"
3) "item1"
# 获取从下标1到下标2的范围值
127.0.0.1:6379> lrange list1 1 2
1) "item"
2) "item1"
# 当右边下标超过list的长度后,只返回list所拥有的值
127.0.0.1:6379> lrange list1 0 5
1) "item2"
2) "item"
3) "item1"
# 如果左下标超过了list长度,则抛空
127.0.0.1:6379> lrange list1 3 5
# 左下标必须小于右下标
127.0.0.1:6379> lrange list1 2 1
(empty list or set)
lpush,rpush
lpush可以理解为从list表头插入,rpush可以为从表尾插入。
127.0.0.1:6379> lrange list1 0 -1
1) "item2"
2) "item"
3) "item1"
# 表头插入数据,插入成功后会返回list的长度
127.0.0.1:6379> lpush list1 item3
(integer) 4
# 获取list的第一个值
127.0.0.1:6379> lindex list1 0
"item3"
# 表尾插入一个值
127.0.0.1:6379> rpush list1 item4
(integer) 5
# 获取list 最后一个值
127.0.0.1:6379> lindex list1 4
"item4"
127.0.0.1:6379> lrange list1 0 -1
1) "item3"
2) "item2"
3) "item"
4) "item1"
5) "item4"
lpop ,rpop
移除命令,从表头或表尾移除一个值
127.0.0.1:6379> lrange list1 0 -1
1) "item3"
2) "item2"
3) "item"
4) "item1"
5) "item4"
# 移除表头一个数据,返回移除的数据
127.0.0.1:6379> lpop list1
"item3"
# 移除表尾的一个数据,返回移除的数据
127.0.0.1:6379> rpop list1
"item4"
# 查看剩下的list所有值
127.0.0.1:6379> lrange list1 0 -1
1) "item2"
2) "item"
3) "item1"
应用场景:
1、作为栈或队列使用
列表有序可以作为栈和队列使用
2、可用于各种列表,比如用户列表、商品列表、评论列表等。
其它常用命令
set
set是一个无序且不重复的集合,存储的值是string,因为无序性,所以不能像list那可以从表头表尾插入。集合中最大的成员数为 2^32 - 1
最常用命令如下
sadd
往set里插入一个值
# 1表示插入成功
127.0.0.1:6379> sadd set1 test
(integer) 1
127.0.0.1:6379> sadd set1 test1
(integer) 1
# set不支持重复值,0表示此数据set中已经存在
127.0.0.1:6379> sadd set1 test
(integer) 0
smembers
获取set里面所有的值, 如果数据量过大,此命令执行速度会降低。
127.0.0.1:6379> smembers set1
1) "test"
2) "test1"
sismember
检查一个set里是否存在某个值
# 存在的话即返回值为1,否则为0
127.0.0.1:6379> sismember set1 test
(integer) 1
127.0.0.1:6379> sismember set1 test2
(integer) 0
srem
移除集合里某个值
# 返回值为1代表移除成功,为0则代表此值造set集合里不存在
127.0.0.1:6379> srem set1 test
(integer) 1
127.0.0.1:6379> srem set1 test3
(integer) 0
127.0.0.1:6379> smembers set1
1) "test1"
应用场景
适用于不能重复的且不需要顺序的数据结构
比如:关注的用户,还可以通过spop进行随机抽奖
其它常用命令
hash
Redis hash 是一个 string 类型的 field 和 value 的映射表,它提供了字段和字段值的映射。
每个 hash 可以存储 2^32 - 1 键值对(40多亿)。
hash其实可以理解为缩小版的redis,存储key,value形式。值支持字符串,整型,浮点型。
最常用命令如下
hget
获取一个hash的值
127.0.0.1:6379> hget hash1 key1
"test"
# 获取的hash不存在,抛空
127.0.0.1:6379> hget hash2 key1
(nil)
# 获取的子key不存在的话,抛空
127.0.0.1:6379> hget hash1 key2
(nil)
hgetall
获取所有的值
# 第一个值为key,第二个为key对应发value
127.0.0.1:6379> hgetall hash1
1) "key1"
2) "test"
hset
get一个hash赋值
# 1b表示添加成功,0表示此值已经存在。
127.0.0.1:6379> hset hash1 key1 test
(integer) 1
127.0.0.1:6379> hset hash1 key1 test
(integer) 0
hdel
删除hash下的key,value
# 1表示删除成功,0表示此hash已不存在这个key
127.0.0.1:6379> hdel hash1 key1
(integer) 1
127.0.0.1:6379> hdel hash1 key1
(integer) 0
应用场景:
对象的存储 ,表数据的映射
常用命令如下
zset
SortedSet(ZSet) 有序集合: 元素本身是无序不重复的,有序集合存储和hash一样也是键值对,不过是特殊形式的键值对。在有序集合里。key称为member,value称为score,而且value必须是浮点型。每个元素关联一个分数(score) 可按分数排序,分数可重复
常用命令如下
zadd
有序集合里添加一个数据
# 有序集合里先复制score,后复制member,而且member不能重复。返回0代表zset里已经存在了member的键值对
127.0.0.1:6379> zadd zset1 78 member
(integer) 1
127.0.0.1:6379> zadd zset1 78 member
0
zrange
和集合一样,获取有序集合里的范围值
127.0.0.1:6379> zrange zset1 0 -1
1) "member"
# withscores参数表示同时获取其对应的score
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "member"
2) "78"
zrangebyscore
根据score范围获取一定的集合值
# 查询score为0-800之间的数据
zrangebyscore zset1 0 800 withscores
1) "member"
2) "78"
zrem
与list一样,移除某个数据
127.0.0.1:6379> zrem zset1 member
(integer) 1
127.0.0.1:6379> zrem zset1 member
(integer) 0
应用场景:
由于可以按照分值排序,所以适用于各种排行榜。比如:点击排行榜、销量排行榜、关注排行榜等
常见操作命令
总结
此文主要介绍了下redis的五种数据结构以及常用的命令,各种数据结构的命令远不止如此,感兴趣的读者可以去redis官网下,笔者也会在后续的文章中针对运用的到具体数据结构讲解其他的命令。