分散パーティション ビューの作成

パーティション ビューを実装するには、まずテーブルを行方向にパーティション分割する必要があります。パーティション構成のデザイン時には、各メンバ テーブルにどのデータが所属するかを明確にします。元のテーブルは、複数の小規模なメンバ テーブルに置換されます。各メンバ テーブルには元のテーブルと同数の列があり、各列の属性は、データ型、サイズ、照合順序など、元のテーブル内の対応する列の属性と同じです。分散パーティション ビューを作成すると、各メンバ テーブルの場所は別々のメンバ サーバーに分散します。場所の透過性を最大にするには、各メンバ サーバー上のメンバ データベースの名前を同じにします。ただし、これは必要条件ではありません。たとえば、Server1.CustomerDBServer2.CustomerDBServer3.CustomerDB のようにします。

メンバ テーブルの作成

メンバ テーブルをデザインする際には、各メンバ テーブルにキー値の範囲に基づいて元のテーブルの行方向のスライスを格納するようにデザインします。範囲は、パーティション分割列のデータ値に基づきます。各メンバ テーブルの値の範囲は、パーティション分割列の CHECK 制約によって設定され、範囲を重ねることはできません。たとえば、あるテーブルの値の範囲を 1 ~ 200000 とし、別のテーブルの値の範囲を 150000 ~ 300000 とすることはできません。この場合 150000 ~ 200000 の値がどちらのテーブルに含まれるかが不明確になるためです。

たとえば、Customer テーブルを 3 つのテーブルにパーティション分割するとします。これらの 3 つのテーブルの CHECK 制約は次のように指定します。

-- On Server1:
CREATE TABLE Customers_33
  (CustomerID   INTEGER PRIMARY KEY
                CHECK (CustomerID BETWEEN 1 AND 32999),
  ... -- Additional column definitions)

-- On Server2:
CREATE TABLE Customers_66
  (CustomerID   INTEGER PRIMARY KEY
                CHECK (CustomerID BETWEEN 33000 AND 65999),
  ... -- Additional column definitions)

-- On Server3:
CREATE TABLE Customers_99
  (CustomerID   INTEGER PRIMARY KEY
                CHECK (CustomerID BETWEEN 66000 AND 99999),
  ... -- Additional column definitions)

分散パーティション ビューの定義

メンバ テーブルの作成後、各メンバ サーバー上に分散パーティション ビューを同じ名前で定義します。これにより、分散パーティション ビュー名を参照するクエリを 1 つ以上のメンバ サーバーで実行できるようになります。各サーバーにあるのは、1 つのメンバ テーブルと分散パーティション ビューのみですが、元のテーブルのコピーが各メンバ サーバー上にあるかのように操作できます。アプリケーションに対してはデータの場所が透過的になっています。

分散パーティション ビューは、次の作業を行うことにより作成します。

  • 各メンバ サーバーに、リンク サーバー定義を追加します。メンバ サーバーには、分散クエリを他のメンバ サーバー上で実行するのに必要な接続情報が保持されます。これにより、分散パーティション ビューを使用して、他のサーバー上のデータにアクセスできるようになります。

  • 分散パーティション ビューで使用する各リンク サーバー定義に対して、sp_serveroption を使用して lazy schema validation オプションを設定します。この設定では、リモート メンバ テーブルが実際にデータを必要とするまで、クエリ プロセッサからリンク テーブルに対するメタデータの要求が発生しないので、パフォーマンスを最適化することができます。

  • 分散パーティション ビューを各メンバ サーバーに作成します。このビューでは、分散型 SELECT ステートメントを使用して、各リンク メンバ サーバーのデータにアクセスし、リンク メンバ サーバーに分散している行とローカル メンバ テーブルの行をマージします。

上の例で説明した分散パーティション ビューを作成するには、次の手順を実行する必要があります。

  • Server2 の接続情報を持つ Server2 という名前のリンク サーバー定義を追加し、Server3 へのアクセス用に Server3 という名前のリンク サーバー定義を追加します。

  • 次の分散パーティション ビューを作成します。

    CREATE VIEW Customers AS
       SELECT * FROM CompanyDatabase.TableOwner.Customers_33
    UNION ALL
       SELECT * FROM Server2.CompanyDatabase.TableOwner.Customers_66
    UNION ALL
       SELECT * FROM Server3.CompanyDatabase.TableOwner.Customers_99
    
  • Server2 と Server3 で同じ手順を実行します。

テーブルに関するルール

