现在的位置: 首页 > 综合 > 正文

SQL SERVER 2005 分区DEMO

2018年05月04日 ⁄ 综合 ⁄ 共 8133字 ⁄ 字号 评论关闭

 http://www.cnblogs.com/tieminsa/archive/2006/11/17/563878.html

SQL SERVER 2005 分区DEMO

问题描述:
--------
每天新增的记录数超过100万条;主要的需求是能够按照
时间来查询这些历史记录,同时有新增数据在不停地添加
进来。架构上该如何来合理地规划数据,该如何合理地来处理新增和历史查询。

解决方案
--------
此类问题涉及到VLDB的管理,而分区是解决该类问题的佳选,SQL Server 2005为我们提供了更好的分区功能,需要着重分析实现一个

分区和索引的Case,实际上这是micosoft 提供的一个DEMO, 如下:

对 AdventureWorks 中的 TransactionHistory 和 TransactionHistoryArchive 表进行分区。TransactionHistory 表包含本年度的

销售记录。此表主要用于插入新记录并根据需要对其进行更新。TransactionHistoryArchive 表包含本年度之前的销售记录。此表主

要用于 SELECT 查询并用作将数据移入数据仓库的临时表

在真实方案中,TransactionHistory 表和 TransactionHistoryArchive 表可能会成为数据库中两个最大的表。通过对这两个表进行

分区,可以在它们之间管理每月数据的子集。每个月,最早一个月的数据都将从 TransactionHistory 表移动到

TransactionHistoryArchive 表。通过这种方式,TransactionHistory 表中的数据保持为最新以便进行 INSERT 和 UPDATE 操作,而

较旧的数据都移动到 TransactionHistoryArchive 表以便进行擦除和分析。由于表已分区,表之间每月数据“块”的传输通常只需几

秒,而在以前版本中要几分钟或几小时。这是因为现在只进行元数据操作,而不会对数据进行物理重定位。

对表或索引进行分区前,必须计划创建下列数据库对象:

分区函数
分区方案

分区函数定义如何根据某些列(称为分区依据列)的值将表或索引的行映射到一组分区。
分区方案将把分区函数指定的每个分区映射到文件组。

在计划分区函数时,需要考虑下列两个因素:其值确定如何对表进行分区的列(称为分区依据列)及每个分区的分区依据列的值范围

。此值范围将确定组成表的分区数。一张表最多可以有 1000 个分区。

代码DEMO :

 

--**************************************************************************************

--

-- File:    PartitionAW.sql for Partitioning Transaction History Tables Example

--

-- Summary: Range partition tables TransactionHistory and TransactionHistoryArchive

--

-- Date:    July 19, 2005

--

-- SQL Server Version: 9.00.1281.00

--

--**************************************************************************************

-- This file is part of the Microsoft SQL Server Code Samples.

-- Copyright (C) Microsoft Corporation.  All rights reserved.

--

-- This source code is intended only as a supplement to Microsoft

-- Development Tools and/or on-line documentation.  See these other

-- materials for detailed information regarding Microsoft code samples.

--

-- THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY

-- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE

-- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A

-- PARTICULAR PURPOSE.

--**************************************************************************************

 

SET DATEFORMAT mdy;

GO

 

USE [AdventureWorks];

GO

 

-- Drop foreign key constraints on TransactionHistory to allow table to be dropped

IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'FK_TransactionHistory_Product_ProductID') AND parent_object_id = OBJECT_ID(N'[Production].[TransactionHistory]'))

ALTER TABLE [Production].[TransactionHistory] DROP CONSTRAINT [FK_TransactionHistory_Product_ProductID];

GO

 

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[Production].[TransactionHistory]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)

DROP TABLE [Production].[TransactionHistory]

GO

 

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[Production].[TransactionHistoryArchive]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)

DROP TABLE [Production].[TransactionHistoryArchive];

GO

 

 

IF EXISTS (SELECT * FROM [sys].[partition_schemes] WHERE name = 'TransactionsPS1')

DROP PARTITION SCHEME [TransactionsPS1];

GO

 

