数据仓库中事实表的水平分区

数据库 数据仓库
分区是管理大型数据库表的有效手段。表的水平分区是对表的行进行分区,分区后表的行会被划分为若干不重叠的小单元。通过FOR VALUES语句可以为这些分区单元指定边界范围值。要将事实表进行水平分区,我们首先需要创建一个分区函数和一个分区方案,然后再创建分区表。

对于大型数据库来说,其事实表的数据记录数量往往会在很短的时间内迅猛地增长。有时候,难以对这样的庞大的数据集进行有效的管理,甚至SQL查询的性能和速度都会受到不利的影响。数据库分区技术就应运而生了。对事实表进行水平分区,有利于改善大型数据库的查询和读写性能,并简化数据库管理。

表的水平分区是将表的行划分为多个不重叠的单元。水平分区表中的每一个分区单元都是通过对某个属性列的值进行边界范围界定的,例如日期、地理区划、客户名等等。(注:你可以考虑将每个分区单元存储在不同的硬盘,以提高查询性能)。虽然对于数据库管理员和数据库开发人员来说,对表进行水平分区并不是什么难事,不过在实际操作之前还是需要进行一定的规划,因为你正在处理的可是超大量的数据。下面,我们会和大家探讨一下什么时候应当对一个事实表进行水平分区,而进行水平分区的原因又是什么。此外,我们还会介绍如何使用SQL Server 2005的内置功能创建分区函数、分区方案和分区表。

为什么要对事实表进行水平分区?

大型表格(例如,具有亿万行的表)的管理难度很大,主要是因为表的规模太大,无论你对其进行任何操作都要花费大量的时间(例如,重新生成索引操作)。在一个事务数据库中,关联表(例如,涉及多对多关系的表)通常是拥有最多行数的表。在维度建模过程中,一个事实表相当于一个关联表。就像事务数据库中的关联表一样,事实表往往拥有比其相关维度更多的行。

分区可以将这些超大型的表分割成便于管理的小单元。如果你用于维护数据库的时间在紧缩,而需要处理的数据量却在不断的增长,你就可以先对表进行分区,再按照分区来执行备份和恢复操作以及更新表统计信息等维护任务,而不是对整个表进行这些操作。SQL Server 2005将一个分区表的所有分区看作一个逻辑实体,而且在终端用户面前,这些分区仍然以一个整体表的形式出现。

对表进行水平分区有以下原因:

◆可以更好地控制将每个分区放在存储器的哪些位置,并利用多读写头来实现快速查询。

◆可以按分区来进行备份和恢复操作,索引的重新生成和重新组织也可以按照分区来执行,而且可以对索引本身进行分区。

◆可以直接通过一个包含分区列或索引列的WHERE语句进行查询。

◆由于将锁限制在分区,你可以减少锁升级和锁管理的开销。

◆如果多个分区在同一个文件组,那么合并和分割分区就非常容易。

接下来的问题是什么表适合进行水平分区呢?适合进行水平分区的表包括包含数据量非常大的表、预计在近期内会数据量将会猛增的表、以及能够根据某种业务属性值(例如,财政年度)来直观分割的表。这些表都必须包含一个能用来将行分割成独立不重叠单元的非空属性列,例如由销售时间构成的列。

如果你的数据库包含了一个大型表格,对这个表格进行查询和更新操作时,执行的性能都没能达到你的预期要求,那么你就可以考虑对表进行分区以提高查询性能。SQL Server 2005能够识别分区,也就是说,如果包含了涉及分区列或索引列(该索引也是分区索引)的WHERE语句的查询运行很慢时,查询策略只会访问相关的分区,这样查询可以在小范围记录里进行。该功能可以显著提高查询性能。

#p#

创建分区函数

要对表进行分区,首先需要创建由一个指定的分区列和一系列范围边界值构成的分区函数。执行下面的例子中的指令为SALESFact表创建了分区函数:

CREATE PARTITION FUNCTION MyDateRangePF (datetime)