メンバ テーブルは、ビュー定義内の各 SELECT ステートメントの FROM 句で定義します。それぞれのメンバ テーブルを定義する際には、以下のルールに従う必要があります。

  • メンバ テーブルをビュー内で複数回参照することはできません。

  • メンバ テーブルでは計算列にインデックスを作成できません。

  • 各メンバ テーブルでは、必ず PRIMARY KEY 制約が同数の列に対して設定されている必要があります。

  • 各メンバ テーブルでは、ANSI 埋め込み設定が同一でなければなりません。ANSI 埋め込み設定の詳細については、「SET ANSI_PADDING」を参照してください。

列に関するルール

列は、ビュー定義内の各 SELECT ステートメントの選択リストで定義します。それぞれの列を定義する際には、以下のルールに従う必要があります。

  • 各メンバ テーブル内のすべての列が、選択リスト内に含まれている必要があります。SELECT * FROM <member table> は使用可能な構文です。

  • 選択リスト内で列を複数回参照することはできません。

  • 列は選択リスト内で同じ順番に並べられている必要があります。

  • 各 SELECT ステートメントの選択リスト内の列の形式を同じにする必要があります。形式には、データ型、有効桁数、小数点以下桁数、および照合順序が含まれます。たとえば、次のビュー定義は、両方の SELECT ステートメントの最初の列が同じデータ型ではないのでエラーになります。

    CREATE VIEW NonUpdatable
    AS
    SELECT IntPrimaryKey, IntPartNmbr
    FROM FirstTable
      UNION ALL
    SELECT NumericPrimaryKey, IntPartNmbr
    FROM SecondTable
    

パーティション分割列に関するルール

パーティション分割に使用できる列は 1 つだけであり、その列は各メンバ テーブルに存在していなければなりません。各メンバ テーブルで使用できるデータは CHECK 制約で特定されます。さらに、次のルールにも従う必要があります。

  • 各テーブルの CHECK 制約のキー範囲は、他のテーブルの範囲と重ねることはできません。パーティション分割列の特定の値は、1 つのテーブルにだけマップされる必要があります。CHECK 制約で使用できる演算子は、BETWEEN、IN、AND、OR、<、<=、>、>=、および = だけです。

  • パーティション分割列は、ID 列、既定の列、および timestamp 列にはできません。

  • パーティション分割列は、ビューの各 SELECT ステートメントの選択リスト内で、同じ位置になければなりません。たとえば、1 番目の列をパーティション分割列とする場合は、どの選択リストでも 1 番目の列をパーティション分割列にします。もし 2 番目の列がパーティション分割列であれば、各選択リストの 2 番目の列をパーティション分割列にします。

  • パーティション分割列には NULL を使用できません。

  • パーティション分割列は、テーブルの主キーの一部である必要があります。

  • パーティション分割列を計算列にすることはできません。

  • パーティション分割列に設定する制約は、1 つだけにする必要があります。複数の制約が設定されていると、SQL Server によってすべての制約が無視され、そのビューがパーティション ビューかどうかの判断にこれらの制約が考慮されません。

  • パーティション分割列の更新に関する制限はありません。

これらのルールをすべて満たすパーティション分割列では、クエリ オプティマイザが提供する最適化がすべてサポートされます。詳細については、「分散パーティション ビューの解決」を参照してください。

一般ルール

注意

同一サーバー上にローカルのパーティション ビューを作成した場合、次に示す条件は適用されません。これは、旧バージョンとの互換性のために用意されている機能です。

考慮する必要がある追加ルールを以下に示します。

  • 分散パーティション ビューは、EXCEPT 演算子や INTERSECT 演算子を使用して作成することはできません。

  • 分散トランザクションは、更新によって影響を受けるすべてのノードで原子性を保証するために開始されます。

  • XACT_ABORT SET オプションを ON に設定する必要があります。

  • リモート テーブルの smallmoney 列と smalldatetime 列は、それぞれ money 列および datetime 列としてマップされます。したがって、ローカル テーブル内の対応する列も money 列および datetime 列にする必要があります。

  • どのリンク サーバーも、ループバック リンク サーバーにすることはできません。ループバック リンク サーバーは、SQL Server の同一のインスタンスを指すリンク サーバーです。

パーティション テーブルを参照しているビューが上記のルールのすべてを満たしていなくても、そのビューに INSTEAD OF トリガがあれば更新可能である場合があります。ただし、クエリ オプティマイザは、INSTEAD OF トリガがあるビューに対して、すべてのルールを満たすパーティション ビューの実行プランと同程度に効率的な実行プランを常に作成できるわけではありません。