DUICUO

SchemaHero - クラウドネイティブの宣言型データベース構造移行ツール

SchemaHeroは、オープンソースでクラウドネイティブな宣言型データベーススキーマ移行ツールです。スキーマ定義を、あらゆる環境に適用可能な移行スクリプトに変換します。CLIツールとKubernetes Operatorとして開発されたSchemaHeroは、アプリケーションが実行されるあらゆる環境と互換性のあるシーケンシャルな移行スクリプトの作成と管理の手間を省きます。

多くのデータベーススキーマ管理ツールは命令型のインターフェースを作成しますが、開発者はスキーマの現在の状態と、現在のスキーマ(および関連データ)を新しいスキーマに移行するためのコマンドを理解する必要があります。SchemaHeroは、侵入を必要とする命令型のインターフェースに代わる宣言型のインターフェースを提案します。

宣言型モデル

データベース スキーマを宣言的に管理することには、次のような多くの利点があります。

  1. 変更管理手順に準拠する能力。
  2. 新しい環境に繰り返し展開できます。
  3. 新しいランタイムと互換性があります。

宣言型モデルでは、スキーマの現在の状態のみが定義されます。宣言型スキーママネージャは、スキーマを以前の状態から目的の状態に移行するために必要なコマンドを実行します。現在の状態のみを保存する利点は、新しい環境またはインスタンスを作成する際に、以前に使用したデータベース拡張機能、テーブル、その他のデータが不要になることです。

従来のデータベースエンジンは、DDL(データ定義言語)と呼ばれるSQL文のサブセットを通じてスキーマ変更を受け取ります。開発者は、対象とするデータベースエンジンごとのDDLの違いを理解する必要はありません。統一された宣言型モデルから適切なDDLコマンドへの変換は、データベースの機能と状態に応じてプログラム的に処理できます。

宣言型パターンを使用してデータベーススキーマ管理を定義すると、適用前に一連のポリシーに基づいてスキーマを検証できます。これは、移行スクリプトのみを保存する命令型ツールでは実現が困難です。必要な状態がすべて整っているため、データベーススキーマを一連のルールに照らして評価し、ポリシーとベストプラクティスが遵守されていることを確認できます。

データ移行

管理と展開を必要とする移行には 2 つの種類があります。

  1. スキーマの移行。
  2. データ移行。

スキーママイグレーションはSQL構文を用いて表現でき、データベースの構造を変更します。これには、多くの場合、新しいテーブルの作成、列の変更、インデックスデータの変更などが含まれます。これらは一般的な構文であり、常にべき等構文を用いて表現できます。データベースエンジンによって、これらのルールの適用方法が異なります。例えば、MySQLではトランザクション内でのスキーママイグレーションは許可されませんが、Postgresでは許可されます。スキーマ管理は多くの場合、データベース固有のアプローチであり、 ​SchemaHero​スキーママイグレーションの処理に重点を置いています。

あまり一般的ではありませんが、開発者はデータベース内のデータを新しい形式に移行する必要があります。これには、新しい列を計算して書き込む、またはコード内で新しい値を作成して挿入するといった作業が含まれる場合があります。多くの従来のデータベース管理ツールは、スキーマ移行とデータ移行のタスクを1つのツールに統合しています。

SchemaHero は現在、スキーマの移行に重点を置いており、将来的にはデータ移行をサポートする予定です。

使用

次に、SchemaHeroとサンプルデータベースをデプロイします。仮想航空会社予約システム用の非常に基本的なデータベースを設計し、PostgreSQLにデプロイします。

まず、空のデータベースをデプロイし、初期スキーマを作成し、そのスキーマを変更して最終的に次のテーブル構造を作成します。

SchemaHeroをインストールする

kubectlプラグインをインストールする

SchemaHeroクライアントコンポーネントはkubectlプラグインとしてパッケージ化されており、krewパッケージマネージャーを通じて配布されているため、まずkrewをインストールする必要があります。krewをインストールしたら、以下のコマンドでSchemaHeroクライアントをインストールできます。

 $ kubectl krew インストールスキーマヒーロー

インストール後、次のコマンドを使用してインストールが成功したかどうかを確認できます。

 $ kubectl schemahero バージョン

通常、インストールされている SchemaHero のバージョン (0.12.1 または類似) が表示されます。

クラスタコンポーネントをインストールする

kubectl プラグインがインストールされると、次のコマンドを使用してワンクリック インストールで SchemaHero コンポーネントを Kubernetes クラスターにインストールできます。

 $ kubectl schemahero インストール