IF EXISTS (SELECT * FROM [sys].[partition_functions] WHERE name = 'TransactionRangePF1')

DROP PARTITION FUNCTION [TransactionRangePF1]

GO

 

IF EXISTS (SELECT * FROM [sys].[partition_schemes] WHERE name = 'TransactionArchivePS2')

DROP PARTITION SCHEME [TransactionArchivePS2];

GO

 

IF EXISTS (SELECT * FROM [sys].[partition_functions] WHERE name = 'TransactionArchivePF2')

DROP PARTITION FUNCTION [TransactionArchivePF2]

GO

 

-- 三步曲

-- 1 Range partition table TransactionHistory 分区功能划分

CREATE PARTITION FUNCTION [TransactionRangePF1] (datetime)

AS RANGE RIGHT FOR VALUES ('10/01/2003', '11/01/2003', '12/01/2003',

               '1/01/2004', '2/01/2004', '3/01/2004', '4/01/2004',

               '5/01/2004', '6/01/2004', '7/01/2004', '8/01/2004');

GO

 

-- 2 分区架构划分

CREATE PARTITION SCHEME [TransactionsPS1]

AS PARTITION [TransactionRangePF1]

TO ([PRIMARY], [PRIMARY], [PRIMARY]

, [PRIMARY], [PRIMARY], [PRIMARY]

, [PRIMARY], [PRIMARY], [PRIMARY]

, [PRIMARY], [PRIMARY], [PRIMARY]

, [PRIMARY]);

GO

-- 3 把表创建在分区架构上

CREATE TABLE [Production].[TransactionHistory](

    [TransactionID] [int] IDENTITY (1, 1) NOT NULL,

    [ProductID] [int] NOT NULL,

    [ReferenceOrderID] [int] NOT NULL,

    [ReferenceOrderLineID] [int] NOT NULL CONSTRAINT [DF_TransactionHistory_ReferenceOrderLineID] DEFAULT (0),

    [TransactionDate] [datetime] NOT NULL CONSTRAINT [DF_TransactionHistory_TransactionDate] DEFAULT (GETDATE()),

    [TransactionType] [nchar](1) NOT NULL,

    [Quantity] [int] NOT NULL,

    [ActualCost] [money] NOT NULL,

    [ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_TransactionHistory_ModifiedDate] DEFAULT (GETDATE()),

    CONSTRAINT [CK_TransactionHistory_TransactionType] CHECK (UPPER([TransactionType]) IN ('W', 'S', 'P'))

) ON [TransactionsPS1] (TransactionDate);

GO

 

 

 

-- Range partition table TransactionHistoryArchive

CREATE PARTITION FUNCTION [TransactionArchivePF2] (datetime)

AS RANGE RIGHT FOR VALUES ('9/01/2003');

GO

 

CREATE PARTITION SCHEME [TransactionArchivePS2]

AS PARTITION [TransactionArchivePF2]

TO ([PRIMARY], [PRIMARY]);

GO

 

--   把表创建在分区架构TransactionArchivePS2

CREATE TABLE [Production].[TransactionHistoryArchive](

    [TransactionID] [int] NOT NULL,

    [ProductID] [int] NOT NULL,

    [ReferenceOrderID] [int] NOT NULL,

    [ReferenceOrderLineID] [int] NOT NULL CONSTRAINT [DF_TransactionHistoryArchive_ReferenceOrderLineID] DEFAULT (0),

    [TransactionDate] [datetime] NOT NULL CONSTRAINT [DF_TransactionHistoryArchive_TransactionDate] DEFAULT (GETDATE()),

    [TransactionType] [nchar](1) NOT NULL,

    [Quantity] [int] NOT NULL,

    [ActualCost] [money] NOT NULL,

    [ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_TransactionHistoryArchive_ModifiedDate] DEFAULT (GETDATE()),

    CONSTRAINT [CK_TransactionHistoryArchive_TransactionType] CHECK (UPPER([TransactionType]) IN ('W', 'S', 'P'))

) ON [TransactionArchivePS2] (TransactionDate);

GO

 

--以下为插入数据测试

-- Bulk Insert the TransactionHistory and TransactionHistoryArchive data.

