Veri Taşıma Nedir? (Database Migration)

Migration nedir?

Database migration, bir veri tabanından başka bir veri tabanına veri taşıma işlemidir. Bu işlem, genellikle bir işletmenin yeni bir sistem veya platforma geçmesi, fiziksel sunucuların sanal sunuculara taşınması veya verilerin bir depolama ortamından başka bir depolama ortamına aktarılması gibi durumlarda yapılır.

Database migration, veri kaybı, bozulma veya uyumsuzluk riskini azaltmak için özel bir servis kullanılarak gerçekleştirilir. Bu servis, kaynak ve hedef veri tabanları arasında veri dönüştürme, eşitleme, doğrulama ve senkronizasyon gibi işlemleri yapar. Database migration veri tabanı performansını, güvenliğini, esnekliğini ve maliyetini iyileştirmeye yardımcı olabilir. Ancak database migration yapmadan önce veri tabanı yapısını, boyutunu, ilişkilerini ve gereksinimlerini iyi analiz etmek gerekir.

Peki database migration neden yaparız?

Database migration yapmak için çeşitli nedenler olabilir. Bazı yaygın nedenler şunlardır:

  • Sistem veya platform değişikliği bu sebeplerden biridir; bir işletme yeni bir yazılım, donanım sistemine veya platformuna geçmek isteyebilir.

  • Performans veya güvenlik iyileştirme sağladığı için kullanabiliriz. Bir veri tabanının performansını, güvenliğini, esnekliğini veya maliyetini iyileştirmek için database migration yapılması gerekebilir. Örneğin, veri tabanını daha hızlı, daha güvenli veya daha ucuz bir sunucuya taşımak isteyebilirsiniz.

  • Veri depolama veya analiz gereksinimi olan büyük yapılarda bizlere kolaylık sağlar. Bir veri tabanının veri depolama veya analiz gereksinimlerini karşılamak için database migration yapılması gerekebilir. Örneğin, veri tabanını daha büyük, daha karmaşık veya daha çok boyutlu bir veri modeline sahip bir veri tabanına taşımak isteyebilirsiniz.

Database migration yapmak, veri tabanınızı daha iyi hale getirebilir. Ancak aynı zamanda bazı riskler ve zorluklar da içerir. Bu nedenle database migration yapmadan önce veri tabanınızı iyi analiz etmeli, uygun bir strateji belirlemeli ve veri kaybı, bozulma veya uyumsuzluk gibi olası sorunlara karşı önlem alınmalıdır.

Golang programlama dilinde migration nasıl yaparız?

Bunun için bir çok seçeneğimiz var; bunlardan bazıları aşağıda belirttim:

  • Golang-Migrate: Bu kütüphane, farklı veri tabanı motorlarıyla çalışabilen ve hem CLI hem de Golang kütüphanesi olarak kullanılabilen bir araçtır. Migration dosyalarını oluşturmak, çalıştırmak ve geri almak için çeşitli komutlar sunmaktadır. Bu seçeneği nasıl kullanabileceğinizi önceki mesajımda anlatmıştım.

  • Goose: Bu kütüphane de, golang-migrate gibi, hem CLI hem de Golang kütüphanesi olarak kullanılabilen bir başka migration aracıdır. Migration dosyalarını SQL veya Go kodu olarak yazabilirsiniz. Migration dosyalarını çalıştırmak için goose up veya goose down komutlarını kullanabilirsiniz. Ayrıca, goose status komutu ile migration durumunu kontrol edebilirsiniz.

  • Sql-migrate: Bu kütüphane, sadece SQL dosyalarını destekleyen bir migration aracıdır. Migration dosyalarını çalıştırmak için sql-migrate up veya sql-migrate down komutlarını kullanabilirsiniz. Ayrıca, sql-migrate status komutu ile migration durumunu kontrol edebilirsiniz.

  • Gorm: Bu kütüphane, Golang için popüler bir ORM (Object Relational Mapping) aracıdır. Veri tabanı işlemlerini Go nesneleri ile yapmanızı sağlar. Ayrıca, migration özelliği de sunar. Migration dosyalarını Go kodu olarak yazabilirsiniz. Migration dosyalarını çalıştırmak için db.AutoMigrate veya db.Migrate fonksiyonlarını kullanabilirsiniz.

  • Sqlboiler: Bu kütüphane, Golang için başka bir ORM aracıdır. Veri tabanı şemasından Go kodu üretir. Migration özelliği için soda adlı bir CLI aracı kullanır. Migration dosyalarını oluşturmak, çalıştırmak ve geri almak için çeşitli komutlar sunar.

  • Ent: Bu kütüphane, Golang için yeni ve modern bir ORM aracıdır. Veri tabanı şemasını Go kodu olarak tanımlamanızı sağlar. Migration özelliği için entc adlı bir CLI aracı kullanır. entc, migration dosyalarını oluşturmak ve çalıştırmak için çeşitli komutlar sunar.

