文章

Redis 核心数据结构简介

Redis 核心数据结构简介

Redis 是一种高级的 Key-Value 存储系统,其 Value 支持五种核心数据类型。了解这些数据结构是高效使用 Redis 的基础。

关于 Key 的几点建议:

  1. 不要过长:长度超过 1024 字节会消耗更多内存,并降低查找效率。
  2. 不要过短:过短的 Key 会降低可读性。
  3. 统一命名规范:在项目中建议使用统一的命名模式,例如 object:id:field,如 user:10000:passwd

1. Strings (字符串)

字符串是 Redis 最基础的数据类型,可以存储任何形式的二进制安全数据,例如文本、序列化的对象,甚至是图片文件的内容。如果只使用字符串类型且不开启持久化,Redis 在功能上非常接近 Memcached。

基本操作:

SET mystr "hello world"
GET mystr

原子计数: 字符串类型可以用于数值操作。当对一个字符串键执行 INCRDECR 等命令时,Redis 会尝试将其解释为整数并执行原子性的增减操作。这个特性常用于实现高并发场景下的计数器,如网站访问量、点赞数等。

redis> SET mynum "2"
OK
redis> GET mynum
"2"
redis> INCR mynum
(integer) 3
redis> GET mynum
"3"

2. Lists (列表)

Redis 的列表在底层是基于链表实现的,而非数组。这意味着在列表的头部或尾部添加元素的时间复杂度是 O(1),即使列表包含数百万个元素,操作速度也极快。

列表的常见应用包括:

  • 消息队列:利用 LPUSHRPOP(或 RPUSHLPOP)可以轻松实现一个先进先出(FIFO)的消息队列。
  • 分页查询LRANGE 命令可以方便地获取列表的一个片段,实现分页功能。
  • 动态集合:博客的评论列表、用户的动态流等。

常用命令:

// 在列表左侧(头部)插入元素
redis> LPUSH mylist "1"
(integer) 1

// 在列表右侧(尾部)插入元素
redis> RPUSH mylist "2"
(integer) 2

// 再次从左侧插入
redis> LPUSH mylist "0"
(integer) 3

// 查看列表所有元素(从头到尾)
redis> LRANGE mylist 0 -1
1) "0"
2) "1"
3) "2"

3. Sets (集合)

集合是无序的字符串集合,不允许有重复的成员。集合中的元素没有先后顺序。

集合非常适合用于存储不重复的数据,例如:

  • 标签系统:为用户或物品打标签,一个标签对应一个集合,集合内是所有关联的用户或物品ID。
  • 共同好友:利用交集操作 SINTER 可以快速找出两个用户的共同好友。

常用命令:

// 添加元素到集合
redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1

// 查看集合所有成员
redis> SMEMBERS myset
1) "one"
2) "two"

// 判断成员是否存在
redis> SISMEMBER myset "one"
(integer) 1

// 求两个集合的并集
redis> SADD yourset "1" "2"
(integer) 2
redis> SUNION myset yourset
1) "1"
2) "one"
3) "2"
4) "two"

4. Sorted Sets (有序集合)

有序集合(ZSET)与集合类似,也是不允许重复成员的字符串集合。但不同的是,有序集合的每个成员都会关联一个 score(分数),Redis 通过这个 score 来为集合中的成员进行排序。

有序集合非常适合用于排行榜系统,例如:

  • 游戏积分榜:用玩家ID作为成员,分数为 score
  • 带权重的任务队列:用任务内容作为成员,优先级作为 score

常用命令:

// 添加成员并指定分数
redis> ZADD myzset 1 "baidu.com"
(integer) 1
redis> ZADD myzset 3 "360.com"
(integer) 1
redis> ZADD myzset 2 "google.com"
(integer) 1

// 按分数升序列出所有成员
redis> ZRANGE myzset 0 -1
1) "baidu.com"
2) "google.com"
3) "360.com"

// 按分数升序列出成员及其分数
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "baidu.com"
2) "1"
3) "google.com"
4) "2"
5) "360.com"
6) "3"

5. Hashes (哈希)

哈希是一个字符串字段和字符串值之间的映射表,特别适合用于存储对象。相比于为对象的每个字段都创建一个独立的 Key,使用哈希可以极大地节省内存。

应用场景:

  • 存储对象信息:一个用户对象,包含用户名、密码、年龄等字段,可以存储在一个哈希中。

常用命令:

// 批量设置哈希的字段和值
redis> HMSET user:001 username antirez password P1pp0 age 34
OK

// 获取哈希的所有字段和值
redis> HGETALL user:001
1) "username"
2) "antirez"
3) "password"
4) "P1pp0"
5) "age"
6) "34"

// 更新单个字段的值
redis> HSET user:001 password "12345"
(integer) 0

// 再次获取
redis> HGETALL user:001
1) "username"
2) "antirez"
3) "password"
4) "12345"
5) "age"
6) "34"

哈希提供了丰富的操作命令,更多信息可以查阅 Redis 官方文档

本文由作者按照 CC BY 4.0 进行授权