تجزئات Redis (الجزء 1)

التجزئة هي مجموعة مفتاح-قيمة، مثالية لتخزين الكائنات. يغطي هذا الدرس عمليات التجزئة الأساسية.

ما هي التجزئة؟

التجزئة تشبه:

يمكن لمفتاح تجزئة Redis واحد تخزين أزواج حقل-قيمة متعددة:

user:1
├─ name  → "Alice"
├─ age   → "25"
├─ city  → "Beijing"
└─ email → "alice@example.com"
💡 الميزة: تسمح التجزئات بتعديل الحقول الفردية دون قراءة الكائن بأكمله. كما أنها أكثر كفاءة في الذاكرة من تخزين سلاسل JSON.

HSET و HGET: تعيين واسترجاع الحقول

HSET: تعيين حقل واحد

REDIS
# تعيين حقل واحد
HSET user:1 name "Alice"
(integer) 1  # يُرجع عدد الحقول المضافة حديثًا

# تعيين حقول متعددة
HSET user:1 age 25 city "Beijing"
(integer) 2  # أضاف حقلين جديدين

# تحديث حقل موجود
HSET user:1 name "Bob"
(integer) 0  # الحقل موجود بالفعل، يُرجع 0

HGET: الحصول على حقل واحد

REDIS
HGET user:1 name
"Alice"

HGET user:1 age
"25"

# الحقل غير موجود
HGET user:1 notexist
(nil)

HSETNX: التعيين فقط إذا كان الحقل غير موجود

REDIS
# التعيين فقط إذا كان الحقل غير موجود
HSETNX user:1 name "Charlie"
(integer) 0  # الحقل موجود بالفعل، فشل

HSETNX user:1 phone "13800138000"
(integer) 1  # الحقل غير موجود، تم التعيين بنجاح

HMSET و HMGET: عمليات دفعات

HMSET: تعيين حقول دفعات

REDIS
HMSET user:2 name "Bob" age 30 city "Shanghai" email "bob@example.com"
OK
⚠️ ملاحظة: بعد Redis 4.0.0، تم إهمال HMSET. استخدم HSET لتعيين حقول متعددة بدلاً من ذلك.

HMGET: الحصول على حقول دفعات

REDIS
HMGET user:2 name age city
1) "Bob"
2) "30"
3) "Shanghai"

# بما في ذلك الحقول غير الموجودة
HMGET user:2 name email phone
1) "Bob"
2) "bob@example.com"
3) (nil)  # phone غير موجود

HGETALL: الحصول على جميع الحقول والقيم

REDIS
HGETALL user:2
1) "name"
2) "Bob"
3) "age"
4) "30"
5) "city"
6) "Shanghai"
7) "email"
8) "bob@example.com"
⚠️ ملاحظة: HGETALL يُرجع مصفوفة متناوبة من أسماء الحقول والقيم. إذا كانت التجزئة كبيرة، فإن هذا يستهلك ذاكرة وعرض نطاق كبيرين — استخدم بحذر!

HKEYS و HVALS: الحصول على جميع أسماء الحقول أو القيم

HKEYS: الحصول على جميع أسماء الحقول

REDIS
HKEYS user:2
1) "name"
2) "age"
3) "city"
4) "email"

HVALS: الحصول على جميع القيم

REDIS
HVALS user:2
1) "Bob"
2) "30"
3) "Shanghai"
4) "bob@example.com"

HEXISTS: التحقق من وجود حقل

REDIS
HEXISTS user:2 name
(integer) 1  # موجود

HEXISTS user:2 phone
(integer) 0  # غير موجود

HDEL: حذف الحقول

REDIS
# حذف حقل واحد
HDEL user:2 email
(integer) 1  # تم حذف حقل واحد

# حذف حقول متعددة
HDEL user:2 age city
(integer) 2  # تم حذف حقلين

# حذف حقل غير موجود
HDEL user:2 notexist
(integer) 0

HLEN: الحصول على عدد الحقول

REDIS
HSET user:3 name "Charlie" age 28
HLEN user:3
(integer) 2  # لديه حقلين

# المفتاح غير موجود
HLEN notexist
(integer) 0

HSTRLEN: الحصول على طول قيمة الحقل

REDIS
HSET user:1 name "Alice" bio "Software Engineer"
HSTRLEN user:1 name
(integer) 5  # "Alice" طولها 5

HSTRLEN user:1 bio
(integer) 17  # "Software Engineer" طولها 17

حالات استخدام التجزئة

حالة الاستخدام 1: تخزين معلومات المستخدم

REDIS
# تخزين معلومات المستخدم الأساسية
HSET user:1001 name "Alice" age 25 email "alice@example.com" role "admin"

# الحصول على اسم المستخدم
HGET user:1001 name

# تحديث عمر المستخدم
HSET user:1001 age 26

# الحصول على جميع معلومات المستخدم
HGETALL user:1001

حالة الاستخدام 2: عربة التسوق

REDIS
# عربة تسوق المستخدم 1
HSET cart:user:1 product:101 2    # المنتج 101، الكمية 2
HSET cart:user:1 product:102 1    # المنتج 102، الكمية 1
HSET cart:user:1 product:103 5    # المنتج 103، الكمية 5

# عرض جميع العناصر في العربة
HGETALL cart:user:1

# تحديث كمية العنصر
HSET cart:user:1 product:101 3