DECLARE

     @retcode INT

    ,@data_path NVARCHAR(256)

 

SELECT @data_path = SUBSTRING([physical_name], 1, CHARINDEX(N'master.mdf', LOWER([physical_name])) - 1)

FROM [master].[sys].[master_files]

WHERE [database_id] = 1

    AND [file_id] = 1;

 

SET @data_path = LEFT(@data_path, PATINDEX('%/MSSQL%', @data_path)) + '90/Tools/Samples/AdventureWorks OLTP/'

 

EXECUTE (N'BULK INSERT [Production].[TransactionHistory] FROM ''' + @data_path + N'TransactionHistory.csv''

WITH (

   CODEPAGE=''ACP'',

   DATAFILETYPE = ''char'',

   FIELDTERMINATOR= ''/t'',

   ROWTERMINATOR = ''/n'' ,

   KEEPIDENTITY,

   TABLOCK  

)');

 

EXECUTE (N'BULK INSERT [Production].[TransactionHistoryArchive] FROM ''' + @data_path + N'TransactionHistoryArchive.csv''

WITH (

   CODEPAGE=''ACP'',

   DATAFILETYPE = ''char'',

   FIELDTERMINATOR= ''/t'',

   ROWTERMINATOR = ''/n'' ,

   KEEPIDENTITY,

   TABLOCK  

)');

GO

 

--CREATE INDEX [IX_TransactionHistory_TransactionDate] ON [Production].[TransactionHistory]([TransactionDate]);

GO

 

--CREATE INDEX [IX_TransactionHistoryArchive_TransactionDate] ON [Production].[TransactionHistoryArchive]([TransactionDate]);

GO

 

ALTER TABLE [Production].[TransactionHistory] WITH CHECK ADD

    CONSTRAINT [PK_TransactionHistory_TransactionID] PRIMARY KEY CLUSTERED

    (

        [TransactionDate],

        [TransactionID]

    )  ON [TransactionsPS1] (TransactionDate);

GO

 

ALTER TABLE [Production].[TransactionHistoryArchive] WITH CHECK ADD

    CONSTRAINT [PK_TransactionHistoryArchive_TransactionID] PRIMARY KEY CLUSTERED

    (

        [TransactionDate],

        [TransactionID]

    )  ON [TransactionArchivePS2] (TransactionDate);

GO

 

CREATE INDEX [IX_TransactionHistory_ProductID] ON [Production].[TransactionHistory]([ProductID]) ON [TransactionsPS1] (TransactionDate);

CREATE INDEX [IX_TransactionHistory_ReferenceOrderID_ReferenceOrderLineID] ON [Production].[TransactionHistory]([ReferenceOrderID], [ReferenceOrderLineID]) ON [TransactionsPS1] (TransactionDate);

GO

 

CREATE INDEX [IX_TransactionHistoryArchive_ProductID] ON [Production].[TransactionHistoryArchive]([ProductID]) ON [TransactionArchivePS2] (TransactionDate);

CREATE INDEX [IX_TransactionHistoryArchive_ReferenceOrderID_ReferenceOrderLineID] ON [Production].[TransactionHistoryArchive]([ReferenceOrderID], [ReferenceOrderLineID]) ON [TransactionArchivePS2] (TransactionDate);

GO

 

ALTER TABLE [Production].[TransactionHistory] ADD

    CONSTRAINT [FK_TransactionHistory_Product_ProductID] FOREIGN KEY

    (

        [ProductID]

    ) REFERENCES [Production].[Product](

        [ProductID]

    );

GO

 

--查询系统表,得出表在各个分区的数据分布

 

SELECT OBJECT_NAME([object_id]), * FROM [sys].[partitions]

WHERE [object_id] = OBJECT_ID('[DBO].[TA]')

ORDER BY [partition_number], [index_id];

GO

 

SELECT OBJECT_NAME([object_id]), * FROM [sys].[partitions]

WHERE [object_id] = OBJECT_ID('[dbo].[TH]')

ORDER BY [partition_number], [index_id];

GO

抱歉!评论已关闭.