タイトルと内容がマッチしなくなってきましたが、続けたいと思います。
前回の投稿では SQL Azure フェデレーションの基本的な構成と操作を見てみました。
今回の投稿ではクエリの実行についてみていきたいと思います。
■DDL の実行
DDL の実行に関しては少し癖がありそうでした。
SQL Azure フェデレーションは Federation Member 毎にデータベースを保持しています。
今回は CREATE TABLE の動作を見ていきたいと思います。
フェデレーションでシャーディングされたテーブルを作成するときには CREATE TABLE で [FEDERATED ON] を設定します。
CREATE TABLE 自体は以下のようなクエリになります。
このクエリを単純に (FEDERATION ROOT に対して) 実行しようとすると以下のようなエラーとなります。
FEDERATED ON を指定した CREATE TABLE を実行する前には、[USE FEDERATION] を使用して、テーブルを作成する Federation Member を指定する必要があります。
今回は 4 つの Federation Member がありますので以下のようなクエリとなります。
USE FEDERATION を使用して、テーブルを作成する Federation Member を指定する必要があります。
そのため、テーブルの作成状況は以下のようになります。
データベースによって作成されているテーブルがまちまちになっていますね。
フェデレーションを使用する場合、どの Federation Member にどのテーブルを作成するのかを意識する必要があるようです。
今回の場合であれば、Table2 の作成をすべての Federation Member に対して USE FEDERATION で切り替えながら実行する (4回 CREATE TABLE を実行する) 必要があります。
# SPLIT の場合はもとになるデータベースを分割しますので、対象となったデータベースに含まれているオブジェクトはコピーされるようです。
また DDL に関しては USE FEDERATION の FILTERING = OFF が必要となります。
FILTERING には ON / OFF の二種類の設定があるのですが、ON を使用した場合、DDL を実行することができません。
■フィルタリング
フェデレーションされたテーブルに対してクエリを実行する場合は必ず USE FEDERATION を使用する必要があります。
どの Federation Member に対してクエリを実行するのかを明示的に指定する必要があります。
# 軽く調べてみたのですが全 Federation Member に対して単純にクエリを実行する方法を見つめることができませんでした。
以下のように Federation Member を設定しています。
この Federation Member に対してクエリを実行してみます。
まずは USE FEDERATION を使用してどの Federation Member に対してのクエリなのかを設定します。
USE FEDERATION [SQL_Azure_Federation] ([FedId] = 14) WITH FILTERING = OFF, RESET |
として実行した場合、14 が含まれる Federation Member に接続がされます。
今回の場合はこのデータベースになります。
この状態で以下のクエリを実行します。
SELECT COUNT(*) FROM Table1 |
現在は FILTERING = OFF として実行していますので接続されている Federation Member に含まれている全レコードが取得取得されています。
それでは、USE FEDERATION を以下のように FILTERING = ON に変更します。
USE FEDERATION [SQL_Azure_Federation] ([FedId] = 14) WITH FILTERING = ON, RESET |
FILTERING = ON と設定することで、USE FEDERATION で指定したデータのみとするか、それとも対象の Federation Member に含まれるデータを対象とするかのフィルタリングを切り替えることができるようになります。
■新規のデータ挿入
現在、以下の Federation Member に接続をした状態となっています。
今回使用しているテーブルは、以下のような構造となっています。
Col3 を使用してデータを分散しています。
この状態で、Col3 が 25 のデータを挿入してみたいと思います。
INSERT INTO Table1 VALUES ((SELECT MAX(Col1) FROM Table1) + 1, NEWID(), 25) |
現在選択されている Federation Member では、Col3 が 11 ~ 20 までのデータが入るように設定されています。
その Federation Member に対して Col3 が 25 (自分に格納するデータではないもの) を INSERT しようとしたためにエラーとなっています。
INSERT INTO Table1 VALUES ((SELECT MAX(Col1) FROM Table1) + 1, NEWID(), 20) |
というクエリであれば正常に処理が完了します。
自分が接続している Federation Member に対してどのような範囲のデータが格納できるかを意識して操作をする必要があるようですね。
■データの削除
データの削除ですが、接続している Federation Member を意識する必要があります。
データの操作に関しては自分が接続している Federation Member に対しての操作となります。
この状態の場合は、11~20 のデータが格納されている Federation Member に対しての操作となります。
DELETE FROM <テーブル名> とした場合、対象の Federation Member のデータを削除する操作になります。
そのため、全 Federation Member のデータを削除するためには USE FEDERATION で接続を切り替えながら削除をしていく必要がありそうです。
また、DELETE 文でもフィルタは有効ですので、ON / OFF を使い分けることで Federation Member 内の全データを削除するか、フィルタにより選択されたデータのみを切り替えることができます。
フェデレーションされたテーブルに対しても Truncate Table を使用することは可能ですが、FILTERING = OFF の必要があるようです。
FILTERING = ON の状態で接続して、Truncate Table を実行すると DDL 操作ということでエラーとなります。
■データの更新
今回は Col3 という列を使用してデータの分散を行っています。
この Col3 を更新できるか試してみました。
今回も以下の Federation Member に接続をしています。
USE FEDERATION は以下のクエリを使用しています。
USE FEDERATION [SQL_Azure_Federation] ([FedId] = 11) WITH FILTERING = OFF, RESET |
この状態で以下の UPDATE 文を実行します。
UPDATE Table1 SET Col3 = 12 |
それでは接続している Federation Member の範囲外の値に更新をしてみたいと思います。
UPDATE Table1 SET Col3 = 24 |
フェデレーションされたテーブルを更新する場合、分散に使用している列に対しての更新は制限されている形になるようです。
■表の結合
これが一番難しそうです。
フェデレーションされたデータベースは以下のような構造となります。
フェデレーションルートとして、データベースを持ち、その配下にフェデレーションされたテーブルに使用されるデータベースを持つという構成になります。
そのため、フェデレーションルートに存在しているテーブルを参照するということができないようです。
# 逆もできません。
Fedeartion Member のテーブルでマスター系の表と結合が必要な場合は、参照テーブルとして各 Federation Member 内にテーブルを保持する必要があるようです。
# Parallel Data Ware House と似たようなデータの持ち方にする必要がありそうです。
参照テーブルは以下のような形で作ることが可能です。
USE FEDERATION [SQL_Azure_Federation] ([FedId] = 11) WITH FILTERING = OFF, RESET GO CREATE TABLE RefTable (Col1 int,CONSTRAINT [PK_RefTable] PRIMARY KEY (Col1)) |
対象の Federation Member に接続をして通常の CREATE TABLE 文を実行しているだけです。
そうすると Federation Member 内にデータを分散させない通常のテーブルが作成されますので、このテーブルと結合をすることでデータの参照を可能とするようです。
SPLIT する前にあるデータを整えておけば、SPLIT により作成された Federation Member も同一のテーブルを保持することが可能ですので、参照に使用するテーブルの初期データは SPLIT 前に準備しておくと良さそうです。
ただし、マスター変更の必要が入った場合は各 Federation Member 毎にメンテナンスをする必要がありそうなので注意が必要ですね。
SQL Azure フェデレーションは最初パーティショニングのようなものかと思っていたのですが、大分管理方法が違うようですね。
テーブルの設計や運用の設計に関してもフェデレーションを意識する必要がかなりありそうです。
# マスターを各 Federation Member で保持する必要があるので。
使いこなせるとかなり面白そうですね。