SQL Azure Federationsを使用して、実際のプロジェクトのデータベースをスケーリングします。 パート2:入力

前回は、SQL Azureフェデレーションの理論的な部分を見ました。 SQL Azureフェデレーションに移行する際の考慮事項と考慮事項。 本質は技術そのものにもないことに注意してください。 タスクがデータベースをスケーリングすることである場合、フェデレーション、MySQL Cluster、または別の方法を使用することは重要ではありません。最初に考慮する必要があるのはデータベースアーキテクチャです。 そもそもスケーリングが必要なデータベースは、これをアーキテクチャー指向にする必要があります。



それでは、プロジェクトに戻りましょう。 データベースのサブジェクト領域は、個人財務会計です。 データベースダイアグラムを図に示します。







ご覧のとおり、データベースは非常に単純です。 各システムオブジェクトは、基本的なプロパティ(Id、Name、Description)を持つエンティティです。 特定のエンティティは、アカウント(それから継承:銀行口座、クレジットカード)、支出カテゴリ(それから継承:予算、および子カテゴリ)およびアカウントトランザクションです。



データベースには、テーブルに加えて、エンティティをデータベースに追加するためのロジック(ストアドプロシージャの形式でフレーム化)、およびデータベースへの一般的なクエリの結果を表示するためのいくつかのビューが含まれています。



データベースを作成するSQLスクリプトのソースコードは、 ここにあります







実際のプロジェクトでは、データベース内のアーティファクトの数は桁違いに大きくなる可能性がありますが、そのような小さなデータベースの移行でも、SQL Azureフェデレーションを使用するときに遭遇する可能性のある主なレーキを示すことがあります。



分析


急いでデータベースを移行してSQL Azureフェデレーションを使用する前に、データベース内のどのデータが論理的に独立しているかを判断する必要があります。 さまざまなデータベースに分散できるデータの種類。 実際、データが複数のデータベースに分割されるテーブル、いわゆる連合テーブルを選択する必要があります。







データベースの構造を見ると、最初に思い浮かぶのは、エンティティの基本テーブル(エンティティ)です。 このテーブルを作成するためのスクリプトは次のとおりです。

CREATE TABLE Entity (





[Id] INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1),





[Name] NVARCHAR(MAX) NOT NULL,





[Description] NVARCHAR(MAX) NOT NULL,





)







一見、このテーブルは分割に最適です。 しかし、これはそうではありません。 はい、外部キーは含まれません。かなり単純な構造で、最大数のレコードが保存されます。 ただし、データベースのロジックに従って、「後続テーブル」のデータはこのテーブルに関連付けられています。 つまり、システムで作成されたすべてのエンティティのエンティティテーブルにエントリがあります。



この例を考えてみましょう。 データをエンティティの識別子の範囲(IDフィールド)に分割するとします。 ID 1〜50のレコードが最初のシャードに保存され、51〜100が2番目のシャードに保存されているとします。







ユーザーは、Operationsテーブルに新しいレコードを追加しようとしています。 牛乳のパッケージの購入に関するデータとします。 アカウントエンティティIDが1、費用カテゴリIDが6であると仮定します。また、最初のデータベースにすでに50レコードがあると仮定します。



テーブルに新しいデータを追加するリクエストは次のようになります。

USE FEDERATION Entities(EntityId = 51) WITH RESET, FILTERING = OFF





GO





INSERT INTO Operation VALUES (





51, -- EntityId





1, -- AccountId





6, -- CategoryId





GETDATE(), -- Date





10, -- Amount





'USD' -- Currency





)







要求は完全に正しく実行されます。 このアカウント(ID = 1)のすべての操作のリストを取得してみましょう。 データベースには、これに対応するビューがあります。 そのコードは次のとおりです。

SELECT





Account_Entity.Description AS 'Account',





Operation_Entity.Name AS 'Operation',





Operation_Entity.Description,





Operation.Amount,





Operation.Currency,





Operation.Date





FROM





Operation





INNER JOIN Entity AS Operation_Entity ON Operation.EntityId = Operation_Entity.Id





INNER JOIN Account ON Operation.AccountId = Account.Id





INNER JOIN Entity AS Account_Entity ON Account.EntityId = Account_Entity.Id





INNER JOIN Category ON Operation.CategoryId = Category.Id





INNER JOIN Entity AS Category_Entity ON Category.EntityId = Category_Entity.Id





WHERE





Account.Id = 1







思い出すと、1つのアカウントのデータは異なるシャードに保存されます。 したがって、このクエリが正しい結果を返すには、各シャードで個別に実行する必要があります。

USE FEDERATION Entities(EntityId = 1) WITH RESET, FILTERING = OFF





GO





...





USE FEDERATION Entities(EntityId = 51) WITH RESET, FILTERING = OFF





GO





...







このアプローチからアプリケーションのパフォーマンスに大きな打撃が与えられることを説明する必要はないと思います。 最も単純なクエリでさえ2回実行する必要がある場合! 明らかに、Entityテーブルは私たちには適していません。



データベース設計に対するマルチテナントアプローチを思い起こせば、各ユーザーが自分のデータベースを操作し、データが重複しない場合、疑問が生じます。 SQL Azureフェデレーションのフレームワーク内で同様の何かを実装することは可能ですか? 各シャードには1人のユーザー(アカウント)のデータが含まれます。 実際、このアプローチは非常に論理的です。 ビジネスロジックの観点からは、次のようになります。



1人の家族が1つのプログラムを使用するとします。 それぞれが個別に予算を維持します。 また、夫が彼の経理を行い、妻が彼のようになっているとします。 したがって、夫のデータ(AccountId = 1)は妻のデータ(AccountId = 2)と重複しません。 この場合、勘定科目表によって断片に分割することは非常に論理的に見えます。







新しいアカウントの追加は、シャードの追加に対応します。 次のような頻繁な操作:カテゴリ、操作などのリストを操作しても、生産性は低下しません。

USE FEDERATION Accounts(AccountId = 1) WITH RESET, FILTERING = OFF





GO







そのようなリクエストを実行すると、現在作業しているユーザーのデータがすぐにわかります。 したがって、同じ操作は1回だけ実行されます。



そこで、既存のデータベースを分割するための2つのオプションを検討しました。 ここで、データを異なるデータベースに論理的に分割するフィールドを決定しました。 次回は、データを異なるシャードに直接拡散します。 切り替えないでください! 新しい週の仕事を始めましょう。 ご清聴ありがとうございました!



All Articles