发布网友 发布时间:2022-04-22 23:58
共4个回答
懂视网 时间:2022-04-08 11:40
优化思路:采用分区表来实现日志表的自动随时间窗口滚动,即每天新增明天分区,并将7天前数据归档至日志表。以8月份为例子,当日日期为8号,流程如下图:
具体步骤:
1.建立32个文件组,32个数据库文件,对应于每月31天,每月对31个文件进行复用
-- 创建文件组 USE [master] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY00] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY01] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY02] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY03] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY04] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY05] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY06] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY07] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY08] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY09] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY10] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY11] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY12] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY13] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY14] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY15] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY16] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY17] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY18] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY19] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY20] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY21] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY22] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY23] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY24] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY25] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY26] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY27] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY28] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY29] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY30] GO ALTER DATABASE TClientLog ADD FILEGROUP [FGDAY31] GO -- 创建和文件组相对应的文件,由于只有3个盘 USE [master] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY01‘, FILENAME = N‘E:partfileFDAY01.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY01] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY02‘, FILENAME = N‘E:partfileFDAY02.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY02] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY03‘, FILENAME = N‘E:partfileFDAY03.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY03] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY04‘, FILENAME = N‘E:partfileFDAY04.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY04] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY05‘, FILENAME = N‘E:partfileFDAY05.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY05] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY06‘, FILENAME = N‘E:partfileFDAY06.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY06] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY07‘, FILENAME = N‘E:partfileFDAY07.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY07] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY08‘, FILENAME = N‘E:partfileFDAY08.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY08] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY09‘, FILENAME = N‘E:partfileFDAY09.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY09] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY10‘, FILENAME = N‘E:partfileFDAY10.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY10] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY11‘, FILENAME = N‘E:partfileFDAY11.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY11] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY12‘, FILENAME = N‘E:partfileFDAY12.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY12] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY13‘, FILENAME = N‘E:partfileFDAY13.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY13] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY14‘, FILENAME = N‘E:partfileFDAY14.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY14] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY15‘, FILENAME = N‘E:partfileFDAY15.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY15] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY16‘, FILENAME = N‘E:partfileFDAY16.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY16] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY17‘, FILENAME = N‘E:partfileFDAY17.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY17] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY18‘, FILENAME = N‘E:partfileFDAY18.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY18] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY19‘, FILENAME = N‘E:partfileFDAY19.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY19] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY20‘, FILENAME = N‘E:partfileFDAY20.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY20] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY21‘, FILENAME = N‘E:partfileFDAY21.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY21] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY22‘, FILENAME = N‘E:partfileFDAY22.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY22] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY23‘, FILENAME = N‘E:partfileFDAY23.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY23] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY24‘, FILENAME = N‘E:partfileFDAY24.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY24] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY25‘, FILENAME = N‘E:partfileFDAY25.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY25] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY26‘, FILENAME = N‘E:partfileFDAY26.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY26] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY27‘, FILENAME = N‘E:partfileFDAY27.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY27] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY28‘, FILENAME = N‘E:partfileFDAY28.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY28] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY29‘, FILENAME = N‘E:partfileFDAY29.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY29] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY30‘, FILENAME = N‘E:partfileFDAY30.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY30] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY31‘, FILENAME = N‘E:partfileFDAY31.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY31] GO ALTER DATABASE TClientLog ADD FILE ( NAME = N‘FDAY00‘, FILENAME = N‘E:partfileFDAY00.ndf‘ , SIZE = 100MB , FILEGROWTH = 500MB ) TO FILEGROUP [FGDAY00] GO
注意:为什么是32个文件组,32个数据库文件。这和分区函数和分区方案有关系,比如分区函数以DATETIME为分区类型,建立20150801和20150802两个边界,那么就会产生如下3个分区。那相应的分区方案中就要有3个文件组和其对应。
在建立分区函数时,边界的归属。请看上图,以20150801为例,如果是right,边界归属于右边,所分的两个区间:数据<20150801和20150801<=数据<20150802;如果是left,边界归属左边,所分区间为:数据<=20150801和20150801<数据<=20150802;总结一句话,关键字是那边,那么边界值就归属于所分区域的那边。
对于是否有必要将每个文件建立到不同的磁盘上,我这里没有建立,因为应用中的查询一般不会跨分区,都查近几个小时的,所以没有必要将文件建立到不同的磁盘文件中。
如果对于分区表的基础概念还不清楚,请看SQL Server表分区。
2.建立相应的分区函数和分区方案
USE TClientLog; CREATE PARTITION FUNCTION part_day_rang_func(DATETIME) AS RANGE right FOR VALUES ( ‘2015-08-01 00:00:00‘, ‘2015-08-02 00:00:00‘, ‘2015-08-03 00:00:00‘, ‘2015-08-04 00:00:00‘, ‘2015-08-05 00:00:00‘, ‘2015-08-06 00:00:00‘, ‘2015-08-07 00:00:00‘, ‘2015-08-08 00:00:00‘, ‘2015-08-09 00:00:00‘, ‘2015-08-10 00:00:00‘, ‘2015-08-11 00:00:00‘, ‘2015-08-12 00:00:00‘, ‘2015-08-13 00:00:00‘, ‘2015-08-14 00:00:00‘, ‘2015-08-15 00:00:00‘, ‘2015-08-16 00:00:00‘, ‘2015-08-17 00:00:00‘, ‘2015-08-18 00:00:00‘, ‘2015-08-19 00:00:00‘, ‘2015-08-20 00:00:00‘, ‘2015-08-21 00:00:00‘, ‘2015-08-22 00:00:00‘, ‘2015-08-23 00:00:00‘, ‘2015-08-24 00:00:00‘, ‘2015-08-25 00:00:00‘, ‘2015-08-26 00:00:00‘, ‘2015-08-27 00:00:00‘, ‘2015-08-28 00:00:00‘, ‘2015-08-29 00:00:00‘, ‘2015-08-30 00:00:00‘, ‘2015-08-31 00:00:00‘); CREATE PARTITION SCHEME part_day_rang_scheme AS PARTITION part_day_rang_func TO ( FGDAY00, FGDAY01, FGDAY02, FGDAY03, FGDAY04, FGDAY05, FGDAY06, FGDAY07, FGDAY08, FGDAY09, FGDAY10, FGDAY11, FGDAY12, FGDAY13, FGDAY14, FGDAY15, FGDAY16, FGDAY17, FGDAY18, FGDAY19, FGDAY20, FGDAY21, FGDAY22, FGDAY23, FGDAY24, FGDAY25, FGDAY26, FGDAY27, FGDAY28, FGDAY29, FGDAY30, FGDAY31 );
注意:分区方案指定的是文件组不是文件,FGDAY00文件组对应的分区是‘分区数据<20150801‘,FGDAY31对应的分区是‘分区数据>=20150831‘。
3.建立主日志分区表和历史日志分区表,以表内的时间字段为分区键,索引采用与表分区对齐方式,分区自动化管理脚本如下:
CREATE TABLE [dbo].[ClientLog]( [SynID] [nchar](38) NOT NULL, [ParkingId] [int] NOT NULL, [ParkingBoxId] [int] NOT NULL, [Message] [varchar](max) NULL, [OccurTime] [datetime] NOT NULL, [UpdateTime] [datetime] NOT NULL, [ErrorLevel] [int] NOT NULL, [State] [int] NULL, [IsSend] [int] NULL, CONSTRAINT [PK_ClientLog] PRIMARY KEY NONCLUSTERED ( [SynID] ASC, [OccurTime] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [part_day_rang_scheme]([OccurTime]) ) ON [part_day_rang_scheme]([OccurTime]) GO CREATE NONCLUSTERED INDEX [idx_clientlog_otime] ON [dbo].[ClientLog] ( [ParkingId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [part_day_rang_scheme]([OccurTime]) GO
注意:主键中必须包含分区键;分区索引必须使用和表一致的分区方案,即索引必须与表对齐,才能进行分区切换;
4.主日志分区表保留7天,每天增加后数第7天的分区,前数第7天的数据进行归档,与日志历史表进行分区交换,流程图参考优化思路的图。
-- ============================================= -- Author: zhangkun -- Create date: <2015.08.07> -- Description: <根据日志的滑动窗口业务,进行自动化分区管理> -- ============================================= -- 1.修改分区方案和分区函数 -- 2.进行分区交换,将归档数据放入历史表 alter PROCEDURE [dbo].[sp_PartitionManage] @td DATETIME AS BEGIN DECLARE @flag CHAR(1) --标志位 IF @td IS NULL --如果@td为null,则默认当天 SET @td = GETDATE() -- 1.修改分区方案和分区函数,当天新增后数第七天的日期 BEGIN DECLARE @td_next7 DATETIME DECLARE @day_next7 VARCHAR(2) DECLARE @sql NVARCHAR(MAX) --动态sql字符串 SET @td_next7 = DATEADD(DAY, 7, @td) --7天后日期 SET @day_next7 = CASE WHEN LEN(DATENAME(DAY, @td_next7)) = 1 THEN ‘0‘ + DATENAME(DAY, @td_next7) ELSE DATENAME(DAY, @td_next7) END; --7天后是当月第几天SELECT @flag = COUNT(1) FROM sys.partition_functions a , sys.partition_range_values b WHERE a.name = ‘part_day_rang_func‘ AND a.function_id = b.function_id AND CONVERT(DATETIME, b.value) = CONVERT(VARCHAR(10), @td_next7, 120) + ‘ 00:00:00.000‘; PRINT @flag; IF ( @flag != ‘1‘ ) BEGIN SET @sql = ‘alter partition scheme part_day_rang_scheme next used FGDAY‘ + @day_next7 + ‘; alter partition function part_day_rang_func() split range(‘‘‘ + CONVERT(VARCHAR(10), @td_next7, 120) + ‘‘‘)‘ EXEC sp_executesql @sql; END END -- 2.进行分区交换,将归档数据放入历史表 DECLARE @td_before7 DATETIME DECLARE @day_before7 VARCHAR(2) SET @td_before7 = DATEADD(DAY, -7 热心网友 时间:2022-04-08 08:48 你第一个句子应该是创建了三个分区:<='01/01/2007'、<='01/01/2008'并且>'01/01/2007'、>'01/01/2008',所以下面的名称应该是三个就够了(FG1,FG2,FG3)
参考:
SQL Server数据库表分区操作过程由三个步骤组成:
1. 创建分区函数
2. 创建分区架构
3. 对表进行分区
下面将对每个步骤进行详细介绍。
步骤一:创建一个分区函数
此分区函数用于定义你希望SQL Server如何对数据进行分区的参数值([u]how[/u])。这个操作并不涉及任何表格,只是单纯的定义了一项技术来分割数据。
我们可以通过指定每个分区的边界条件来定义分区。例如,假定我们有一份Customers表,其中包含了关于所有客户的信息,以一一对应的客户编号(从1到1,000,000)来区分。我们将通过以下的分区函数把这个表分为四个大小相同的分区:
CREATEPARTITIONFUNCTIONcustomer_partfunc(int)
ASRANGERIGHT
FORVALUES(250000,500000,750000)
这些边界值定义了四个分区。第一个分区包括所有值小于250,000的数据,第二个分区包括值在250,000到49,999之间的数据。第三个分区包括值在500,000到7499,999之间的数据。所有值大于或等于750,000的数据被归入第四个分区。
请注意,这里调用的"RANGE RIGHT"语句表明每个分区边界值是右界。类似的,如果使用"RANGE LEFT"语句,则上述第一个分区应该包括所有值小于或等于250,000的数据,第二个分区的数据值在250,001到500,000之间,以此类推。
步骤二:创建一个分区架构
一旦给出描述如何分割数据的分区函数,接着就要创建一个分区架构,用来定义分区位置([u]where[/u])。创建过程非常直截了当,只要将分区连接到指定的文件组就行了。例如,如果有四个文件组,组名从"fg1"到"fg4",那么以下的分区架构就能达到想要的效果:
CREATEPARTITIONSCHEMEcustomer_partscheme
ASPARTITIONcustomer_partfunc
TO(fg1,fg2,fg3,fg4)
注意,这里将一个分区函数连接到了该分区架构,但并没有将分区架构连接到任何数据表。这就是可复用性起作用的地方了。无论有多少数据库表,我们都可以使用该分区架构(或仅仅是分区函数)。
步骤三:对一个表进行分区
定义好一个分区架构后,就可以着手创建一个分区表了。这是整个分区操作过程中最简单的一个步骤。只需要在表创建指令中添加一个"ON"语句,用来指定分区架构以及应用该架构的表列。因为分区架构已经识别了分区函数,所以不需要再指定分区函数了。
例如,使用以上的分区架构创建一个客户表,可以调用以下的Transact-SQL指令:
CREATETABLEcustomers(FirstNamenvarchar(40),LastNamenvarchar(40),CustomerNumberint)
ONcustomer_partscheme(CustomerNumber)
关于SQL Server的表分区功能,你知道上述的相关知识就足够了。记住!编写能够用于多个表的一般的分区函数和分区架构就能够大大提高可复用性。追问你好,用你给出的例子,为什么还是 消息 208,级别 16,状态 58,第 2 行
对象名 'fg1' 无效呢,不胜感激啊!追答文件组没有创建吧:
ALTER DATABASE sandboxdb ADD FILEGROUP fg1
ALTER DATABASE sandboxdb ADD FILEGROUP fg2
ALTER DATABASE sandboxdb ADD FILEGROUP fg3
ALTER DATABASE sandboxdb ADD FILEGROUP fg4
关于文件组及分区的部分看下相关文档吧,我也很少用,讲得不是很系统。
热心网友 时间:2022-04-08 10:06
sql server 和分区表没有关系的。
sql server 是数据库,分区表是硬盘分区用的。
你要创建数据库表
create table tableName (
sex varchar(10),
year varchar(4)
)
但是只有性别和出生年份没有实际意义的。
另外,虚机团上产品团购,超级便宜热心网友 时间:2022-04-08 11:41
视图不是物理表,
不能对视图做dml操作.