このコマンドは、schemahero-system という名前空間を作成し、SchemaHero オペレーターをデプロイします。以下のコマンドを実行することで、SchemaHero がインストールされているかどうかを確認できます。

 $ kubectl get pods - n schemahero - システム

通常、1 つのポッドが実行されており、出力は次のようになります。

 名前準備完了ステータス再起動年齢
schemahero - 0 1 / 1 実行中0 38

クライアントとクラスター コンポーネントがインストールされたら、データベースに接続できます。

データベースに接続する

次に、PostgreSQL インスタンスをデプロイし、そのデータベース インスタンスを管理するように SchemaHero を構成する必要があります。

便宜上、PostgreSQL Helm Chart テンプレートからレンダリングされた YAML ファイルを SchemaHero コード リポジトリに直接追加し、schemahero-tutorial という名前空間にデプロイします。

 $ kubectl create ns schemahero - チュートリアル
$ kubectl apply -n schemahero - tutorial -f https://raw.githubusercontent.com/schemahero/schemahero/main/examples/tutorial/postgresql/postgresql-11.8.0.yaml

PostgreSQL をデプロイしたら、次のコマンドを使用してデータベース インスタンスに接続できます。

 $ kubectl exec -it -n schemahero-tutorial \
postgresql-0 -- psql -U 航空会社データベースユーザー -d 航空会社データベース

airlinedb-user のパスワードは password です。

ここでは、前に紹介したデータベース管理ツールである Beekeeper Studio を使用して、このデータベース インスタンスを管理します。

デフォルトでは、上記でデプロイした PostgreSQL インスタンスはクラスター外部からアクセスできないため、kubectl を使用してポート転送を作成し、データベース インスタンスを公開することができます。

 $ kubectl port - forward -n schemahero - tutorial svc / postgresql 5432 : 5432

次に、ユーザー airlinedb-user、データベース airlinedb、パスワード password を使用して、データベース 127.0.0.01:5432 に接続できます。

接続後、データベースがまだ空であることがわかります。

クラスター内でSchemaHeroとPostgreSQLインスタンスが稼働している状態になったので、SchemaHeroにデータベース情報を提供し、データベースを管理できるようにします。これは、接続情報を使用してカスタムリソースをクラスターにデプロイすることで実現できます。

`database` オブジェクトは、SchemaHero がデータベーススキーマを管理できるようにします。`database` 定義には、名前、型、接続パラメータが含まれます。ここでは、以下の内容を含む `airline-db.yaml` というファイルを作成します。

 api バージョン: databases.schemahero.io/v1alpha4  
種類: データベース
メタデータ
名前: 航空会社データベース
名前空間: schemahero - チュートリアル
仕様:
繋がり
ポストグルス:
ウリ:
値の開始値:
シークレットキー参照:
名前: postgresql
キー: uri

上記で定義したデータベースは、Schemaheroによって定義されたCRDオブジェクトです。ここでは、secretKeyRefを介して以前のPostgreSQLデプロイメントの認証データを参照しています。SchemaHeroは、インライン、シークレット、またはHashiCorp Vaultからの認証情報の読み取りをサポートしています。

上記のリソース オブジェクトを直接適用できます。

 $ kubectl apply -f 航空会社- db .yaml
$ kubectl get databases - n schemahero - チュートリアル
名前年齢
航空会社db 47

これで、SchemaHeroを使ってPostgreSQLインスタンスを管理できるようになりました。次に、SchemaHeroを使ってこのインスタンスに新しいテーブルをデプロイします。

新しいテーブルを作成する

このステップでは、先ほど作成したairlinesdbデータベースにいくつかのテーブルをデプロイします。この操作を実行する際に、SchemaHeroで承認と拒否のワークフローを実行し、これらの変更を実装前に検証する方法を理解します。

まず、シンプルな「airports」テーブルを定義します。このテーブルは、ルートを定義する際にデータモデルで使用します。このテーブルには、空港コードと空港名の2つの列しかありません。

SchemaHero を使用する前に、次に示すような SQL ステートメントを記述する場合があります。

 テーブル空港の作成
