مجموعات Redis المرتبة (الجزء 1)
المجموعة المرتبة هي مجموعة مع درجات، حيث يتم ترتيب العناصر حسب الدرجة. يغطي هذا الدرس عمليات المجموعات المرتبة الأساسية.
ما هي المجموعة المرتبة؟
ميزات المجموعة المرتبة:
- مرتبة: العناصر مرتبة حسب الدرجة (تصاعديًا)
- فريدة: العناصر فريدة، لكن الدرجات يمكن أن تتكرر
- كل عنصر له درجة: تُستخدم للفرز
leaderboard
├─ "player1" → degree: 100
├─ "player2" → degree: 200
├─ "player3" → degree: 300
└─ "player4" → degree: 400
💡 التنفيذ الداخلي: تستخدم المجموعات المرتبة قائمة تخطي + جدول تجزئة. قائمة التخطي تدعم الفرز الفعال واستعلامات النطاق، بينما جدول التجزئة يتيح عمليات بحث سريعة عن الدرجات.
ZADD: إضافة عناصر
الاستخدام الأساسي
REDIS
# إضافة عنصر واحد
ZADD leaderboard 100 "player1"
(integer) 1 # يُرجع عدد العناصر المضافة حديثًا
# إضافة عناصر متعددة
ZADD leaderboard 200 "player2" 300 "player3" 400 "player4"
(integer) 3
معاملات ZADD
REDIS
# NX: إضافة عناصر جديدة فقط، لا تقم بتحديث العناصر الموجودة
ZADD leaderboard NX 150 "player1"
(integer) 0 # player1 موجود بالفعل، لم يتم التحديث
# XX: تحديث العناصر الموجودة فقط، لا تقم بإضافة عناصر جديدة
ZADD leaderboard XX 500 "player5"
(integer) 0 # player5 غير موجود، لم يتم الإضافة
# CH: إرجاع عدد العناصر التي تغيرت (بما في ذلك التحديثات)
ZADD leaderboard CH 120 "player1"
(integer) 1 # تم تحديث درجة player1
# INCR: زيادة الدرجة (مكافئ لـ ZINCRBY)
ZADD leaderboard INCR 50 "player1"
"170" # يُرجع الدرجة الجديدة
تحديث درجة عنصر موجود
REDIS
# إذا كان العنصر موجودًا بالفعل، قم بتحديث درجته
ZADD leaderboard 250 "player1"
# عرض الدرجة الجديدة
ZSCORE leaderboard "player1"
"250"
ZSCORE: الحصول على درجة عنصر
REDIS
ZADD leaderboard 100 "player1" 200 "player2"
# الحصول على الدرجة
ZSCORE leaderboard "player1"
"100"
# العنصر غير موجود
ZSCORE leaderboard "notexist"
(nil)
ZRANK و ZREVRANK: الحصول على الترتيب
ZRANK: الترتيب من الأقل إلى الأعلى
REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"
# الترتيب يبدأ من 0
ZRANK leaderboard "player1"
(integer) 0 # المركز الأول (أقل درجة)
ZRANK leaderboard "player2"
(integer) 1 # المركز الثاني
ZRANK leaderboard "player3"
(integer) 2 # المركز الثالث
ZREVRANK: الترتيب من الأعلى إلى الأقل
REDIS
# الترتيب من الأعلى إلى الأقل (أعلى درجة هي الترتيب 0)
ZREVRANK leaderboard "player3"
(integer) 0 # المركز الأول (أعلى درجة)
ZREVRANK leaderboard "player2"
(integer) 1 # المركز الثاني
ZREVRANK leaderboard "player1"
(integer) 2 # المركز الثالث
💡 قواعد الترتيب:
- ZRANK: من الأقل إلى الأعلى، أقل درجة لها الترتيب 0
- ZREVRANK: من الأعلى إلى الأقل، أعلى درجة لها الترتيب 0
- الترتيب يبدأ من 0، المركز الأول له الترتيب 0
ZRANGE و ZREVRANGE: الحصول على العناصر حسب نطاق الترتيب
ZRANGE: الحصول حسب نطاق الترتيب (من الأقل إلى الأعلى)
REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3" 400 "player4"
# الحصول على جميع العناصر
ZRANGE leaderboard 0 -1
1) "player1"
2) "player2"
3) "player3"
4) "player4"
# الحصول على أول عنصرين
ZRANGE leaderboard 0 1
1) "player1"
2) "player2"
# الحصول على آخر عنصرين
ZRANGE leaderboard -2 -1
1) "player3"
2) "player4"
# الحصول على العناصر مع الدرجات
ZRANGE leaderboard 0 -1 WITHSCORES
1) "player1"
2) "100"
3) "player2"
4) "200"
5) "player3"
6) "300"
7) "player4"
8) "400"
ZREVRANGE: الحصول حسب نطاق الترتيب (من الأعلى إلى الأقل)
REDIS
# الحصول على جميع العناصر من الأعلى إلى الأقل
ZREVRANGE leaderboard 0 -1 WITHSCORES
1) "player4"
2) "400"
3) "player3"
4) "300"
5) "player2"
6) "200"
7) "player1"
8) "100"
# الحصول على أفضل 3 (أعلى الدرجات)
ZREVRANGE leaderboard 0 2 WITHSCORES
1) "player4"
2) "400"
3) "player3"
4) "300"
5) "player2"
6) "200"
ZCARD: الحصول على عدد العناصر
REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"
ZCARD leaderboard
(integer) 3
ZCOUNT: عد العناصر ضمن نطاق درجة
REDIS
ZADD leaderboard 100 "player1" 150 "player2" 200 "player3" 250 "player4" 300 "player5"
# عد العناصر بدرجات بين 150 و 250
ZCOUNT leaderboard 150 250
(integer) 3 # player2، player3، player4
# استخدم -inf و +inf للانهاية السالبة والموجبة
ZCOUNT leaderboard -inf +inf
(integer) 5 # جميع العناصر
ZREM: إزالة العناصر
REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"
# إزالة عنصر واحد
ZREM leaderboard "player1"
(integer) 1
# إزالة عناصر متعددة
ZREM leaderboard "player2" "player3"
(integer) 2
# إزالة عنصر غير موجود
ZREM leaderboard "notexist"
(integer) 0
ZINCRBY: زيادة الدرجة
REDIS
ZADD leaderboard 100 "player1"
# زيادة الدرجة بمقدار 50
ZINCRBY leaderboard 50 "player1"
"150" # يُرجع الدرجة الجديدة
# إنقاص الدرجة (تمرير رقم سالب)
ZINCRBY leaderboard -20 "player1"
"130"
حالات استخدام المجموعات المرتبة
حالة الاستخدام 1: لوحة متصدرين للألعاب
REDIS
# تحديث درجات اللاعبين
ZADD game:leaderboard 1500 "player:123"
ZADD game:leaderboard 2300 "player:456"
ZADD game:leaderboard 1800 "player:789"
# الحصول على أفضل 10
ZREVRANGE game:leaderboard 0 9 WITHSCORES
# الحصول على ترتيب اللاعب
ZREVRANK game:leaderboard "player:123"
# زيادة درجة اللاعب
ZINCRBY game:leaderboard 100 "player:123"
حالة الاستخدام 2: البحث الرائج
REDIS
# تحديث درجات الرواج
ZADD hot:search 10000 "Redis tutorial"
ZADD hot:search 8000 "Python basics"
ZADD hot:search 15000 "JavaScript"
# الحصول على أفضل 10 رائجة
ZREVRANGE hot:search 0 9 WITHSCORES
# زيادة درجة الرواج
ZINCRBY hot:search 100 "Redis tutorial"
حالة الاستخدام 3: قائمة انتظار مؤجلة
REDIS
# إضافة مهام مؤجلة (الدرجة هي طابع زمني للتنفيذ)
ZADD delay:queue 1719129600 "task:1" # 2024-06-23 10:00:00
ZADD delay:queue 1719133200 "task:2" # 2024-06-23 11:00:00
# الحصول على المهام قبل الوقت الحالي (المهام التي يجب تنفيذها)
ZRANGEBYSCORE delay:queue -inf 1719129600
حالة الاستخدام 4: العلامات المرجحة
REDIS
# علامات اهتمامات المستخدم (الدرجة هي مستوى الاهتمام)
ZADD user:1:interests 100 "redis"
ZADD user:1:interests 80 "database"
ZADD user:1:interests 60 "cache"
# الحصول على أكثر العلامات أهمية للمستخدم
ZREVRANGE user:1:interests 0 4 WITHSCORES
حالة الاستخدام 5: ترتيب الامتحانات
REDIS
# درجات الطلاب
ZADD exam:math 95 "student:1"
ZADD exam:math 88 "student:2"
ZADD exam:math 92 "student:3"
# الحصول على ترتيب الدرجات
ZREVRANGE exam:math 0 -1 WITHSCORES
# الحصول على ترتيب الطالب
ZREVRANK exam:math "student:1"
تحسين ترميز المجموعة المرتبة
يختار Redis ترميزًا تلقائيًا بناءً على حجم المجموعة المرتبة:
| الترميز | الشرط | الوصف |
|---|---|---|
| ziplist | العناصر <= 128، طول العنصر <= 64 بايت | قائمة مضغوطة، توفر الذاكرة |
| skiplist | العناصر > 128 أو طول العنصر > 64 بايت | قائمة تخطي + جدول تجزئة، أداء أفضل |
التحقق من نوع الترميز
REDIS
ZADD small:zset 1 "a" 2 "b" 3 "c"
OBJECT ENCODING small:zset
"ziplist"
# بعد إضافة العديد من العناصر
OBJECT ENCODING large:zset
"skiplist"
❓ أسئلة شائعة
س ما الفرق بين المجموعة المرتبة والمجموعة؟
ج كل عنصر في المجموعة المرتبة له درجة ويتم ترتيبه بها. المجموعات غير مرتبة. المجموعات المرتبة مثالية للوحات المتصدرين وسيناريوهات الترتيب。
س هل يمكن أن تكون الدرجات أعدادًا عشرية؟
ج نعم. الدرجات هي أعداد عائمة مزدوجة الدقة، تدعم الأعداد العشرية。
س هل ZRANK يُرجع الترتيب بدءًا من 0 أم 1؟
ج من 0. المركز الأول له الترتيب 0، المركز الثاني له الترتيب 1。
س كيف أحصل على العنصر ذي أعلى درجة؟
ج استخدم
ZREVRANGE key 0 0 أو ZRANGE key -1 -1。س هل يمكن تكرار العناصر؟
ج لا. العناصر فريدة، لكن الدرجات يمكن أن تتكرر。
📖 ملخص
- المجموعات المرتبة هي مجموعات مع درجات؛ العناصر مرتبة حسب الدرجة
- ZADD يضيف عناصر، ZSCORE يحصل على الدرجات
- ZRANK/ZREVRANK يحصل على الترتيب (من الأقل إلى الأعلى / من الأعلى إلى الأقل)
- ZRANGE/ZREVRANGE يحصل على العناصر حسب نطاق الترتيب
- ZCARD يحصل على عدد العناصر، ZCOUNT يعد العناصر في نطاق درجة
- ZREM يزيل العناصر، ZINCRBY يزيد الدرجات
- تطبيقات المجموعات المرتبة: لوحات المتصدرين، الرائج، قوائم الانتظار المؤجلة، الترتيب
📝 تمارين
- لوحة متصدرين: استخدم مجموعة مرتبة لتنفيذ لوحة متصدرين للألعاب — حدث الدرجات، اعرض الترتيب، احصل على أفضل 10
- قائمة رائجة: نفذ قائمة بحث رائجة — حدث درجات الرواج، اعرض الرائج، زد الرواج
- ترتيب امتحان: خزّن درجات الطلاب في مجموعة مرتبة، اعرض الترتيب والدرجات
- قائمة انتظار مؤجلة: استخدم مجموعة مرتبة لتنفيذ قائمة انتظار مهام مؤجلة — أضف مهام، احصل على المهام المستحقة
الدرس التالي
في الدرس التالي، سنتعلم مجموعات Redis المرتبة (الجزء 2)، والتي تغطي عمليات المجموعات المرتبة المتقدمة.



