🗂️ Redis 哈希(Hash)

Redis 中存储对象的最佳数据类型

哈希类型概述

Redis 哈希是一个键值对集合,特别适合存储对象。哈希类型的值本身又是一个键值对集合,可以看作是一个小型的 Redis 数据库。每个哈希可以存储多达 2^32 - 1 个键值对。

📝 基本操作命令

哈希类型的基础读写操作:

命令 描述 示例
HSET key field value 设置哈希字段的值 HSET user:1001 name "张三"
HGET key field 获取哈希字段的值 HGET user:1001 name
HEXISTS key field 检查哈希字段是否存在 HEXISTS user:1001 email
HDEL key field [field ...] 删除哈希字段 HDEL user:1001 temp_field
HLEN key 获取哈希字段数量 HLEN user:1001
HKEYS key 获取所有哈希字段名 HKEYS user:1001
HVALS key 获取所有哈希字段值 HVALS user:1001
HGETALL key 获取所有字段和值 HGETALL user:1001

基本操作示例:

# 创建用户信息
HSET user:1001 name "张三"
HSET user:1001 age "25"
HSET user:1001 email "zhang@example.com"
HSET user:1001 city "北京"

# 获取用户信息
HGET user:1001 name     # 返回: "张三"
HGET user:1001 age      # 返回: "25"

# 检查字段是否存在
HEXISTS user:1001 email # 返回: 1 (存在)
HEXISTS user:1001 phone # 返回: 0 (不存在)

# 获取所有信息
HGETALL user:1001
# 返回: 1) "name" 2) "张三" 3) "age" 4) "25" 5) "email" 6) "zhang@example.com" 7) "city" 8) "北京"

# 获取字段数量
HLEN user:1001          # 返回: 4

⚡ 批量操作命令

Redis 支持批量操作多个哈希字段,提高操作效率:

命令 描述 示例
HMSET key field value [field value ...] 批量设置多个字段 HMSET user:1002 name "李四" age "30"
HMGET key field [field ...] 批量获取多个字段的值 HMGET user:1002 name age
HSETNX key field value 仅当字段不存在时设置 HSETNX user:1002 phone "13800138000"

批量操作示例:

# 批量创建用户信息
HMSET user:1002 name "李四" age "30" city "上海" email "li@example.com"

# 批量获取用户信息
HMGET user:1002 name age city
# 返回: 1) "李四" 2) "30" 3) "上海"

# 条件设置字段
HSETNX user:1002 phone "13800138000"  # 返回: 1 (设置成功)
HSETNX user:1002 phone "13900139000"  # 返回: 0 (字段已存在,设置失败)

🔢 数值操作命令

当哈希字段存储数值时,可以进行原子性的数值操作:

命令 描述 示例
HINCRBY key field increment 将字段值增加指定整数 HINCRBY user:1001 login_count 1
HINCRBYFLOAT key field increment 将字段值增加指定浮点数 HINCRBYFLOAT user:1001 balance 10.5

数值操作示例:

# 初始化用户统计信息
HMSET user:1001 login_count 0 balance 100.0 points 0

# 用户登录计数
HINCRBY user:1001 login_count 1    # 登录次数+1
HINCRBY user:1001 login_count 1    # 再次登录,计数+1

# 用户余额操作
HINCRBYFLOAT user:1001 balance 50.5   # 充值50.5元
HINCRBYFLOAT user:1001 balance -20.0  # 消费20元

# 积分操作
HINCRBY user:1001 points 100       # 获得100积分
HINCRBY user:1001 points -50       # 消费50积分

# 查看最终结果
HGETALL user:1001

🔍 字段遍历命令

Redis 提供了安全的字段遍历命令:

命令 描述 示例
HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希字段 HSCAN user:1001 0 MATCH "*name*"

字段遍历示例:

# 遍历所有字段
HSCAN user:1001 0

# 按模式匹配字段
HSCAN user:1001 0 MATCH "*count*"

# 限制返回数量
HSCAN user:1001 0 COUNT 2

实际应用场景

👤 用户信息存储

使用哈希存储用户的详细信息:

# 用户基本信息
HMSET user:1001 \
    name "张三" \
    age "25" \
    email "zhang@example.com" \
    phone "13800138000" \
    city "北京" \
    register_time "2024-01-01" \
    last_login "2024-01-15"

# 用户统计信息
HMSET user:1001:stats \
    login_count 0 \
    post_count 0 \
    comment_count 0 \
    like_count 0

# 更新统计
HINCRBY user:1001:stats login_count 1
HINCRBY user:1001:stats post_count 1

🛒 购物车管理

使用哈希存储用户的购物车信息:

# 添加商品到购物车
HSET cart:user:1001 product:101 2    # 商品101,数量2
HSET cart:user:1001 product:102 1    # 商品102,数量1
HSET cart:user:1001 product:103 3    # 商品103,数量3

# 更新商品数量
HINCRBY cart:user:1001 product:101 1  # 商品101数量+1

# 获取购物车所有商品
HGETALL cart:user:1001

# 获取特定商品数量
HGET cart:user:1001 product:101

# 删除商品
HDEL cart:user:1001 product:102

# 清空购物车
DEL cart:user:1001

📊 网站统计

使用哈希存储网站的各种统计数据:

# 页面访问统计
HINCRBY stats:page:views home 1
HINCRBY stats:page:views about 1
HINCRBY stats:page:views contact 1

# 用户行为统计
HINCRBY stats:user:actions login 1
HINCRBY stats:user:actions register 1
HINCRBY stats:user:actions purchase 1

# 获取统计数据
HGETALL stats:page:views
HGETALL stats:user:actions

# 按日期统计
HINCRBY stats:daily:2024-01-15 page_views 1
HINCRBY stats:daily:2024-01-15 unique_visitors 1

⚙️ 配置管理

使用哈希存储应用的配置信息:

# 数据库配置
HMSET config:database \
    host "localhost" \
    port "3306" \
    username "root" \
    database "myapp" \
    max_connections "100"

# 缓存配置
HMSET config:cache \
    redis_host "localhost" \
    redis_port "6379" \
    default_ttl "3600" \
    max_memory "1gb"

# 获取配置
HGET config:database host
HGET config:cache default_ttl

# 更新配置
HSET config:database max_connections "200"

性能优化建议

哈希 vs 字符串

存储对象的两种方式对比:

# 方式1:使用字符串存储JSON
SET user:1001 "{\"name\":\"张三\",\"age\":25,\"city\":\"北京\"}"
# 优点:简单直接
# 缺点:更新单个字段需要序列化/反序列化整个对象

# 方式2:使用哈希存储
HMSET user:1001 name "张三" age 25 city "北京"
# 优点:可以单独操作字段,内存效率高
# 缺点:不能设置单个字段的过期时间