Hashes là cấu trúc dữ liệu hoàn hảo để lưu trữ objects trong Redis. Nếu bạn quen với JSON objects hoặc Python dictionaries, bạn sẽ thấy Hashes rất tự nhiên.

Hashes là gì?
Một Redis Hash là một tập hợp các field-value pairs, giống như một object nhỏ nằm dưới một key:
# Thay vì lưu từng field riêng biệt:
SET user:1001:name "Tan"
SET user:1001:email "[email protected]"
SET user:1001:age "28"
# Dùng Hash để gom nhóm:
HSET user:1001 name "Tan" email "[email protected]" age "28"
Tại sao dùng Hashes?
- ✅ Tiết kiệm memory — Ít overhead hơn nhiều keys riêng biệt
- ✅ Truy cập từng field — Không cần load toàn bộ object
- ✅ Cập nhật atomic — Sửa 1 field không ảnh hưởng field khác
- ✅ Tự động tối ưu — Redis dùng ziplist cho object nhỏ
Các lệnh cơ bản
Thêm và lấy dữ liệu
# Thêm một hoặc nhiều field
HSET user:1001 name "Tan" email "[email protected]" age "28"
# (integer) 3
# Lấy một field
HGET user:1001 name
# "Tan"
# Lấy nhiều fields
HMGET user:1001 name email
# 1) "Tan"
# 2) "[email protected]"
# Lấy tất cả fields và values
HGETALL user:1001
# 1) "name"
# 2) "Tan"
# 3) "email"
# 4) "[email protected]"
# 5) "age"
# 6) "28"
# Kiểm tra field tồn tại
HEXISTS user:1001 phone
# (integer) 0 → không tồn tại
# Lấy tất cả field names
HKEYS user:1001
# 1) "name"
# 2) "email"
# 3) "age"
# Lấy tất cả values
HVALS user:1001
# 1) "Tan"
# 2) "[email protected]"
# 3) "28"
# Đếm số fields
HLEN user:1001
# (integer) 3
Cập nhật dữ liệu
# Thêm field mới
HSET user:1001 phone "+84901234567"
# Thêm chỉ nếu field CHƯA tồn tại
HSETNX user:1001 avatar "default.png"
# (integer) 1 nếu thêm được
# (integer) 0 nếu field đã tồn tại
# Xóa field
HDEL user:1001 phone
# (integer) 1 nếu xóa thành công
Độ phức tạp Big O
| Lệnh | Độ phức tạp | Ghi chú |
|---|---|---|
| HSET / HGET / HDEL | O(1) | Thêm, lấy, xóa một field |
| HEXISTS / HLEN | O(1) | Kiểm tra tồn tại, đếm số field |
| HINCRBY / HINCRBYFLOAT | O(1) | Tăng giá trị số của field |
| HGETALL / HKEYS / HVALS | O(N) | N = số lượng field trong hash |
| HMSET / HMGET | O(N) | N = số lượng field thao tác |
| HSCAN | O(1) mỗi lần gọi / O(N) hoàn thành | Cursor-based, an toàn cho production |
💡 Lưu ý: Tránh dùng HGETALL trên hash có quá nhiều field (hàng nghìn field) — dùng HSCAN thay thế để duyệt dần.
Thao tác với số trong Hash
# Tăng giá trị số
HSET stats:page views "100"
HINCRBY stats:page views 1
# (integer) 101
HINCRBY stats:page views 50
# (integer) 151
# Tăng giá trị float
HSET product:100 rating "4.5"
HINCRBYFLOAT product:100 rating "0.3"
# "4.8"
User Profile Pattern
Hashes rất phù hợp để lưu trữ user profiles:
# Tạo user profile
HSET user:1001 \
name "Tan" \
email "[email protected]" \
age "28" \
role "admin" \
created_at "2026-03-30" \
last_login "2026-03-30T11:00:00Z"
# Cập nhật last_login khi user đăng nhập
HSET user:1001 last_login "2026-03-30T12:30:00Z"
# Tăng số lần đăng nhập
HINCRBY user:1001 login_count 1
# Lấy thông tin hiển thị
HMGET user:1001 name avatar role
Product Catalog Pattern
# Lưu thông tin sản phẩm
HSET product:555 \
name "iPhone 15 Pro" \
price "999" \
stock "50" \
category "electronics" \
rating "4.8"
# Giảm stock khi có đơn hàng
HINCRBY product:555 stock -1
# Cập nhật giá
HSET product:555 price "899"
# Kiểm tra còn hàng không
stock = HGET product:555 stock
if int(stock) > 0:
print("Còn hàng")
Session Storage Pattern
# Lưu session data
HSET session:abc123 \
user_id "1001" \
ip "192.168.1.1" \
user_agent "Mozilla/5.0..." \
cart_items "3"
# Thêm sản phẩm vào giỏ hàng
HINCRBY session:abc123 cart_items 1
# Kiểm tra session
HEXISTS session:abc123 user_id
# Xóa session khi logout
DEL session:abc123
Counters Pattern
# Thống kê theo ngày
HSET stats:2026-03-30 \
page_views "0" \
api_calls "0" \
errors "0" \
unique_users "0"
# Tăng counters
HINCRBY stats:2026-03-30 page_views 1
HINCRBY stats:2026-03-30 api_calls 1
# Lấy tất cả thống kê
HGETALL stats:2026-03-30
So sánh: Hash vs nhiều Strings
| Tiêu chí | Nhiều Strings | Một Hash |
|---|---|---|
| Memory | ❌ Nhiều overhead | ✅ Ít hơn (ziplist) |
| Truy cập 1 field | ✅ O(1) | ✅ O(1) |
| Truy cập tất cả | ❌ Nhiều lệnh | ✅ HGETALL |
| Xóa object | ❌ Nhiều DEL | ✅ 1 DEL |
| Set expiry | ❌ Mỗi key 1 TTL | ✅ 1 TTL cho cả object |
Bước tiếp theo
Bạn đã nắm vững Hashes trong Redis! Tiếp theo, chúng ta sẽ tìm hiểu về Keys & Expiration — cách quản lý keys và đặt thời gian sống cho dữ liệu.