AS RANGE LEFT FOR VALUES (‘1/01/2003’, ‘1/01/2005’, ‘1/01/2007)

MyDateRangePF是分区函数的名称。在本例的环境中,分区列通常是datetime数据类型的列,例如本例中为Date_of_Event列。将datetime记录分离为不重叠的组很简单。例如,如果业务规则和已知的业务查询都表明按照销售事件发生的日期来分割表是合理的话,那么你就可以将数据分割成两年一组,就像上面的分区函数命令中所示。

(datetime)指定了分区列的数据类型,而RANGE LEFT规定了FOR VALUES所定义的边界日期属于每个边界值间隔的哪一侧。在范围分区中,如果要分为四个分区,就定义三个边界值,设置边界值有两种方法:RANGE LEFT或RANGE RIGHT。RANGE LEFT指定每个值为每个分区的上边界,而RANGE RIGHT则指定每个值为下一个分区的下边界。例如,上面的RANGE LEFT分区函数将数据分为四个分区,每个分区的取值范围如下表所示。如果用RANGE RIGHT来替代上述命令的RANGE LEFT,而使用相同的边界值,那么其分区取值范围会发生变化,见下表。

从上面的表格可以看出,如果销售事件发生的日期是2005年1月1日,那么对于RANGE LEFT分区函数,你会在第二个分区中找到这条记录,而对于RANGE RIGHT分区函数,则要在第三个分区中找到该记录。为了数据的一致性,也为了方便查询,建议对所有创建的分区表都统一选择其中一种方法设置边界值。

每一个分区的取值范围都在FOR VALUES语句明确规定了其边界值。注意,如果你使用datetime数据类型作为边界值,则必须为日期时间设定一个国际标准,特别是对在不同的时区都有分部的企业来说更是如此。SQL Server将美国英语作为该会话的默认语言,如果实际使用的是其他语言,必须创建用户自定义函数将不同的日期格式转换为美国英语格式,并在FOR VALUES子句中引用该自定义函数。

创建分区方案

现在分区函数已经创建完毕,接下来要创建一个分区方案。分区方案可以将以分区表或已分区索引的分区映射到不同的文件组,可以使用以下命令创建分区方案:

CREATE PARTITION SCHEME MyPartitionScheme

AS MyDateRangePF

TO (MyFilegroup1, MyFilegroup2, MyFilegroup3, MyFilegroup4, MyFilegroup5)

MyPartitionScheme是分区方案的名称,而MyDateRangePF则是使用该分区方案的分区函数的名称。该命令将分区函数所创建的分区映射到指定的一个或多个文件组。在上面的例子中,对分区按照Date_of_Event列使用分区函数MyDateRangePF的表的分区会按照下表所示分配到各个文件组:

上面的CREATE PARTITION FUNCTION命令包含了三个边界值和四个分区。不管分区是按照RANGE RIGHT还是RANGE LEFT创建的,分区数都比边界值数大1,每个表最多可以有1000个分区。那么为什么在本例中,分区数只有四个,却设置了五个文件组而不是四个呢?在SQL Server中,当分区数少于文件组数的时候,会将***个没有分配分区的文件组标记为NEXT USED,作为候选待用文件组,如本例中的MyFilegroup5。下面我们来看看在分区方案中,这个NEXT USED文件组是如何使用的而其重要性又有多大。

CREATE PARTITION FUNCTION命令中,***一个边界值为1/01/2007,所以Date_of_Event列的值大于等于1/01/2007的行记录都会被存储到第四个分区(P4)中。当2009年1月1日来临的时候,你可能会创建一个新的分区来维持你之前所建立的分区计划。如果你使用不包含NEXT USED文件组的原始CREATE PARTITION SCHEME命令创建新分区,你将无法将现有的P4划分成P4(保留2007年到2008年底数据的分区)和P5(存储2009年1月1日及以后数据的分区)两个分区。如果你的分区计划需要定期创建的新分区来保存新数据(如本例),那么你就要保证在你的CREATE PARTITION SCHEME命令中包含了NEXT USED文件组。你不需要为这个文件组分配一个分区。相反,你可以将多个分区映射到一个文件组,设置可以将所有的分区都映射到一个文件组。不过,你无法将一个分区映射到多个不同的文件组。

