مجموعات 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 BSDIFF 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 BSDIFF B A. الترتيب مهم。
س هل عمليات المجموعات تعدّل المجموعات الأصلية؟ *ج:لا. SINTER/SUNION/SDIFF للقراءة فقط. أوامر STORE تستبدل المجموعة الوجهة。

س:كيف أحسب حجم التقاطع دون الحصول على العناصر؟

ج استخدم SINTERCARD (Redis 7.0+)، أو استخدم SINTER + عد النتائج。
س ما مدى سرعة عمليات المجموعات؟
ج يعتمد على حجم المجموعة. عمليات المجموعات الكبيرة يمكن أن تكون بطيئة — حدد أحجام المجموعات أو استخدم التخزين المؤقت。

📖 ملخص

  • SINTER: العناصر الموجودة في جميع المجموعات
  • SUNION: العناصر الموجودة في أي مجموعة
  • SDIFF: العناصر في المجموعة الأولى وليست في الأخرى
  • أوامر *STORE تحفظ نتائج العمليات في مجموعات جديدة
  • عمليات المجموعات من أجل: الأصدقاء المشتركون، التوصيات، التصفية، التحقق من الأذونات
  • الأداء: عمليات المجموعات الكبيرة بطيئة — خزّن مؤقتًا أو حدد الأحجام
  • SSCAN يتكرر عبر المجموعات الكبيرة لتجنب الحظر

📝 تمارين

  1. الأصدقاء المشتركون: أنشئ قائمتي أصدقاء لمستخدمين وابحث عن الأصدقاء المشتركين
  2. نظام التوصيات: نفذ نظام توصية مقالات بسيط يعتمد على علامات اهتمامات المستخدم
  3. تصفية المنتجات: استخدم المجموعات لتصفية المنتجات بمعايير متعددة (الفئة + العلامة التجارية)
  4. التحقق من الأذونات: استخدم عمليات المجموعات للتحقق مما إذا كان المستخدم لديه جميع الأذونات المطلوبة لمورد

الدرس التالي

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

100%