# إزالة عنصر
HDEL cart:user:1 product:102

# التحقق من عدد العناصر في العربة
HLEN cart:user:1

حالة الاستخدام 3: بيانات وصفية للمقالة

REDIS
# تخزين معلومات المقالة
HSET article:123 title "Redis Tutorial" author "Alice" views 1000 likes 50

# زيادة عدد المشاهدات (يتطلب HINCRBY)
HINCRBY article:123 views 1

# زيادة عدد الإعجابات
HINCRBY article:123 likes 1

# الحصول على عنوان المقالة والمؤلف
HMGET article:123 title author

حالة الاستخدام 4: تخزين المنتج مؤقتًا

REDIS
# تخزين تفاصيل المنتج مؤقتًا
HSET product:2001 name "iPhone 15" price 5999 stock 100 category "phone"

# الحصول على سعر المنتج
HGET product:2001 price

# تحديث المخزون
HSET product:2001 stock 95

# التحقق من وجود المنتج
HEXISTS product:2001 name

Hash مقابل String لتخزين الكائنات

الطريقة 1: String مع JSON

REDIS
SET user:1 '{"name":"Alice","age":25,"email":"alice@example.com"}'

# الحصول على الكائن بأكمله
GET user:1

# تعديل العمر: يحتاج إلى قراءة وتحليل وتعديل وتسلسل وكتابة
# خطوات متعددة، غير فعال

الطريقة 2: Hash

REDIS
HSET user:1 name "Alice" age 25 email "alice@example.com"

# الحصول على حقل واحد
HGET user:1 name

# تعديل العمر: عملية خطوة واحدة
HSET user:1 age 26

# الحصول على حقول متعددة
HMGET user:1 name age

ملخص المقارنة

الجانب String (JSON) Hash
تعديل حقل واحد يحتاج قراءة الكائن بأكمله تعديل مباشر
استخدام الذاكرة أكبر (ترميز JSON زائد) أصغر (تخزين مضغوط)
استعلام حقل واحد يحتاج تحليل JSON وصول مباشر
كائنات متداخلة معقدة ✅ مدعومة ❌ غير مدعومة
تحديث جزئي ❌ صعب ✅ بسيط
💡 دليل الاختيار:

  • كائنات بسيطة (هيكل مسطح): استخدم Hash
  • كائنات معقدة (هيكل متداخل): استخدم String مع JSON
  • تعديل متكرر للحقول الفردية: استخدم Hash

تحسين ترميز التجزئة

يختار Redis ترميزًا تلقائيًا بناءً على حجم التجزئة:

الترميز الشرط الوصف
ziplist الحقول <= 512، طول القيمة <= 64 بايت قائمة مضغوطة، توفر الذاكرة
hashtable الحقول > 512 أو طول القيمة > 64 بايت جدول تجزئة، أداء أفضل

التحقق من نوع الترميز

REDIS
HSET small:hash field1 "value1" field2 "value2"
OBJECT ENCODING small:hash
"ziplist"

# بعد إضافة العديد من الحقول
HSET large:hash field1 "value1" field2 "value2" ... field600 "value600"
OBJECT ENCODING large:hash
"hashtable"
ℹ️ ملاحظة: يتم اختيار الترميز تلقائيًا بواسطة Redis. يمكنك ضبط العتبات من خلال معاملات الإعدادات.

❓ أسئلة شائعة

س كم عدد الحقول التي يمكن للتجزئة تخزينها؟
ج نظريًا غير محدود (2^32 - 1)، لكن عمليًا محدود بالذاكرة. يُوصى بالاحتفاظ بالتجزئات الفردية تحت بضعة آلاف من الحقول。
س هل يؤثر HGETALL على الأداء؟
ج نعم. إذا كانت التجزئة كبيرة، يُرجع HGETALL الكثير من البيانات، مما يستهلك الذاكرة وعرض النطاق. استخدم HSCAN للاسترجاع التكراري。
س هل يمكن أن تكون قيم حقول التجزئة رقمية؟
ج نعم. جميع القيم في Redis هي سلاسل، لكن السلاسل الرقمية تدعم العمليات الحسابية (HINCRBY)。
س كيف أحذف مفتاح تجزئة بأكمله؟
ج استخدم DEL لحذف المفتاح، وليس HDEL لحذف الحقول: DEL user:1
س هل تدعم التجزئة التداخل؟
ج لا. يمكن أن تكون قيم التجزئة سلاسل فقط. للتداخل، استخدم String مع JSON。

📖 ملخص

📝 تمارين

  1. معلومات المستخدم: استخدم تجزئة لتخزين معلومات المستخدم (الاسم، العمر، البريد الإلكتروني، المدينة)، ثم استرجع جميع المعلومات
  2. عربة التسوق: نفذ عربة تسوق باستخدام تجزئة — أضف 3 منتجات، عدّل كمية واحدة، احذف منتجًا واحدًا
  3. عمليات الحقول: استخدم HEXISTS للتحقق من وجود حقل، HLEN لعد الحقول
  4. تمرين المقارنة: خزّن نفس الكائن باستخدام كل من String JSON و Hash، قارن الخطوات لتعديل حقل واحد

الدرس التالي

في الدرس التالي، سنتعلم تجزئات Redis (الجزء 2)، والتي تغطي عمليات التجزئة المتقدمة والحسابات الرقمية.

100%