( コードchar ( 4 ) キーが null でない,
名前varchar255

SchemaHero が作成されたので、SQL ステートメントを記述する必要はなくなり、SchemaHero Table カスタム オブジェクトを作成するだけで済みます。

以下に示すように、airport-table.yaml という名前のリソース マニフェスト ファイルを作成します。

 api バージョン: schemas.schemahero.io / v1alpha4
種類: テーブル
メタデータ
名前空港
名前空間: schemahero - チュートリアル
仕様:
データベース: 航空会社データベース
名前空港
スキーマ:
ポストグルス:
プライマリキー: [ コード]
:
- 名前: コード
: char ( 4 )
- 名前: 名前
: varchar ( 255 )
制約:
notNull : true

`spec.database` は、以前に定義した `database` オブジェクトに関連付けるために使用され、`spec.name` は Postgres データベース内の実際のテーブル名であり、テーブル構造は `spec.schema` で定義されます。`primaryKey` を使用して主キーを指定でき、`columns` はテーブルの列定義を定義します。

リソース オブジェクトを直接適用するだけです。

 $ kubectl apply -f 空港- テーブル.yaml 

テーブルオブジェクトをデプロイしても、テーブル構造は自動的に変更されないことに注意してください。新しい(または編集された)テーブルオブジェクトは移行オブジェクトを生成し、これを検査して承認または拒否することができます。SchemaHeroでは、データベース構造の移行によって混乱が生じる可能性があるため、デフォルトでは承認プロセスが必要です。データベースオブジェクトに属性を追加することで、承認なしで即時デプロイを有効にすることができます。

次のコマンドを使用して、保留中の状態にある移行オブジェクトを表示できます。

 $ kubectl schemahero get migrations - n schemahero - チュートリアル
ID データベーステーブル 計画済み 実行済み承認済み 拒否済み
eaa36ef 航空会社db 空港11

リソースが見つからない場合は、数秒待ってからもう一度お試しください。移行が利用可能になる前に、SchemaHeroオペレーターが計画フェーズを完了する必要があります。

移行を承認する前に、生成され移行オブジェクトに追加されたSQL文を確認できます。前のコマンドの出力からIDを取得し、`describe migration` を実行します。

 $ kubectl schemahero 移行eaa36ef - n schemahero - チュートリアルの説明
移行: eaa36ef
生成されたDDL ステートメント 2020-06-06 T10 : 41 : 04-07 : 00 生成 :
テーブル「airport」「コード」 文字4 )、 「名前」 文字可変255NULLキー「コード」 )) を作成します
この移行を適用するには:
kubectl schemahero - n schemahero - チュートリアル移行の承認eaa36ef
現在スキーマに対してこの移行を再計算するには:
kubectl schemahero - n schemahero - チュートリアル移行の再計算eaa36ef
この移行を拒否しキャンセルするには:
kubectl schemahero - n schemahero - チュートリアル移行を拒否eaa36ef

出力の上部にある、生成された DDL ステートメントは計画された移行であり、SchemaHero がこの移行を適用するために実行する正確な SQL ステートメントです。

SchemaHero は、後続のステップに次の 3 つのコマンドを提供します。

  • apply: このコマンドを実行すると、SQL ステートメントが受け入れられ、SchemaHero がそれをデータベース上で実行します。
  • `recalculate`: このコマンドを実行すると、SchemaHeroは生成されたSQL文を破棄し、再生成します。これは、データベース構造が変更され、SchemaHeroにプランを再実行させたい場合に便利です。
  • 拒否: このコマンドを実行すると、移行は拒否され、実行されません。

例えば、現在のマイグレーションが安全で期待どおりであることがわかります。次に、SchemaHero がプランを実行できるように、マイグレーションを承認します。次のコマンドを実行するだけです。

 $ kubectl schemahero - n schemahero - チュートリアル移行の承認eaa36ef
移行EAA36EF 承認

移行ステータスを確認するには、再度 `get migrations` を実行します。

 $ kubectl schemahero get migrations - n schemahero - チュートリアル
ID データベーステーブル 計画済み 実行済み承認済み 拒否済み
eaa36ef 航空会社db 空港9 38秒 38 52

上記の情報は、移行計画が 9 分 38 秒前、52 秒前に承認され、38 秒前に実行されたことを示しています。

次に、Beekeeper Studioツールで、左側のナビゲーションにある「テーブルとビュー」の見出しにある更新ボタンをクリックします。通常、publicの下にあるairportテーブルが表示されます。テーブルをクリックすると、列データが表示されます。

テーブルを変更する

次に、テーブル オブジェクトをデプロイし、テーブル構造を変更します。

前と同様に、まず次の構造のスケジュール テーブルを作成します。

次の内容を持つ対応する Table オブジェクトを定義します。

 # スケジュール- テーブル.yaml
