什么数据库须要进行分区?首先看一下咱们的案例:2010年6月咱们六期IT开发团队接到一个XX全国连锁店的餐饮系统,通过一周的敏捷开发以后,XX餐饮系统正式上线了,因为该软件的功能强大,操做简单,功能灵活等特性,很快在全国各地铺展开来。XX餐饮店的美食也颇受顾客的喜好,有的店天天的收入高达1W元人民币,天天这么多的收入,那么天天要产生多大的订单呢?< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />mysql
这是一个很大的数据量,在刚开始的几个月中,咱们还可以正常根据所产生的全部订单,根据产品的类别和销售状况,产生一个商品销售排行报表。但是随着数据量愈来愈大,如今每次进行商品销售排行汇总都要进行很长时间的等待。而咱们的服务器性能是没有问题的,那么咱们只有改善数据库的结构来提升数据的检索效率了。改善数据库的结构有两种,一种是采用存储过程代替普通的SQL语句,另一种就是使用数据库系统中加强索引和规划分区表进行优化,这里咱们采用第二种方案来解决问题。程序员
咱们这里采用数据分区表的方法来进行数据优化,那么是否是只要数据量足够大以后就要进行数据库分区表来提升查询效率呢?数据多了并非建立分区表的唯一条件,哪怕你有一千万条记录,可是这一千万条记录都是经常使用的记录,那么最好也不要使用分区表,说不定会得不偿失。只有你的数据是分段的数据,那么才要考虑到是否须要使用分区表。这里咱们的数据是按时间段进行查询的,因此咱们能够在这里进行分区。sql
上面这些就是咱们进行数据分区表的前提,若是你有这样的需求,那么还等什么,赶快使用数据分区表吧。这里咱们提供一个简单的数据库,方便之后实例的练习,若是你须要的话,能够点击这里下载。若是你有一个刚刚备份过来的数据库,就是还原不成功怎么办?这里有解决方案。数据库
表分区分为水平分区和垂直分区。水平分区将表分为多个表。每一个表包含的列数相同,可是行更少。例如,能够将一个包含十亿行的表水平分区成 12 个表,每一个小表表示特定年分内一个月或几个月的数据。任何须要特定月份数据的查询只需引用相应月份的表。而垂直分区则是将原始表分红多个只包含较少列的表。水平分区是最经常使用分区方式,后面咱们以水平分区来介绍具体实现方法。编程
简单一点说,分区表就是将一个大表分红若干个小表。这里,咱们有一个销售记录表,记录着每一个某餐饮店的订单状况,那么你就能够把这个销售记录表按时间分红几个小表,咱们这里分红15个小表。2011年之前的记录使用一个表,2011年的记录每两个月使用一个表(2011//01/01-2011/03/01,每一个两个月一个表,一共六个表),2012年,2013()年的的记录同上,2013年的记录使用一个表,2012年之后的记录使用一个表。那么,你想查询哪一个年份的记录,就能够去相对应的表里查询,因为每一个表中的记录数少了,查询起来时间天然也会减小。服务器
但将一个大表分红几个小表的处理方式,会给程序员增长编程上的难度。以添加记录为例,以上15个表是独立的15个表,在不一样时间添加记录的时候,程序员要使用不一样的SQL语句,例如在2011年添加记录时,程序员要将记录添加到2011年那个表里;在2012年添加记录时,程序员要将记录添加到2012年的那个表里。这样,程序员的工做量会增长,出错的可能性也会增长。 ide
使用分区表就能够很好的解决以上问题。分区表能够从物理上将一个大表分红几个小表,可是从逻辑上来看,仍是一个大表。分区表能够将一个销售记录表分红十五个物理上的小表,可是对于程序员而言,他所面对的依然是一个大表,不管是2010年添加记录仍是2012年添加记录,对于程序员而言是不须要考虑的,他只要将记录插入到销售记录表——这个逻辑中的大表里就好了。SQL Server会自动地将它放在它应该呆在的那个物理上的小表里。函数
一样,对于查询而言,程序员也只须要设置好查询条件,OK,SQL Server会自动将去相应的表里查询,不用管太多事了。性能
分区表的准备工做完事了,下一步就是具体建立分区表了,等不急了吧,看下篇博文你就知道了。学习
建立分区表必需要通过下面五个步骤。
1)建立文件组
2)建立文件
3)建立分区函数
4)建立分区方案
5)建立分区表
(1)建立文件组,有两种方案,一种是经过手动添加,另一种就是经过SQL脚本进行添加。下面以两种方案来讲明:
方案一:建立文件组,虽然这一步咱们能够省略,由于咱们能够直接使用Primary文件(也就是系统主文件)。可是为了方便管理,咱们仍是要建立几个文件组,这样能够将不一样的小表(不一样时间段,或者不一样数据表)放在不一样的文件组里,既便于理解又能够提升运行速度。
打开SQL Server Management Studio,找到分区表所在的数据库,右键单击选择“属性”,选择“文件组”选项,单击下面的“添加”按钮,添加X个文件组,以下图所示:
方案二:经过查询分析器SQL脚本执行
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2010
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2012
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2013
(2)建立数据库文件
方案一:建立了文件组以后,还要再建立几个数据库文件。为何要建立数据库文件,这很好理解,由于分区的小表必需要放在硬盘上,而放在硬盘上的什么地方呢?固然是文件里啦。再说了,文件组中没有文件,文件组还要来有啥用呢?仍是在上图的那个界面,选择“文件”选项,而后添加几个文件。在添加文件的时候要注意如下几点:
一、不要忘记将不一样的文件放在文件组中。固然一个文件组中也能够包含多个不一样的文件。
二、若是能够的话,将不一样的文件放在不一样的硬盘分区里,最好是放在不一样的独立硬盘里。要知道IQ的速度每每是影响SQL Server运行速度的重要条件之一。将不一样的文件放在不一样的硬盘上,能够加快SQL Server的运行速度。
在本文的实例中,数据库主文件与分区文件就不在同一个目录下,各个分区文件也能够放置在不一样的目录下,建议你们在练习时使用。
方案二:经过查询分析器SQL脚本执行
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail2010', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail2010.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2010
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201102', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201102.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2010
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201104', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201104.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201106', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201106.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201108', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201108.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201110', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201110.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201112', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201112.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201202', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201202.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2012
.
.
.
因为建立的数据文件太多了,这里就不一一贴出来了,剩下的几个,留给你们本身锻炼一下吧。建立完分区文件后,你就能够在D盘相应的目录下找到你刚刚建立的数据文件。
(3)建立分区函数
建立一个分区函数,建立分区函数的目的是告诉SQL Server以什么方式对分区表进行分区。这一步必需要什么SQL脚原本完成。以上面的例子,咱们要将销售记录表按时间分红15个小表。划分的时间为:
第1个小表:2011-01-01之前的数据(不包含2010-01-01)。
第2个小表:2011-01-01(包含2011-01-01)到2010-01-01之间的数据。
第3个小表:2011-03-01(包含2011-03-01)到2011-05-01之间的数据。
第4个小表:2011-05-01(包含2011-05-01)到2011-07-01之间的数据。
第5个小表:……
第6个小表:……
--建立分区函数
CREATE PARTITION FUNCTION partfun_CX (datetime)
AS RANGE RIGHT FOR VALUES('20110101','20110301','20110501','20110701','20110901','20111101','20120101','20120301','20120501','20120701','20120901','20121101','20130101','20130301','20130501','20130701')
一、CREATE PARTITION FUNCTION意思是建立一个分区函数。
二、partfun_CX为分区函数名称。
三、AS RANGE RIGHT为设置分区范围的方式为Right,也就是右置方式。
四、FOR VALUES ('20110101','20110301','20110501','20130101',……)为按这些个值来分区,Values中的值就是分区的条件
(4)建立分区方案
分区方案的做用是将分区函数生成的分区映射到文件组中去。分区函数的做用是告诉SQL Server,如何将数据进行分区,而分区方案的做用则是告诉SQL Server将已分区的数据放在哪一个文件组中。
--.建立分区方案
CREATE PARTITION SCHEME partsch_CX
AS PARTITION partfun_CX
TO (
CX2010,
CX2011, CX2011, CX2011, CX2011, CX2011,CX2011,
CX2012, CX2012, CX2012, CX2012, CX2012,CX2012,
CX2013, CX2013, CX2013, CX2013)
一、CREATE PARTITION SCHEME意思是建立一个分区方案。
二、partsch_CX为分区方案名称。
三、AS PARTITION partfun_CX说明该分区方案所使用的数据划分条件(也就是所使用的分区函数)为partfun_CX。
四、TO后面的内容是指partfun_CX分区函数划分出来的数据对应存放的文件组。
到此为止,分区函数和分区方案就建立完毕了。建立后的分区函数和分区方案在数据库的“存储”中能够看到
(5)建立分区表
建立分区表,建立方式和建立广泛表相似,以下所示:
CREATE TABLE t_partition3(
ptId int IDENTITY(1,1) NOT NULL primary key NONCLUSTERED,
ptName varchar(16) NOT NULL,
sellTime[datetime] NOT NULL
) ON partsch_CX(sellTime)
若是你按照上面的代码来实现的话出出现下图所示的错误代码提示:
消息1908,级别16,状态1,第1 行
列'sellTime' 是索引'PK__t_partition3__671F4F74' 的分区依据列。惟一索引的分区依据列必须是索引键的子集。
消息1750,级别16,状态0,第1 行
没法建立约束。请参阅前面的错误消息。
这里是不能建立除分区表中除分区字段之外的其它字段为汇集索引,由于汇集索引是在物理上顺序存储的,而分区表是将数据分别存储在不一样的表中,这两个概念是冲突的。若是咱们建立了其它字段的汇集索引,那么就会按照其它字段在物理上顺序存储,而咱们的分区表是根据分区字段进行物理上的顺序存储的。
2011-02-15 16:27:43| 分类: 数据库学习 | 标签: |字号大中小 订阅
咱们的数据库已经投入使用一段时间了,可是当时没有建立建立分区表,如今咱们须要作的是将普通表转换成分区表,可是并不能影响咱们数据库里面的数据,那么咱们应该如何作呢?只需在该表上建立一个汇集索引,并在该汇集索引中使用分区方案便可。
说的很简单,可是在实现实现可就没有那么容易了,由于你的数据库中存在主键,外键等约束关系,那么咱们在将普通表转换成分区表时,首先就须要解决这些问题。
咱们知道分区表时某个字段为分区条件的,除了这个字段以外的其余字段是不能建立汇集索引的,因此咱们将普通表转换成分区表时,必需要删除汇集索引,而后再从新建立一个新的汇集索引,在该汇集索引中使用分区方案。
可是咱们须要修改的t_sellLog表中的orderId既是主键又是汇集索引,并且仍是其它表的外键。所以,咱们只能先删除外键关联,再删除主键,而后从新建立orderId为主键,可是设置为非汇集索引,而后将咱们的sellTime字段设置为汇集索引,最后添加上咱们的外键约束,至此普通表转换成分区表的工做结束,代码以下:
--查看外键约束
use CX_Partiton_Scheme
exec sp_helpconstraint t_SellLog
--删除外键约束
alter table t_sellLog drop constraint FK_t_SellLog_t_User
--删掉主键
ALTER TABLE t_SellLog DROP constraint PK_t_SellLog
--建立主键,但不设为汇集索引
ALTER TABLE t_SellLog ADD CONSTRAINT PK_t_SellLog PRIMARY KEY NONCLUSTERED (
orderId ASC
)
ON [PRIMARY]
--建立一个新的汇集索引,在该汇集索引中使用分区方案
CREATE CLUSTERED INDEX CT_SellLog ON t_SellLog(sellTime)
ON partsch_CX([sellTime])
--添加删除掉的外键约束(具体本身根据实际状况本身实现)
转换成功以后,咱们能够经过下面代码查看每一个分区表中的记录数:
--统计全部分区表中的记录总数
select $PARTITION.partfun_CX([sellTime]) as 分区编号,count(orderId) as 记录数from t_SellLog group by$PARTITION.partfun_CX([sellTime])
咱们还能够经过下面的代码,查看数据库库中的数据在哪一个分区中:
--查看数据库表中的数据在哪一个分区中
select $PARTITION.partfun_CX('2010-10-1') --查询年月日的数据在哪一个分区中
select $PARTITION.partfun_CX('2011-01-1') --查询年月日的数据在哪一个分区中若是你想比较一下咱们使用分区方案以后和以前程序有多少效率提升,咱们能够经过下面的语句来看看一下脚本的执行时间就OK了,我通过测试的数据是快了0.017秒,一方面因为咱们的测试数据量比较小,另外一方面个人机器配置仍是蛮不错的。
--查看SQL脚本的执行时间
select getDate()
select * from t_sellLog
select getDate()