Göz önünde bulundurmanız gerekenler

Migration kullanırken dikkat etmeniz gereken birkaç önemli nokta var:

  • Her zaman yedek alın: Migration uygulamadan ve geri almaya geçmeden önce veri tabanınızın yedeklerini almayı unutmayın.

  • Test ortamında deneyin: Production ortamında uygulamadan önce migrationları bir test ortamında deneyin.

  • Migration ve versiyonlama: Her migration ekleme ve geri alma işlemi, yönetim ve sürüm kontrolü açısından düzgün bir şekilde yönetilmelidir.

Goose Migration Tool

Goose Nedir?

Golang goose, Go programlama dili ile yazılmış bir database migration aracıdır. Goose, SQL dosyaları veya Go fonksiyonları ile veri tabanı şemasını yönetmenize olanak sağlar. Goose, veri tabanı sürümlerini takip eder ve veri tabanınızı en güncel sürüme veya belirli bir sürüme göre günceller. Goose, PostgreSQL, MySQL, SQLite3, MSSQL, Redshift, TiDB, ClickHouse, Vertica ve YDB gibi çeşitli veri tabanı sürücülerini destekler.

Goose Nasıl İndirilir?

Goose kullanmak için öncelikle goose komut satırı aracını kurmanız gerekir. Bunu yapmak için

go install github.com/pressly/goose/v3/cmd/goose@latest

komutunu çalıştırabilirsiniz. Daha sonra veri tabanı sürücünüzü ve bağlantı dizinizi belirterek goose komutlarını kullanabilirsiniz.

Goose Komutlarına Genel Bakış

İşte Goose ile kullanabileceğiniz bazı temel komutlar ve açıklamaları:

  • create - Yeni bir migration dosyası oluşturur.

  • up - Tüm bekleyen migration'ları sırasıyla uygular.

  • down - En son migration'ı geri alır.

  • status - Uygulanmış ve bekleyen migration'ların durumunu gösterir.

  • reset - Tüm migration'ları geri alır ve veri tabanını ilk durumuna getirir.

  • to - Veri tabanını belirli bir migration sürümüne günceller.

Goose ile Yeni Bir Migration Dosyası Oluşturma

Goose, yeni migration dosyalarını kolayca oluşturmanızı sağlar. Komut satırından aşağıdaki gibi yeni bir migration dosyası oluşturabilirsiniz:

Komut:
$ goose create sql_dosyanın_ismi sql
Çıktı:
$ Created new file:20240205082420_sql_dosyanın_ismi.sql

komutunu kullanabilirsiniz. Aynı zamanda migration dosyasında, veri tabanınızda yapmak istediğiniz değişiklikleri Go kodları ile belirtebilirsiniz. Örneğin:

Komut:
$ goose create sql_dosyanın_ismi go
Çıktı:
$ Created new file:20240205082420_sql_dosyanın_ismi.go

Bu komutlar, mevcut zaman damgası ile bir migration dosyası oluşturur. Zaman damgası birden fazla oluşturulan SQL dosyalarını hangi sıra ile migration yapması gerektiğini belirtir yani ilk oluşturduğunuz dosya ilk migration olacaktır. Örneğin:

└── database
   ├── 003_kullanıcılar.sql
   ├── 001_resimler.sql
   └── 002_takımlar.go
sırası
$ OK    001_resimler.sql
$ OK    002_takımlar.go
$ OK    003_kullanıcılar.sql

Migration Uygulama ve Geri Alma

Migration'ları veri tabanınıza uygulamak için Goose'un up komutunu kullanabilirsiniz. Bu, sırayla tüm migration dosyalarını çalıştırır:

Komut:
$ goose up
Çıktı:
$ OK    001_kullanıcılar.sql
$ OK    002_resimler.sql
$ OK    003_takımlar.go

Bir migrationı geri almak isterseniz down komutu ile son migrationı geri alabilirsiniz:

Komut:
$ goose down
Çıktı:
$ OK    001_kullanıcılar.sql
$ OK    002_resimler.sql
$ OK    003_takımlar.go

Birden fazla migrationı geri almak için down komutunu her seferinde tekrar çalıştırabilirsiniz.

Goose Durumunu Gösterme ve Migration Sıfırlama

Veri tabanınızın hangi migration sürümünde olduğunu ve uygulanan migrationların bir listesini görmek için status komutunu kullanabilirsiniz:

$ goose status
$   Applied At                  Migration
$   =======================================
$   Sun Jan  6 11:25:03 2024 -- 001_kullanıcılar.sql
$   Sun Jan  6 11:25:03 2024 -- 002_resimler.sql
$   Pending                  -- 003_takımlar.go

Eğer tüm migrationları sıfırlamak ve veri tabanınızı ilk durumuna çekmek isterseniz reset komutu yardımcı olacaktır:

