「マルチスキーマ」戦略を使用するマルチテナント SaaS アプリケーションがあります。つまり、すべての顧客が同じデータベース インスタンスに専用のスキーマを持っています。MS SQL Server をデータベースとして使用し、SQL Server の「ユーザー」の「デフォルト スキーマ」設定を介してスキーマを切り替えます。たとえば、顧客 A、B、C は SQL Server で次のように構成されています。
- 顧客 A:
user_A
デフォルトのスキーマを使用schema_A
- 顧客 B:
user_B
デフォルトのスキーマを使用schema_B
- 顧客 C:
user_C
デフォルトのスキーマでschema_C
... など。
このアプリケーションでは、すべてのクエリの前に次の SQL を実行して、接続に SQL Server "ユーザー" を設定することにより、DataSource 接続を各顧客の正しいスキーマを指すように切り替えます。
EXECUTE AS USER = 'user_A';
これは、グローバルな方法でスキーマ バージョンの状態を管理するために Flyway を使用しようとするときに、いくつかの問題を引き起こします。flyway のスキーマ サポートはスキーマ名のリストのみを受け取るため、これは MS SQL Server では機能しません。Flyway は、DataSource 構成で提供されたユーザーのデフォルト スキーマで移行を実行します。SQL Server の場合、「ユーザー」は顧客/スキーマごとに異なる必要があります。
理想的には、FlywayCallback.beforeEachSchemaMigrate(Connection)
スキーマごとの各移行の前に「Execute as User」ステートメントを実行することで、スキーマごとに目的のユーザー コンテキストを設定できるようなコールバックが必要です。なぜそのフックがないのかわからない?
schema_version
フライウェイのもう1つの欠点は、テーブルを保持するスキーマとして、スキーマのリストの最初のスキーマを使用するという規則です。これは、SQL Server ベースのマルチテナント環境では望ましくありません。schema_version
テーブルを含むスキーマが実際の Customer スキーマでもあるとは想定できないためです。私たちのような SaaS アプリケーションでは、テナント/顧客ごとのスキーマがその場で作成/破棄されることに注意してください。ユーザーがサインアップすると、プロビジョニング プロセスの一部で、いくつかの規則に基づいて新しいスキーマが作成されます。したがって、スキーマのリストは動的です。
schema_version
理想的には、そのスキーマで移行を実行しようとせずに、特定のスキーマを使用してテーブルを作成するように Flyway に指示できます。通常、これはdbo
スキーマ (SQL Server の既定のスキーマ) です。dbo スキーマを使用して、すべてのテナントにわたって本質的にグローバルなテーブルを保持します。schema_version はグローバル テーブルと見なされます。
したがって、移行が成功すると、データベースは次のようになります。
- dbo.schema_version
- schema_A.my_tables
- schema_B.my_tables
- schema_C.my_tables
上記のスキーマはすべて同じ「状態」にあり、dbo.schema_version
テーブルによって指示および制御されます。
これは現在可能ですか?