DB の移行、なぜそれが重要なのでしょうか?
更新されたデータベース スキーマを使用して新しい更新を実稼働環境にデプロイしたが、その後バグが発生し、元に戻す必要があるという状況に直面したことはありませんか。移行が必要になるのはそのときです。
データベースの移行は、いくつかの重要な目的を果たします。
- スキーマの進化: アプリケーションが進化するにつれて、そのデータ モデルも変化します。移行により、開発者はデータベース スキーマを体系的に更新してこれらの変更を反映し、データベース構造がアプリケーション コードと確実に一致するようにすることができます。
- バージョン管理: 移行により、データベース スキーマのバージョンを管理する方法が提供され、チームが経時的に変更を追跡できるようになります。このバージョン管理は、データベースの進化を理解するのに役立ち、開発者間のコラボレーションに役立ちます。
- 環境全体の一貫性: 移行により、データベース スキーマが異なる環境 (開発、テスト、運用) 間で一貫していることが保証されます。これにより、バグや統合の問題につながる可能性のある不一致のリスクが軽減されます。
- ロールバック機能: 多くの移行ツールは変更のロールバックをサポートしており、移行によって問題が発生した場合に開発者がデータベースを以前の状態に戻すことができます。これにより、開発および展開プロセス中の安定性が向上します。
- 自動展開: 導入プロセスの一部として移行を自動化でき、手動介入なしで必要なスキーマ変更がデータベースに確実に適用されます。これにより、リリース プロセスが合理化され、人的エラーが削減されます。
golang プロジェクトに応募する
MySQL で GORM を使用し、簡単な移行、更新、ロールバックを可能にする、Golang サービスの包括的な運用グレードのセットアップを作成するには、移行ツールを組み込み、データベース接続プーリングを処理し、適切な構造体定義を確保する必要があります。プロセスをガイドする完全な例を次に示します:
プロジェクトの構造
/golang-service |-- main.go |-- database | |-- migration.go |-- models | |-- user.go |-- config | |-- config.go |-- migrations | |-- ... |-- go.mod
1. データベース設定 (config/config.go)
package config import ( "fmt" "log" "os" "time" "github.com/joho/godotenv" "gorm.io/driver/mysql" "gorm.io/gorm" ) var DB *gorm.DB func ConnectDB() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } // charset=utf8mb4: Sets the character set to utf8mb4, which supports all Unicode characters, including emojis. // parseTime=True: Tells the driver to automatically parse DATE and DATETIME values into Go's time.Time type. // loc=Local: Uses the local timezone of the server for time-related queries and storage. dsn := fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_NAME"), ) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("failed to connect database") } sqlDB, err := db.DB() if err != nil { panic("failed to configure database connection") } // Set connection pool settings sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) sqlDB.SetConnMaxLifetime(time.Hour) // 1.sqlDB.SetMaxIdleConns(10) // Sets the maximum number of idle (unused but open) connections in the connection pool. // A value of 10 means up to 10 connections can remain idle, ready to be reused. // 2. sqlDB.SetMaxOpenConns(100): // Sets the maximum number of open (active or idle) connections that can be created to the database. // A value of 100 limits the total number of connections, helping to prevent overloading the database. // 3. sqlDB.SetConnMaxLifetime(time.Hour): // Sets the maximum amount of time a connection can be reused before it’s closed. // A value of time.Hour means that each connection will be kept for up to 1 hour, after which it will be discarded and a new connection will be created if needed. DB = db }
2. データベースの移行 (database/migration.go)
package database import ( "golang-service/models" "golang-service/migrations" "gorm.io/gorm" ) func Migrate(db *gorm.DB) { db.AutoMigrate(&models.User{}) // Apply additional custom migrations if needed }
3. モデル (models/user.go)
package models import "gorm.io/gorm" type User struct { gorm.Model Name string `json:"name"` }
4. 環境設定(.env)
DB_USER=root DB_PASS=yourpassword DB_HOST=127.0.0.1 DB_PORT=3306 DB_NAME=yourdb
5. メインエントリーポイント (main.go)
package main import ( "golang-service/config" "golang-service/database" "golang-service/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) func main() { config.ConnectDB() database.Migrate(config.DB) r := gin.Default() r.POST("/users", createUser) r.GET("/users/:id", getUser) r.Run(":8080") } func createUser(c *gin.Context) { var user models.User if err := c.ShouldBindJSON(&user); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } if err := config.DB.Create(&user).Error; err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(201, user) } func getUser(c *gin.Context) { id := c.Param("id") var user models.User if err := config.DB.First(&user, id).Error; err != nil { c.JSON(404, gin.H{"error": "User not found"}) return } c.JSON(200, user) }
6. 説明:
- データベース構成: 運用グレードのパフォーマンスを実現するために接続プーリングを管理します。
- 移行ファイル: (移行フォルダー内) データベース スキーマのバージョン管理に役立ちます。
- GORM モデル: データベース テーブルを Go 構造体にマップします。
- データベース移行: (データベース フォルダー内) 時間の経過とともにテーブルを変更するためのカスタム ロジック。簡単なロールバックが可能です。
- テスト: httptest と testify を使用して、このセットアップの統合テストを作成できます。
7. 最初の移行の作成
-
実稼働環境の場合、golang-Migrate のような移行ライブラリを使用して、移行を適用、ロールバック、またはやり直すことができます。
golang-移行をインストールします:
go install -tags 'mysql' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
-
ユーザーテーブルの移行ファイルを生成
migrate create -ext=sql -dir=./migrations -seq create_users_table
コマンドを実行すると、.up.sql (スキーマを更新するため) と down.sql (後でロールバックする可能性があるため) のペアが取得されます。番号 000001 は、自動生成された移行のインデックスです。
/golang-service |-- migrations | |-- 000001_create_users_table.down.sql | |-- 000001_create_users_table.up.sql
関連する sql コマンド を .up ファイルと .down ファイルに追加します。
000001_create_users_table.up.sql
CREATE TABLE users ( id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, created_at DATETIME, updated_at DATETIME, deleted_at DATETIME);
000001_create_users_table.down.sql
DROP TABLE IF EXISTS users;
次のコマンド (ログの詳細を表示するには -verbose フラグ) を使用して、アップ移行を実行し、データベースに変更を適用します。
migrate -path ./migrations -database "mysql://user:password@tcp(localhost:3306)/dbname" -verbose up
移行で問題が発生した場合は、次のコマンドを使用して現在の移行バージョンとそのステータスを確認できます。
migrate -path ./migrations -database "mysql://user:password@tcp(localhost:3306)/dbname" version
何らかの理由で移行が失敗した場合は、ダーティ マイグレーションのバージョン番号を指定して、force (慎重に使用してください) コマンドを使用することを検討できます。バージョンが 1 の場合 (migrations または schema_migrations テーブルで確認できます)、次を実行します:
migrate -path ./migrations -database "mysql://user:password@tcp(localhost:3306)/dbname" force 1
8. スキームの変更
-
ある時点で、新しい機能を追加したい場合があり、その中にはデータ スキームの変更が必要になる場合もあります。たとえば、users テーブルに email フィールドを追加したいと考えています。次のようにします。
メール列を users テーブルに追加するための新しい移行を作成します
migrate create -ext=sql -dir=./migrations -seq add_email_to_users
これで、.up.sql と .down.sql の新しいペアができました
/golang-service |-- migrations | |-- 000001_create_users_table.down.sql | |-- 000001_create_users_table.up.sql | |-- 000002_add_email_to_users.down.sql | |-- 000002_add_email_to_users.up.sql
-
次のコンテンツを *_add_email_to_users.*.sql ファイルに追加します
000002_add_email_to_users.up.sql
/golang-service |-- main.go |-- database | |-- migration.go |-- models | |-- user.go |-- config | |-- config.go |-- migrations | |-- ... |-- go.mod
000002_add_email_to_users.down.sql
package config import ( "fmt" "log" "os" "time" "github.com/joho/godotenv" "gorm.io/driver/mysql" "gorm.io/gorm" ) var DB *gorm.DB func ConnectDB() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } // charset=utf8mb4: Sets the character set to utf8mb4, which supports all Unicode characters, including emojis. // parseTime=True: Tells the driver to automatically parse DATE and DATETIME values into Go's time.Time type. // loc=Local: Uses the local timezone of the server for time-related queries and storage. dsn := fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_NAME"), ) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("failed to connect database") } sqlDB, err := db.DB() if err != nil { panic("failed to configure database connection") } // Set connection pool settings sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) sqlDB.SetConnMaxLifetime(time.Hour) // 1.sqlDB.SetMaxIdleConns(10) // Sets the maximum number of idle (unused but open) connections in the connection pool. // A value of 10 means up to 10 connections can remain idle, ready to be reused. // 2. sqlDB.SetMaxOpenConns(100): // Sets the maximum number of open (active or idle) connections that can be created to the database. // A value of 100 limits the total number of connections, helping to prevent overloading the database. // 3. sqlDB.SetConnMaxLifetime(time.Hour): // Sets the maximum amount of time a connection can be reused before it’s closed. // A value of time.Hour means that each connection will be kept for up to 1 hour, after which it will be discarded and a new connection will be created if needed. DB = db }
up Migration コマンドを再度実行して、データ スキーマを更新します
package database import ( "golang-service/models" "golang-service/migrations" "gorm.io/gorm" ) func Migrate(db *gorm.DB) { db.AutoMigrate(&models.User{}) // Apply additional custom migrations if needed }
新しいスキーマとの同期を保つために、golang ユーザーの構造体を更新する (Email フィールドを追加する) 必要もあります。
package models import "gorm.io/gorm" type User struct { gorm.Model Name string `json:"name"` }
9. 移行のロールバック:
何らかの理由で新しく更新されたスキーマにバグが発生し、ロールバックする必要がある場合は、down コマンドを使用します。
DB_USER=root DB_PASS=yourpassword DB_HOST=127.0.0.1 DB_PORT=3306 DB_NAME=yourdb
番号 1 は、1 つの移行をロールバックすることを示します。
ここでは、データ スキーマの変更を反映するために、golang ユーザーの構造体を手動で更新する (Email フィールドを削除する) 必要もあります。
package main import ( "golang-service/config" "golang-service/database" "golang-service/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) func main() { config.ConnectDB() database.Migrate(config.DB) r := gin.Default() r.POST("/users", createUser) r.GET("/users/:id", getUser) r.Run(":8080") } func createUser(c *gin.Context) { var user models.User if err := c.ShouldBindJSON(&user); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } if err := config.DB.Create(&user).Error; err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(201, user) } func getUser(c *gin.Context) { id := c.Param("id") var user models.User if err := config.DB.First(&user, id).Error; err != nil { c.JSON(404, gin.H{"error": "User not found"}) return } c.JSON(200, user) }
10. Makefile で使用する
移行とロールバックのプロセスを簡素化するために、Makefile を追加できます。
go install -tags 'mysql' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
Makefileの内容は以下の通りです。
migrate create -ext=sql -dir=./migrations -seq create_users_table
これで、CLI で make mitigrate_up または make mitigrate_down を実行するだけで、移行とロールバックを行うことができます。
11.考慮事項:
- ロールバック中のデータ損失: 列またはテーブルを削除する移行をロールバックすると、データ損失が発生する可能性があるため、ロールバックを実行する前に必ずデータをバックアップしてください。
- CI/CD 統合: 移行プロセスを CI/CD パイプラインに統合して、デプロイメント中のスキーマ変更を自動化します。
- DB バックアップ: 移行エラーによるデータ損失を防ぐために、定期的なデータベース バックアップをスケジュールします。
DBバックアップについて
移行をロールバックしたり、データベースに影響を与える可能性のある変更を加えたりする前に、考慮すべき重要な点がいくつかあります。
- スキーマの変更: 移行にスキーマの変更 (列の追加または削除、データ型の変更など) が含まれている場合、以前の移行にロールバックすると、変更された列またはテーブルに保存されているデータが失われる可能性があります。 .
- データ削除: 移行にデータを削除するコマンド (テーブルの削除やテーブルの切り捨てなど) が含まれている場合、ロールバックすると対応する「ダウン」移行が実行され、そのデータが永久に削除される可能性があります。
- トランザクション処理: 移行ツールがトランザクションをサポートしている場合、変更はトランザクションで適用されるため、ロールバックがより安全になる可能性があります。ただし、トランザクション外で SQL コマンドを手動で実行すると、データが失われるリスクがあります。
- データの整合性: 現在のスキーマに依存する方法でデータを変更した場合、ロールバックするとデータベースが不整合な状態になる可能性があります。
データをバックアップすることが重要です。簡単なガイドは次のとおりです:
-
データベースダンプ:
データベース固有のツールを使用して、データベースの完全バックアップを作成します。 MySQL の場合、以下を使用できます:
/golang-service |-- main.go |-- database | |-- migration.go |-- models | |-- user.go |-- config | |-- config.go |-- migrations | |-- ... |-- go.mod
これにより、dbname データベースのすべてのデータとスキーマを含むファイル (backup_before_rollback.sql) が作成されます。
-
特定のテーブルをエクスポート:
特定のテーブルのみをバックアップする必要がある場合は、mysqldump コマンドで指定します。
package config import ( "fmt" "log" "os" "time" "github.com/joho/godotenv" "gorm.io/driver/mysql" "gorm.io/gorm" ) var DB *gorm.DB func ConnectDB() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } // charset=utf8mb4: Sets the character set to utf8mb4, which supports all Unicode characters, including emojis. // parseTime=True: Tells the driver to automatically parse DATE and DATETIME values into Go's time.Time type. // loc=Local: Uses the local timezone of the server for time-related queries and storage. dsn := fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_NAME"), ) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("failed to connect database") } sqlDB, err := db.DB() if err != nil { panic("failed to configure database connection") } // Set connection pool settings sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) sqlDB.SetConnMaxLifetime(time.Hour) // 1.sqlDB.SetMaxIdleConns(10) // Sets the maximum number of idle (unused but open) connections in the connection pool. // A value of 10 means up to 10 connections can remain idle, ready to be reused. // 2. sqlDB.SetMaxOpenConns(100): // Sets the maximum number of open (active or idle) connections that can be created to the database. // A value of 100 limits the total number of connections, helping to prevent overloading the database. // 3. sqlDB.SetConnMaxLifetime(time.Hour): // Sets the maximum amount of time a connection can be reused before it’s closed. // A value of time.Hour means that each connection will be kept for up to 1 hour, after which it will be discarded and a new connection will be created if needed. DB = db }
バックアップを確認します:
バックアップ ファイルが作成されていることを確認し、そのサイズを確認するか、バックアップ ファイルを開いて必要なデータが含まれていることを確認してください。バックアップを安全に保存します:
ロールバック プロセス中のデータ損失を防ぐために、バックアップのコピーをクラウド ストレージや別のサーバーなどの安全な場所に保管してください。
クラウド上のバックアップ
Golang を使用し、AWS EKS にデプロイするときに MySQL データをバックアップするには、次の手順に従います。
-
データベースのバックアップに mysqldump を使用する:
Kubernetes cron ジョブを使用して、MySQL データベースの mysqldump を作成します。
package database import ( "golang-service/models" "golang-service/migrations" "gorm.io/gorm" ) func Migrate(db *gorm.DB) { db.AutoMigrate(&models.User{}) // Apply additional custom migrations if needed }
これを永続ボリュームまたは S3 バケットに保存します。
-
Kubernetes CronJob で自動化する:
Kubernetes CronJob を使用して、mysqldump プロセスを自動化します。
YAML 設定の例:yaml
package models import "gorm.io/gorm" type User struct { gorm.Model Name string `json:"name"` }
` AWS RDS 自動バックアップの使用 (RDS を使用している場合):
MySQL データベースが AWS RDS 上にある場合は、RDS の自動バックアップとスナップショットを利用できます。
バックアップの保持期間を設定し、スナップショットを手動で取得するか、Lambda 関数を使用してスナップショットを自動化します。Velero を使用した永続ボリューム (PV) のバックアップ:
Kubernetes のバックアップ ツールである Velero を使用して、MySQL データを保持する永続ボリュームをバックアップします。
EKS クラスターに Velero をインストールし、S3 にバックアップするように構成します。
これらの方法を使用すると、MySQL データが定期的にバックアップされ、安全に保存されます。
以上がGolang サービスの DB 移行、なぜそれが重要なのか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

MySQLは、初心者がデータベーススキルを学ぶのに適しています。 1.MySQLサーバーとクライアントツールをインストールします。 2。selectなどの基本的なSQLクエリを理解します。 3。マスターデータ操作:テーブルを作成し、データを挿入、更新、削除します。 4.高度なスキルを学ぶ:サブクエリとウィンドウの関数。 5。デバッグと最適化:構文を確認し、インデックスを使用し、選択*を避け、制限を使用します。

MySQLは、テーブル構造とSQLクエリを介して構造化されたデータを効率的に管理し、外部キーを介してテーブル間関係を実装します。 1.テーブルを作成するときにデータ形式と入力を定義します。 2。外部キーを使用して、テーブル間の関係を確立します。 3。インデックス作成とクエリの最適化により、パフォーマンスを改善します。 4.データベースを定期的にバックアップおよび監視して、データのセキュリティとパフォーマンスの最適化を確保します。

MySQLは、Web開発で広く使用されているオープンソースリレーショナルデータベース管理システムです。その重要な機能には、次のものが含まれます。1。さまざまなシナリオに適したInnodbやMyisamなどの複数のストレージエンジンをサポートします。 2。ロードバランスとデータバックアップを容易にするために、マスタースレーブレプリケーション機能を提供します。 3.クエリの最適化とインデックスの使用により、クエリ効率を改善します。

SQLは、MySQLデータベースと対話して、データの追加、削除、変更、検査、データベース設計を実現するために使用されます。 1)SQLは、ステートメントの選択、挿入、更新、削除を介してデータ操作を実行します。 2)データベースの設計と管理に作成、変更、ドロップステートメントを使用します。 3)複雑なクエリとデータ分析は、ビジネス上の意思決定効率を改善するためにSQLを通じて実装されます。

MySQLの基本操作には、データベース、テーブルの作成、およびSQLを使用してデータのCRUD操作を実行することが含まれます。 1.データベースの作成:createdatabasemy_first_db; 2。テーブルの作成:createTableBooks(idintauto_incrementprimarykey、titlevarchary(100)notnull、authorvarchar(100)notnull、published_yearint); 3.データの挿入:InsertIntoBooks(タイトル、著者、公開_year)VA

WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。

MySQLデータベースを構築する手順には次のものがあります。1。データベースとテーブルの作成、2。データの挿入、および3。クエリを実行します。まず、createdAtabaseおよびcreateTableステートメントを使用してデータベースとテーブルを作成し、InsertINTOステートメントを使用してデータを挿入し、最後にSelectステートメントを使用してデータを照会します。

MySQLは、使いやすく強力であるため、初心者に適しています。 1.MYSQLはリレーショナルデータベースであり、CRUD操作にSQLを使用します。 2。インストールは簡単で、ルートユーザーのパスワードを構成する必要があります。 3.挿入、更新、削除、および選択してデータ操作を実行します。 4. Orderby、Where and Joinは複雑なクエリに使用できます。 5.デバッグでは、構文をチェックし、説明を使用してクエリを分析する必要があります。 6.最適化の提案には、インデックスの使用、適切なデータ型の選択、優れたプログラミング習慣が含まれます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。