Komut:
$ goose reset
Çıktı:
$ OK    003_takımlar.go rolled back
$ OK    002_resimler.sql rolled back
$ OK    001_kullanıcılar.sql rolled back

Bu komut, tüm migrationları geri alır ve veri tabanını ilk durumuna getirir.

Veri Tabanı Sürümünü Belirli Bir Migration'a Getirme

Eğer veri tabanınızı belirli bir migration sürümüne güncellemek istiyorsanız to komutu ile bu mümkündür:

Komut:
$ goose to 20240205082420
Çıktı:
$ OK    001_kullanıcılar.sql
$ OK    002_resimler.sql

Bu komut, belirtilen zaman damgasına sahip migrationa kadar olan tüm migrationları uygular veya geri alır.

Son olarak goose ile çok optimize çalışan bir tool olan SQLC'i inceleyeceğiz.

sqlc: SQL Derleyici

SQLC, SQL’den güvenli Go kodu üreten bir araçtır. SQLC ile SQL sorgularınızı ayrı bir dosyada yazabilir ve karşılık gelen Go kodunu oluşturabilirsiniz. Oluşturulan Go kodu, derleme zamanında kontrol edilebilen tip güvenli arayüzlere sahiptir. Bu, dinamik sorgularda oluşabilecek çalışma zamanı hatalarını önlemeye yardımcı olur.

SQLC kullanmanın avantajları şunlardır:

SQL sorgularınızı veri tabanı şemanızla eşleştirebilir ve veri tabanı değişikliklerini kolayca takip edebilirsiniz. SQL sorgularınız için güvenli Go fonksiyonları elde edebilir ve çalışma zamanı hatalarını azaltabilirsiniz. SQL sorgularınızı PostgreSQL, MySQL veya SQLite gibi farklı veri tabanı sürücüleriyle kullanabilirsiniz.

Sqlc Nasıl İndirilir

SQLC'ye başlamak için öncelikle goose komut satırı aracını kurmanız gerekir. Bunu yapmak için

go install github.com/kyleconroy/sqlc/cmd/sqlc@latest

GOPATH/bin dosyanızın kabuğunuzun PATH dosyasında olduğundan emin olun, böylece sqlc komutunu global olarak çalıştırabilirsiniz.

SQL'den Go Kodu Oluşturma

  1. Bir sqlc.yaml yapılandırma dosayası oluşturun.

  2. Örnek yapılandırma:

    version: "1"
    packages:
      - name: "db"
        path: "gen/db"
        queries: "./sql/query/" #sorguların bulunduğu klasör
        schema: "./sql/schema/" #tablolar ve anahtarların bulunduğu klasör
  3. Projenizdeki .sql dosyalarındaki SQL sorgularını tanımlayın:

  4. // kullanıcılar.sql
    -- name: Kullanıcı_Sil :exec
    DELETE FROM kullanıcılar WHERE kullanıcı_id = $1;
  5. After komutu çalıştırın:

  6. sqlc generate

    Çıktı olarak bize .sql dosyalarına göre .go dosyaları oluşturacaktır.Bu dosyalar bize Kullanıcı_Sil adlı bir fonkiyon verecektir.\

    //kullanıcılar.sql.go
    const deleteUser = `-- name: Kullanıcı_Sil :exec
    DELETE FROM kullanıcılar WHERE kullanıcı_id = $1
    `
    
    func (q *Queries) DeleteUser(ctx context.Context, userID uuid.UUID) error {
    	_, err := q.db.ExecContext(ctx, deleteUser, userID)
    	return err
    }

Bu örnekte SQLC, şema tanımlarını ./sql/schema/ dizininde, sorguları ise ./sql/query/ dizininde arayacaktır. Go kodunu oluşturacak ve gen/db dizinine yerleştirecektir.

Oluşturulan kod aşağıdaki özelliklere sahip olacaktır:

Veri tip güvenliği: Değişkenler ve dönüş türleri gerçek veri tabanı şemasına dayanır.

Derleme hataları: SQL sorguları ve şema arasındaki herhangi bir tutarsızlık Go derleme hatalarıyla sonuçlanacaktır.

SQLC'yi geçiş ve veri tabanı yönetiminize entegre ederek, SQL sorgularınızın hatasız olduğuna ve Go kodunuzun performans için optimize edildiğine dair soru işaretleriniz olmayacaktır.

Sqlc ve Goose İlişkisi

Yukarıdaki görselde görüldüğü gibi migration dosyalarınızı hem SQLC hem de goose okur. Ardından ikisi de görevlerini yerine getirirler; goose şablon dosyaları ile veri tabanını düzenler.

SQLC ise hem şablon hem de sorgu dosyalarını okur; ardından veri tipleri ve güvenli go kodları oluşturur; bu şekilde sorunsuz bir proje başlangıcına sahip olursunuz.

Last updated