انتقل إلى المحتوى الرئيسي
DevOpsMar 28, 2026

Deep EVM #26: التجزئة مقابل التقسيم — بنية الجداول الضخمة

OS
Open Soft Team

Engineering Team

التقسيم مقابل التجزئة

  • التقسيم — تقسيم جدول واحد إلى أجزاء داخل نفس قاعدة البيانات
  • التجزئة — توزيع البيانات عبر عدة خوادم قاعدة بيانات

متى يكفي التقسيم

التقسيم يكفي عندما:

  • البيانات تتسع في خادم واحد
  • الاستعلامات تستهدف قسماً واحداً عادةً
  • لا تحتاج توسعاً أفقياً للكتابة

متى تحتاج التجزئة

التجزئة ضرورية عندما:

  • حجم البيانات يتجاوز سعة خادم واحد
  • حمل الكتابة يتجاوز قدرة خادم واحد
  • تحتاج عزلاً جغرافياً للبيانات

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

// تجزئة بالتجزئة
fn get_shard(user_id: Uuid, num_shards: usize) -> usize {
    let hash = xxhash(&user_id.as_bytes());
    hash as usize % num_shards
}

// تجزئة بالنطاق
fn get_shard_by_date(created_at: DateTime, shards: &[ShardConfig]) -> &ShardConfig {
    shards.iter().find(|s| s.date_range.contains(&created_at)).unwrap()
}

التجزئة مع Rust

struct ShardedPool {
    pools: Vec<PgPool>,
}

impl ShardedPool {
    async fn query_user(&self, user_id: Uuid) -> Result<User> {
        let shard = get_shard(user_id, self.pools.len());
        sqlx::query_as::<_, User>("SELECT * FROM users WHERE id = $1")
            .bind(user_id)
            .fetch_one(&self.pools[shard])
            .await
            .map_err(Into::into)
    }
    
    async fn query_all_shards(&self, query: &str) -> Result<Vec<Row>> {
        let futures: Vec<_> = self.pools.iter()
            .map(|pool| sqlx::query(query).fetch_all(pool))
            .collect();
        
        let results = futures::future::join_all(futures).await;
        Ok(results.into_iter().flatten().flatten().collect())
    }
}

تحديات التجزئة

  1. الاستعلامات عبر التجزئات — بطيئة ومعقدة
  2. المعاملات الموزعة — تحتاج 2PC أو saga
  3. إعادة التوازن — تغيير عدد التجزئات يتطلب نقل البيانات
  4. مفتاح التجزئة — اختيار سيء يسبب نقاط ساخنة

المقارنة

الجانبالتقسيمالتجزئة
التعقيدمنخفضمرتفع
التوسععموديأفقي
المعاملاتمدعومةمعقدة
الصيانةسهلةصعبة
أقصى حجم~1 تيرابايتغير محدود

الخلاصة

ابدأ بالتقسيم — إنه أبسط ويكفي لمعظم الحالات. انتقل للتجزئة فقط عندما تصل لحدود خادم واحد. والأهم: اختر مفتاح التجزئة بعناية لأنه صعب التغيير لاحقاً.