مجموعات Redis (الجزء 2)
يغطي هذا الدرس عمليات تقاطع واتحاد وفرق المجموعات — أقوى ميزات المجموعات.
نظرة عامة على عمليات المجموعات
تدعم Redis ثلاث عمليات مجموعات:
| العملية | الوصف | الأمر |
|---|---|---|
| التقاطع | العناصر الموجودة في جميع المجموعات | SINTER |
| الاتحاد | العناصر الموجودة في أي مجموعة | SUNION |
| الفرق | العناصر في المجموعة الأولى وليست في الأخرى | SDIFF |
المجموعة أ: {1, 2, 3, 4}
المجموعة ب: {3, 4, 5, 6}
التقاطع أ∩ب: {3, 4}
الاتحاد أ∪ب: {1, 2, 3, 4, 5, 6}
الفرق أ-ب: {1, 2}
SINTER: التقاطع
التقاطع يُرجع العناصر الموجودة في جميع المجموعات المحددة.
الاستخدام الأساسي
REDIS
# إنشاء مجموعتين
SADD set1 "a" "b" "c" "d"
SADD set2 "c" "d" "e" "f"
# حساب التقاطع
SINTER set1 set2
1) "c"
2) "d"
تقاطع مجموعات متعددة
REDIS
SADD set3 "c" "d" "g"
# تقاطع ثلاث مجموعات
SINTER set1 set2 set3
1) "c"
2) "d"
مجموعة غير موجودة
REDIS
# إذا كانت المجموعة غير موجودة، يتم التعامل معها كفارغة
SINTER set1 notexist
(empty array)
SINTERCARD: عددية التقاطع (Redis 7.0+)
REDIS
SINTERCARD 2 set1 set2
(integer) 2 # التقاطع يحتوي على عنصرين
SUNION: الاتحاد
الاتحاد يُرجع العناصر الموجودة في أي من المجموعات.
الاستخدام الأساسي
REDIS
SADD set1 "a" "b" "c"
SADD set2 "c" "d" "e"
# حساب الاتحاد
SUNION set1 set2
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
اتحاد مجموعات متعددة
REDIS
SADD set3 "e" "f" "g"
# اتحاد ثلاث مجموعات
SUNION set1 set2 set3
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "g"
SDIFF: الفرق
الفرق يُرجع العناصر الموجودة في المجموعة الأولى وليست في أي من المجموعات الأخرى.
الاستخدام الأساسي
REDIS
SADD set1 "a" "b" "c" "d"
SADD set2 "c" "d" "e" "f"
# set1 - set2
SDIFF set1 set2
1) "a"
2) "b"
فرق مجموعات متعددة
REDIS
SADD set3 "a" "g"
# set1 - set2 - set3
SDIFF set1 set2 set3
1) "b" # a موجود في set3، لذلك تم استبعاده
⚠️ ملاحظة: الفرق ليس تبادليًا.
SDIFF A B ≠ SDIFF B A.
تخزين نتائج عمليات المجموعات
SINTERSTORE: تخزين نتيجة التقاطع
REDIS
SADD set1 "a" "b" "c" "d"
SADD set2 "c" "d" "e" "f"
# تخزين نتيجة التقاطع في مجموعة جديدة
SINTERSTORE result set1 set2
(integer) 2 # مجموعة النتائج تحتوي على عنصرين
SMEMBERS result
1) "c"
2) "d"
SUNIONSTORE: تخزين نتيجة الاتحاد
REDIS
SUNIONSTORE result set1 set2
(integer) 6
SMEMBERS result
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
SDIFFSTORE: تخزين نتيجة الفرق
REDIS
SDIFFSTORE result set1 set2
(integer) 2
SMEMBERS result
1) "a"
2) "b"
💡 حالة الاستخدام: أوامر *STORE تحفظ النتائج في مجموعات جديدة للعمليات اللاحقة أو التخزين المؤقت.
حالات استخدام عمليات المجموعات
حالة الاستخدام 1: الأصدقاء المشتركون
REDIS
# أصدقاء المستخدم 1
SADD user:1:friends "user:2" "user:3" "user:4" "user:5"
# أصدقاء المستخدم 2
SADD user:2:friends "user:3" "user:4" "user:6" "user:7"
# الأصدقاء المشتركون
SINTER user:1:friends user:2:friends
1) "user:3"
2) "user:4"
حالة الاستخدام 2: أشخاص قد تعرفهم
REDIS
# أصدقائي
SADD user:1:friends "user:2" "user:3"
# أصدقاء الأصدقاء
SADD user:2:friends "user:3" "user:4" "user:5"
SADD user:3:friends "user:4" "user:6"
# اتحاد أصدقاء الأصدقاء
SUNIONSTORE friends:friends user:2:friends user:3:friends
# الأصدقاء الموصى بهم = أصدقاء الأصدقاء - أصدقائي - أنا
SADD me "user:1"
SUNIONSTORE exclude me user:1:friends
SDIFF friends:friends exclude
حالة الاستخدام 3: توصية المقالات
REDIS
# علامات المستخدم المُعجب بها
SADD user:1:liked:tags "redis" "database" "cache"
# علامات المقالات
SADD article:123:tags "redis" "nosql"
SADD article:456:tags "mysql" "database"
SADD article:789:tags "redis" "cache" "performance"
# توصية المقالات المطابقة لاهتمامات المستخدم (تقاطع العلامات)
SINTER user:1:liked:tags article:123:tags
1) "redis" # article:123 يطابق علامة واحدة
SINTER user:1:liked:tags article:789:tags
1) "redis"
2) "cache" # article:789 يطابق علامتين — توصية أقوى
حالة الاستخدام 4: تصفية المنتجات
REDIS
# فئات المنتجات
SADD category:phone "product:1" "product:2" "product:3"
SADD category:laptop "product:4" "product:5"
# علامات المنتجات التجارية
SADD brand:apple "product:1" "product:4"
SADD brand:samsung "product:2" "product:5"
# تصفية: هاتف + علامة Apple التجارية
SINTER category:phone brand:apple
1) "product:1"
حالة الاستخدام 5: التحقق من الأذونات
REDIS
# أذونات المستخدم
SADD user:1:permissions "read" "write" "delete"
# الأذونات المطلوبة للمورد
SADD resource:123:required "read" "write"
# التحقق مما إذا كان المستخدم لديه جميع الأذونات المطلوبة
SINTER user:1:permissions resource:123:required
1) "read"
2) "write"
# إذا كان عدد النتائج يساوي عدد الأذونات المطلوبة، المستخدم مخوّل
حالة الاستخدام 6: تجميع العلامات
REDIS
# علامات المقالات
SADD article:1:tags "redis" "database"
SADD article:2:tags "redis" "cache"
SADD article:3:tags "mysql" "database"
# جميع العلامات
SUNIONSTORE all:tags article:1:tags article:2:tags article:3:tags
SMEMBERS all:tags
1) "redis"
2) "database"
3) "cache"
4) "mysql"
أداء عمليات المجموعات
تعقيد الوقت
| الأمر | تعقيد الوقت | الوصف |
|---|---|---|
| SINTER | O(N*M) | N = حجم أصغر مجموعة، M = عدد المجموعات |
| SUNION | O(N) | N = إجمالي العناصر عبر جميع المجموعات |
| SDIFF | O(N) | N = إجمالي العناصر عبر جميع المجموعات |
⚠️ نصيحة أداء: عمليات المجموعات تجتاز جميع العناصر. المجموعات الكبيرة يمكن أن تكون بطيئة. التوصيات:
- استخدم SINTERCARD بدلاً من SINTER (يُعيد العد فقط)
- خزّن النتائج مؤقتًا (استخدم أوامر *STORE)
- حدد أحجام المجموعات
SSCAN: التكرار عبر المجموعات الكبيرة
للمجموعات الكبيرة، استخدم SSCAN للتكرار عبر العناصر على دفعات.
REDIS
# إنشاء مجموعة كبيرة
SADD large:set value1 value2 ... value10000
# بدء التكرار
SSCAN large:set 0
1) "127" # مؤشر للتكرار التالي
2) 1) "value1"
2) "value2"
...
# متابعة التكرار
SSCAN large:set 127
1) "0" # مؤشر 0 يعني اكتمال التكرار
2) ...
نمط المطابقة
REDIS
# الحصول فقط على العناصر المطابقة لنمط
SSCAN large:set 0 MATCH user:*
قيود المجموعات
1. غير مرتبة
REDIS
# لا يمكن الحصول على العناصر بترتيب محدد
SMEMBERS myset # ترتيب الإرجاع غير محدد
للبيانات المرتبة، استخدم المجموعات المرتبة.
2. سلاسل فقط
REDIS
# يمكن أن تكون عناصر المجموعة سلاسل فقط
SADD myset 123 # يخزن السلسلة "123"
3. لا توجد هياكل متداخلة
المجموعات لا تدعم المجموعات أو الكائنات المتداخلة.
❓ أسئلة شائعة
س ما الفرق بين SINTER و SINTERSTORE؟
ج SINTER يُرجع نتيجة التقاطع؛ SINTERSTORE يخزن النتيجة في مجموعة جديدة。
س هل الفرق تبادلي؟
ج لا.
SDIFF A B ≠ SDIFF B A. الترتيب مهم。س هل عمليات المجموعات تعدّل المجموعات الأصلية؟
*ج:لا. SINTER/SUNION/SDIFF للقراءة فقط. أوامر STORE تستبدل المجموعة الوجهة。
س:كيف أحسب حجم التقاطع دون الحصول على العناصر؟
ج استخدم SINTERCARD (Redis 7.0+)، أو استخدم SINTER + عد النتائج。
س ما مدى سرعة عمليات المجموعات؟
ج يعتمد على حجم المجموعة. عمليات المجموعات الكبيرة يمكن أن تكون بطيئة — حدد أحجام المجموعات أو استخدم التخزين المؤقت。
📖 ملخص
- SINTER: العناصر الموجودة في جميع المجموعات
- SUNION: العناصر الموجودة في أي مجموعة
- SDIFF: العناصر في المجموعة الأولى وليست في الأخرى
- أوامر *STORE تحفظ نتائج العمليات في مجموعات جديدة
- عمليات المجموعات من أجل: الأصدقاء المشتركون، التوصيات، التصفية، التحقق من الأذونات
- الأداء: عمليات المجموعات الكبيرة بطيئة — خزّن مؤقتًا أو حدد الأحجام
- SSCAN يتكرر عبر المجموعات الكبيرة لتجنب الحظر
📝 تمارين
- الأصدقاء المشتركون: أنشئ قائمتي أصدقاء لمستخدمين وابحث عن الأصدقاء المشتركين
- نظام التوصيات: نفذ نظام توصية مقالات بسيط يعتمد على علامات اهتمامات المستخدم
- تصفية المنتجات: استخدم المجموعات لتصفية المنتجات بمعايير متعددة (الفئة + العلامة التجارية)
- التحقق من الأذونات: استخدم عمليات المجموعات للتحقق مما إذا كان المستخدم لديه جميع الأذونات المطلوبة لمورد
الدرس التالي
في الدرس التالي، سنتعلم مجموعات Redis المرتبة (الجزء 1)، والتي تغطي عمليات المجموعات المرتبة الأساسية.



