· Admin

Laravel ile Veritabanı Sharding ve Partitioning

Milyonlarca satır veri biriktikçe sorgular yavaşlar, migration'lar uzar, backup'lar kabusa döner. İki çözüm var: Sharding (veriyi farklı sunuculara dağıtma) ve Partitioning (aynı sunucuda tabloyu parçalama). İkisi de büyük veritabanı yönetiminde kritik teknikler.

Sharding Nedir?

Sharding, büyük veritabanlarını daha küçük, bağımsız parçalara ayırma işlemi. Her parça (shard) farklı sunucuda çalışır.

Çalışma prensibi: Veriler bir anahtar değerine (örneğin kullanıcı ID'si) göre yönlendirilir. Her shard bağımsız olarak çalışabilir.

Laravel'de Sharding

Birden fazla veritabanı bağlantısı tanımlama:

// config/database.php
'connections' => [
    'shard_1' => [
        'driver' => 'mysql',
        'host' => '192.168.1.10',
        'database' => 'app_shard_1',
        'username' => env('DB_USERNAME'),
        'password' => env('DB_PASSWORD'),
    ],
    'shard_2' => [
        'driver' => 'mysql',
        'host' => '192.168.1.11',
        'database' => 'app_shard_2',
        'username' => env('DB_USERNAME'),
        'password' => env('DB_PASSWORD'),
    ],
],

Shard yönlendirme mantığı:

class ShardManager
{
    public function getConnection(int $userId): string
    {
        // Basit modulo ile shard belirleme
        $shardNumber = ($userId % 2) + 1;
        return "shard_{$shardNumber}";
    }
}

Kullanım:

$shardManager = new ShardManager();
$connection = $shardManager->getConnection($userId);

// Veri ekleme
DB::connection($connection)->table('orders')->insert([
    'user_id' => $userId,
    'total' => 150.00,
]);

// Veri okuma
$orders = DB::connection($connection)
    ->table('orders')
    ->where('user_id', $userId)
    ->get();

Shard'lar Arası Sorgulama

Tüm shard'lardan veri toplamak gerektiğinde:

class CrossShardQuery
{
    private array $shards = ['shard_1', 'shard_2'];

    public function getAllOrders(): Collection
    {
        $results = collect();

        foreach ($this->shards as $shard) {
            $orders = DB::connection($shard)->table('orders')->get();
            $results = $results->merge($orders);
        }

        return $results;
    }
}

Partitioning Nedir?

Partitioning, aynı sunucuda büyük tabloları fiziksel olarak parçalama. Veritabanı motoru sorguyu otomatik olarak doğru partition'a yönlendirir.

Partitioning Türleri

Tür Açıklama Kullanım
Range Tarih/sayı aralıklarına göre Zaman bazlı veriler
List Belirli değerlere göre Kategori bazlı veriler
Hash Hash fonksiyonu ile dağıtım Dengeli dağılım
Composite Birden fazla yöntemin birleşimi Karmaşık senaryolar

Laravel'de Range Partitioning

// Migration
public function up(): void
{
    DB::statement("
        CREATE TABLE orders (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
            user_id BIGINT UNSIGNED NOT NULL,
            total DECIMAL(10,2) NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id, created_at)
        )
        PARTITION BY RANGE (YEAR(created_at)) (
            PARTITION p2024 VALUES LESS THAN (2025),
            PARTITION p2025 VALUES LESS THAN (2026),
            PARTITION p2026 VALUES LESS THAN (2027),
            PARTITION p_future VALUES LESS THAN MAXVALUE
        )
    ");
}

List Partitioning

DB::statement("
    CREATE TABLE logs (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        level VARCHAR(10) NOT NULL,
        message TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id, level)
    )
    PARTITION BY LIST COLUMNS (level) (
        PARTITION p_error VALUES IN ('error', 'critical'),
        PARTITION p_warning VALUES IN ('warning'),
        PARTITION p_info VALUES IN ('info', 'debug')
    )
");

Partition Ekleme/Silme

// Yeni yıl için partition ekle
DB::statement("ALTER TABLE orders ADD PARTITION (PARTITION p2027 VALUES LESS THAN (2028))");

// Eski partition'ı sil (veri ile birlikte!)
DB::statement("ALTER TABLE orders DROP PARTITION p2024");

Eski veriyi silmek DROP PARTITION ile anlık olur — DELETE FROM ile milyonlarca satır silmekten çok daha hızlı.

Sharding vs Partitioning

Özellik Sharding Partitioning
Veri dağılımı Farklı sunucular Aynı sunucu
Ölçekleme Yatay (horizontal) Dikey (vertical)
Karmaşıklık Yüksek Orta
Cross-query Zor Kolay
Bakım Her shard ayrı Tek sunucu
Kullanım Yüksek trafik, çok kullanıcı Büyük tablolar, zaman bazlı veri

Ne Zaman Hangisi?

Sharding:

  • Milyonlarca aktif kullanıcı
  • Coğrafi dağıtım ihtiyacı
  • Tek sunucu kapasitesi yetmiyor

Partitioning:

  • Büyük tablolar (100M+ satır)
  • Zaman bazlı veri (loglar, siparişler)
  • Eski veriyi hızlı silme/arşivleme

İkisi birlikte:

  • Her shard içinde partition uygulama
  • Hem yatay hem dikey ölçekleme

Sonuç

Sharding ve Partitioning büyük veritabanı yönetiminde temel teknikler. Laravel'de sharding birden fazla bağlantı ile, partitioning raw SQL migration ile uygulanır. Seçim uygulamanızın ölçeğine ve ihtiyacına bağlı — çoğu proje için önce partitioning yeterli, sharding genelde çok büyük ölçekte gerekir.