web-dev-qa-db-ja.com

パーティションキーを更新して、パーティション間で行を移動できますか?

これはかなり単純な質問だと思いますが、実際にこれに対する答えを見つけるのは困難でした。

質問:パーティション列を更新して、パーティションの境界を越えるようにするだけで、パーティションテーブル内のデータ行をあるパーティションから別のパーティションに移動できますか?

たとえば、パーティションキーを持つテーブルがあるとします。

CREATE TABLE SampleTable
(
    SampleID INT PRIMARY KEY,
    SampleResults VARCHAR(100) NOT NULL,
)

主キーにマップするパーティション関数を使用すると:

CREATE PARTITION FUNCTION MyPartitionFunc (INT) AS
RANGE LEFT FOR VALUES (10000, 20000);

SampleIDを1から(たとえば)500,000に変更して、最初のパーティションから3番目のパーティションに行を移動できますか?

注:どちらもパーティション分割をサポートしているので、これをsql server 2005と2008の両方としてタグ付けしています。彼らはそれを異なって扱いますか?

17
Richard

テストに使用する2005サーバーがありません。しかし、2008年はこれを期待どおりに処理しているようです。

USE [Test]
GO
CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO
--Add one record to each partition
INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;
GO
--Move row between partitions
UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;

更新前に各パーティションに1つのレコードが表示され、その後、最初のパーティションに両方のレコードが表示されます。

14
Kenneth

これをテストするために、実験は実際にテーブルを分割する必要があります。参照 http://www.kodyaz.com/articles/how-to-partition-table-non-partitioned-table-sql-server-2008.aspx

パーティショニング関数を照会すると、パーティショニング関数の内容がわかります。データがどこに保存されているかは表示されません。ここですでに説明したように、実際にテーブルをパーティション化することなく、パーティション化関数を設定して実行できます。

テーブルをパーティション分割するには、ファイルグループと、パーティション分割関数を使用して関数結果をファイルグループに割り当てるパーティション分割スキームも作成する必要があります。次に、そのパーティション分割スキームを使用するテーブルにクラスター化キーを配置する必要があります。

パーティションを設定する

私はコマンドラインSQLの専門家ではありません。 SSMSインターフェースを使用して、pfg1(pf1ファイルを含む)およびpfg2(pf2ファイルを含む)のファイルグループをセットアップしました。次に、パーティショニング関数とスキームを宣言しました。

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO

CREATE PARTITION SCHEME ps_IDRange1
AS PARTITION IDRange1
TO (pfg1, pfg2)
GO

テーブルとクラスター化インデックスを作成する

CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE CLUSTERED INDEX PK_IDRanges
ON dbo.IDRanges(id) ON ps_IDRange1 (ID)
GO

これを行った後、sys.partitions(2005を持っています)をクエリすると、テーブルのパーティションが1つだけではなく2つになったことがわかります。これは、このテーブルのパーティショニングが完全に実装されたことを示しています。

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id partition_number hobt_id rows 
 -------------------- ----------- -------- --- ---------------- -------------------- ----------- --------- 
 72057597780295680 770674389 1 1 72057597780295680 0 
 72057597780361216 770674389 1 2 72057597780361216 0 

これで2つのパーティション(それぞれに行数がある)ができたので、実験を行うことができます。

行を挿入する

INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)

Sys.partitionsをチェックして、何が起こったかを確認します。

select * from sys.partitions where object_id = object_id('IDRanges')
 partition_id object_id index_id partition_number hobt_id rows 
 -------------------- ----------- --- -------- ---------------- -------------------- ------ -------------- 
 72057597780295680 770674389 1 1 72057597780295680 1 
 72057597780361216 770674389 1 2 72057597780361216 1 

うん。各パーティションに1行。

行を移動します。

UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17

パーティションを確認する

select * from sys.partitions where object_id = object_id('IDRanges')
 partition_id object_id index_id partition_number hobt_id rows 
 -------------------- ----------- --- -------- ---------------- -------------------- ------ -------------- 
 72057597780295680 770674389 1 1 72057597780295680 2 
 72057597780361216 770674389 1 2 72057597780361216 0 

これで、最初のパーティションは1行ではなく2行になり、2番目のパーティションは2行ではなく0行になります。

これは、パーティションテーブルのクラスター化されたキーを変更した結果、行が自動的に移動されたことを確認していると思います。

9
Jason Holladay