创建分区方案可能是数据库分区过程中最重要的一个步骤。在将来,你有可能需要将两个相邻分区的数据合并到一个分区里,也可能要为现有的分区增加一个边界值,还可能需要将数据从一个密集的分区移动到一个空分区中。要执行这些操作,你都需要事先做好规划,并创建分区方案来支持这些操作。

#p#

创建分区表

创建分区表和创建普通表的区别不大,你只需要在ON子句中引用分区方案的名称就可以了,见以下命令:

CREATE TABLE SALESFact

(SalesFact_KEY bigint identity

(1, 1) primary not clustered NOT NULL,

Date_of_Event datetime NOT NULL)

ON MyPartitionScheme (Date_of_Event)

通过指定分区方案的名称,你可以看出这个表是一个分区表。当然,在创建该表之前,分区方案和分区函数必须已经存在于数据库当中。

你可以将多个分区的数据合并到一个分区里。不过,你每次只能合并两个相邻的分区,所以如果你想要将一个含有多个分区的表合并成不分区的表,你就需要重复很多次合并的步骤。运行以下命令可以将两个表合并:

ALTER PARTITION FUNCTION

MyPartitionFunction()

MERGE RANGE (‘1/01/2003’)

上面的命令将会把***个分区(P1)合并到第二个分区(P2),也就是说,合并后P2分区将包含Date_of_Event值在1/01/05以前的所有行记录。在数据库内部(例如,在sys.partitions系统表中),将会记录对分区所做的修改。原来的P1和P2将变成P1,原来的P3变为P2,原来的P4变为P3。建议在合并任何分区之前,先画出数据库图表目录,因为如果你在执行这些合并操作时不够小心的话,有可能需要花费很多时间才能理清其中关系。

轻松管理超大型数据库表

SQL Server 2005能够将一个表水平分割成不重叠的单元,并将每个单元分配到一个独立的分区中,使我们能够轻松管理超大型的事实表。SQL Server 2005 的Enterprise版和Developer版都能够识别分区,这样写操作就只需访问相关分区的行,因此运行的速度比要访问整个表的内容来得更快。

【编辑推荐】

  1. 动态数据仓库渐兴起 推动BI走到前端
  2. 轻松掌握数据仓库开发
  3. BI技术在全面预算管理中的研究
  4. CRM中商业智能之数据挖掘全视图
  5. 走近数据库前沿技术——集群
责任编辑:杨鹏飞 来源: IT专家网
相关推荐

2020-11-18 09:39:02

MySQL数据库SQL

2020-07-30 17:59:34

分库分表SQL数据库

2013-03-20 16:23:53

数据清洗

2011-08-25 18:09:36

SQL Server创建数据仓库已分区表

2023-07-27 15:38:52

数据集

2010-07-21 14:50:23

SQL Server

2010-07-21 14:55:48

SQL Server

2023-08-14 16:56:53

2010-07-21 15:16:08

SQL Server

2010-07-21 15:01:09

SQL Server

2022-06-24 09:38:43

数据库大数据

2021-09-01 10:03:44

数据仓库云数据仓库数据库

2009-01-20 14:22:49

ODS数据仓库教程

2016-08-15 12:57:01

数据仓库索引架构维度索引

2023-10-08 16:26:23

数据仓库

2009-01-19 15:52:20

OracleOSFA数据仓库

2022-07-28 13:47:30

云计算数据仓库

2022-08-01 11:30:27

数据建模

2016-12-21 12:46:47

数据仓库SQLHive

2017-11-24 17:20:37

数据库数据仓库读写分离
点赞
收藏

51CTO技术栈公众号