تصميم الخلفية

أنماط توسيع قواعد البيانات: دليل Sharding و Replication و Partitioning

توسيع قواعد البيانات مع sharding و replication و partitioning. يغطي أنماط توسيع PostgreSQL و MySQL و MongoDB مع أرقام أداء حقيقية.

Khalid Aboubakr
22 دقيقة قراءة
DatabasePostgresqlMongodbShardingReplicationIndexingPartitioningMysql

مقدمة

قرارات تصميم قواعد البيانات المتخذة في بداية المشروع غالباً ما تصبح الأصعب للتغيير لاحقاً. فهم أنماط قابلية التوسع من البداية يساعد على تجنب الترحيلات المؤلمة وأزمات الأداء.

الاختيار بين SQL و NoSQL

متى تختار PostgreSQL (SQL)

-- PostgreSQL يتفوق مع: -- 1. الاستعلامات المعقدة والضم SELECT o.id, o.total_amount, c.name as customer_name, json_agg( json_build_object( 'product', p.name, 'quantity', oi.quantity ) ) as items FROM orders o JOIN customers c ON o.customer_id = c.id JOIN order_items oi ON o.id = oi.order_id GROUP BY o.id, c.name; -- 2. معاملات ACID BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2; COMMIT;

متى تختار MongoDB (NoSQL)

// MongoDB يتفوق مع: // 1. المخططات المرنة التي تتطور // 2. أنماط الوصول القائمة على المستندات // 3. إنتاجية كتابة عالية مع اتساق نهائي interface Order { _id: ObjectId; customer: { id: ObjectId; name: string; email: string; }; items: Array<{ productId: ObjectId; name: string; quantity: number; }>; }

استراتيجيات الفهرسة

فهرسة PostgreSQL

-- فهرس B-tree للمساواة واستعلامات النطاق CREATE INDEX idx_orders_customer_date ON orders(customer_id, created_at DESC); -- فهرس جزئي للاستعلامات الشائعة على مجموعة فرعية CREATE INDEX idx_orders_pending ON orders(created_at) WHERE status = 'pending'; -- فهرس GIN للبحث في النص الكامل CREATE INDEX idx_products_search ON products USING GIN(to_tsvector('arabic', name || ' ' || description));

فهرسة MongoDB

// فهرس مركب يتبع قاعدة ESR (المساواة، الترتيب، النطاق) await collection.createIndex( { status: 1, createdAt: -1, totalAmount: 1 } ); // فهرس TTL للتنظيف التلقائي await collection.createIndex( { expiresAt: 1 }, { expireAfterSeconds: 0 } );

التقسيم والشاردينج

تقسيم PostgreSQL

-- التقسيم حسب النطاق بالتاريخ CREATE TABLE orders ( id BIGSERIAL, customer_id BIGINT NOT NULL, created_at TIMESTAMP NOT NULL ) PARTITION BY RANGE (created_at); CREATE TABLE orders_2024_q1 PARTITION OF orders FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');

شاردينج MongoDB

// اختر مفتاح الشارد بعناية - يحدد توزيع البيانات sh.shardCollection( "ecommerce.orders", { customerId: "hashed" } );

أنماط النسخ

نسخ القراءة

class DatabasePool { async query(sql: string, params: unknown[], options?: { readonly?: boolean }) { if (options?.readonly && this.replicas.length > 0) { const replica = this.replicas[this.replicaIndex]; this.replicaIndex = (this.replicaIndex + 1) % this.replicas.length; return replica.query(sql, params); } return this.primary.query(sql, params); } }

تحسين الاستعلام

-- تجنب SELECT * -- استخدم EXISTS بدلاً من IN للاستعلامات الفرعية -- عمليات الدفعات

الخلاصة

تصميم قواعد البيانات للتوسع يتطلب:

  1. اختر قاعدة البيانات المناسبة لأنماط الوصول الخاصة بك
  2. افهرس استراتيجياً بناءً على أنماط الاستعلام الفعلية
  3. قسّم مبكراً إذا توقعت نمو البيانات
  4. استخدم نسخ القراءة لتوسيع أعباء العمل الثقيلة بالقراءة
  5. حسّن الاستعلامات قبل إضافة الأجهزة

مقالات ذات صلة

هندسة البرمجياتقراءة 22 دقيقة

نمط CQRS و Event Sourcing: التنفيذ مع أمثلة كود

دليل تنفيذ CQRS و Event Sourcing الكامل مع TypeScript و Node.js. يغطي مخازن الأحداث والإسقاطات واللقطات ومتى تستحق هذه الأنماط التعقيد.