api バージョン: schemas.schemahero.io / v1alpha4
種類: テーブル
メタデータ
名前: スケジュール
名前空間: schemahero - チュートリアル
仕様:
データベース: 航空会社データベース
名前: スケジュール
スキーマ:
ポストグルス:
主キー: [ フライト番号]
:
- 名前: フライト番号
: int
- 名前由来
: char ( 4 )
制約:
notNull : true
- 名前: 目的地
: char ( 4 )
制約:
notNull : true
- 名前: 出発時刻
タイプ: 時間
制約:
notNull : true
- 名前: 到着時間
タイプ: 時間
制約:
notNull : true

上記のリソース リストを適用するだけです。

 $ kubectl apply -f スケジュール- テーブル. yaml -n schemahero - チュートリアル
$ kubectl schemahero get migrations - n schemahero - チュートリアル

スケジュールの移行が準備されると、出力に表示されます。

 ID データベーステーブル 計画済み 実行済み承認済み 拒否済み
a9626a8 航空会社DB スケジュール21
eaa36ef 航空会社db 空港4 時間3 時間3 時間

`describe` コマンドを使用して、対応する SQL 文を確認することもできます。安全であれば、変更を承認できます。

 $ kubectl schemahero - n schemahero - チュートリアル移行を承認a9626a8

承認されると、Beekeeper Studio にスケジュール テーブルが存在するかどうかを確認できます。

ここで、このテーブル構造にいくつか変更を加えてみましょう。

  • depart_time 列と arrive_time 列を NULL 可能にします。
  • durationという名前の新しい列を追加します

上記の `schedule-table.yaml` ファイルを修正し、`departure_time` 列と `arrival_time` 列から `constraints` 属性を削除します。次に、`constraints` 属性を持たない `duration` という `int` 型の新しい列を追加します。修正後のファイルは以下のとおりです。

 api バージョン: schemas.schemahero.io / v1alpha4
種類: テーブル
メタデータ
名前: スケジュール
名前空間: schemahero - チュートリアル
仕様:
データベース: 航空会社データベース
名前: スケジュール
スキーマ:
ポストグルス:
主キー: [ フライト番号]
:
- 名前: フライト番号
: int
- 名前由来
: char ( 4 )
制約:
notNull : true
- 名前: 目的地
: char ( 4 )
制約:
notNull : true
- 名前: 出発時刻
タイプ: 時間
- 名前: 到着時間
タイプ: 時間
- 名前: 期間
: int

変更後にファイルを再適用します。

 $ kubectl apply -f スケジュール- テーブル.yaml 

変更を適用した後、移行オブジェクトを再度確認します。

 $ kubectl schemahero get migrations - n schemahero - チュートリアル
ID データベーステーブル 計画済み 実行済み承認済み 拒否済み
a9626a8 航空会社データベース スケジュール9 分30秒7 分58秒8 分0秒
eaa36ef 航空会社db 空港4 時間4 時間4 時間
fa32022 航空会社DBスケジュール5

新しい移行オブジェクトが保留状態になっていることがわかります。この移行の詳細情報を表示するには、`describe` コマンドを使用してください。

 $ kubectl schemahero - n schemahero - チュートリアル移行の説明fa32022
移行: fa32022
生成されたDDL ステートメント 2020-06-06 T14 : 56 : 04-07 : 00 生成 :
テーブル"schedule" を変更し、 "departure_time" 時間型を指定し"departure_time" を変更してnull でない値を削除します
テーブル"schedule" を変更し、 "arrival_time"time に変更し"arrival_time"null 以外に変更します
テーブル「schedule」 を変更し「duration」 整数を追加します
この移行を適用するには:
kubectl schemahero - n schemahero - チュートリアル移行承認fa32022
現在スキーマに対してこの移行を再計算するには:
kubectl schemahero - n schemahero - チュートリアル移行の再計算fa32022
この移行を拒否しキャンセルするには:
kubectl schemahero - n schemahero - チュートリアル移行を拒否fa32022

上記の情報から、この移行中に生成されたDDLステートメントには3つの異なるステートメントが含まれていることがわかります。SchemaHero ​SchemaHero​ 、デプロイしたYAMLと実際のデータベース構造を比較し、上記のコマンドを生成しました。

移行ステートメントが正しいことを確認した後、移行を直接承認できます。

 $ kubectl schemahero - n schemahero - チュートリアル移行承認fa32022
移行fa32022 が承認されました

正常に承認され、テーブル構造が正常に変更されました。

これでSchemaHeroの基本的な理解は完了です。もちろん、まだ説明していないSchemaHeroの機能もいくつかあります。詳しくは公式ドキュメント(https://schemahero.io/docs/)をご覧ください。

Git リポジトリ: https://github.com/schemahero/schemahero。