パーティションがOrderDate
によって決定されるパーティションテーブルを作成しようとしています。 OrderDate
にclustered index
を、OrderID
にnonclustered primary key
を作成しようとしています。しかし、私は言ってエラーが出ます:
メッセージ1908、レベル16、状態1、行1列 'OrderDate'は、インデックス 'PK_OrderID'のパーティション列です。一意のインデックスのパーティション列は、インデックスキーのサブセットである必要があります。メッセージ1750、レベル16、状態0、行1制約を作成できませんでした。以前のエラーを参照してください。
これを機能させるためにこれを変更する方法:
CREATE TABLE dbo.Orders
(
OrderID INT NOT NULL ,
Name NVARCHAR(20) NULL ,
OrderDate DATE NOT NULL ,
)
ON PartSchemeOrders(OrderDate)
CREATE CLUSTERED INDEX IX_OrderDate
on dbo.Orders (OrderDate)
on PartSchemeOrders(OrderDate)
ALTER TABLE dbo.Orders
ADD CONSTRAINT PK_OrderID PRIMARY KEY NONCLUSTERED (OrderID)
エラーメッセージに示されているように、パーティションアラインされた一意のインデックスには、パーティションキーをインデックスキーに含める必要があります。この要件が存在するため、エンジンはすべてのパーティションをチェックせずに更新に一意性を適用できます。
あなたの場合、これは、非クラスター化インデックスキーにOrderDate
を含めるか、非整列インデックスを持つことを意味します。状況に応じて、どちらも有効な選択肢である可能性があります。アラインメントを維持するために、テーブルとインデックスの定義は次のようになります。
CREATE TABLE dbo.Orders
(
OrderID integer NOT NULL,
Name nvarchar(20) NULL,
OrderDate date NOT NULL,
CONSTRAINT PK__Orders_OrderID_OrderDate
PRIMARY KEY NONCLUSTERED
(OrderID, OrderDate)
ON PS (OrderDate)
)
ON PS (OrderDate);
GO
CREATE CLUSTERED INDEX CX__Orders_OrderDate
ON dbo.Orders (OrderDate)
ON PS (OrderDate);
もちろん、これにより、非クラスター化インデックスが実施する一意性が変わります。現在、OrderID
とOrderDate
の組み合わせのみが一意であることが保証されています。理論的には、OrderID
が異なる限り、重複するOrderDate
sを追加することができます。このセマンティックの変更が受け入れられるかどうかは、状況によって異なりますが、注意する必要があります。
代替策は、非クラスター化主キーを非整列にすることです。
CREATE TABLE dbo.Orders
(
OrderID integer NOT NULL,
Name nvarchar(20) NULL,
OrderDate date NOT NULL,
CONSTRAINT PK__Orders_OrderID
PRIMARY KEY NONCLUSTERED
(OrderID)
ON [PRIMARY]
)
ON PS (OrderDate);
GO
CREATE CLUSTERED INDEX CX__Orders_OrderDate
ON dbo.Orders (OrderDate)
ON PS (OrderDate);
これにより、OrderID
の一意性のみが維持され、インデックスを使用してMIN
またはMAX
の集計を計算するクエリでいくつかの利点がありますが、切り替え操作後にプライマリキーを削除して再作成することなく、SWITCH
パーティションをイン/アウトできなくなります。
Books Onlineのこのセクション のパーティション分割の詳細と、Remus Rusanuによる この優れた回答 の整列インデックスと非整列インデックスの問題についての詳細を読むことができます。