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

转载于:https://www.cnblogs.com/tieminsa/archive/2006/11/17/563878.html

猜你喜欢

转载自blog.csdn.net/weixin_34331102/article/details/93947504