数据库存储大数据量(千万条记录级别)数据的考虑要点
分区
?将数据库分区可提高其性能并易于维护。通过将一个大表拆分成更小的单个表,只访问一小部分数据的查询可以执行得更快,因为需要扫描的数据较少。而且可以更快地执行维护任务(如重建索引或备份表)。
?实现分区操作时可以不拆分表,而将表物理地放置在个别的磁盘驱动器上。例如,将表放在某个物理驱动器上并将相关的表放在与之分离的驱动器上可提高查询性能,因为当执行涉及表之间联接的查询时,多个磁头同时读取数据。可以使用 Microsoft? SQL Server? 2000 文件组指定将表放置在哪些磁盘上。
?
?硬件分区
?硬件分区将数据库设计为利用可用的硬件构架。硬件分区的示例包括:
?允许多线程执行的多处理器,使得可以同时执行许多查询。换句话说,在多处理器上可以同时执行查询的各个组件,因此使单个查询的速度更快。例如,查询内引用的每个表可同时由不同的线程扫描。
?RAID(独立磁盘冗余阵列)设备允许数据在多个磁盘驱动器中条带化,使更多的读/写磁头同时读取数据,因此可以更快地访问数据。在多个驱动器中条带化的表一般比存储在一个驱动器上的相同的表扫描速度要快。换句话说,将表与相关的表分开存储在不同的驱动器上可以显著提高联接那些表的查询的性能。
?水平分区
?水平分区将一个表分段为多个表,每个表包含相同数目的列和较少的行。例如,可以将一个包含十亿行的表水平分区成 12 个表,每个小表代表特定年份内一个月的数据。任何需要特定月份数据的查询只引用相应月份的表。
?具体如何将表进行水平分区取决于如何分析数据。将表进行分区是为了使查询引用尽可能少的表。否则,查询时须使用过多的 UNION 查询来逻辑合并表,而这会削弱查询性能。有关查询水平分区的表的更多信息,请参见视图使用方案。
?常用的方法是根据时期/使用对数据进行水平分区。例如,一个表可能包含最近五年的数据,但是只定期访问本年度的数据。在这种情况下,可考虑将数据分区成五个表,每个表只包含一年的数据。
?
?垂直分区
?垂直分区将一个表分段为多个表,每个表包含较少的列。垂直分区的两种类型是规范化和行拆分。
?规范化是个标准数据库进程,该进程从表中删除冗余列并将其放到次表中,次表按主键与外键的关系链接到主表。
?行拆分将原始表垂直分成多个只包含较少列的表。拆分的表内的每个逻辑行与其它表内的相同逻辑行匹配。例如,联接每个拆分的表内的第十行将重新创建原始行。
?与水平分区一样,垂直分区使查询得以扫描较少的数据,因此提高查询性能。例如有一个包含七列的表,通常只引用该表的前四列,那么将该表的后三列拆分到一个单独的表中可获得性能收益。
?应谨慎考虑垂直分区操作,因为分析多个分区内的数据需要有联接表的查询,而如果分区非常大将可能影响性能。
?请参见
?使用分区视图
?
?
使用分区视图
?分区视图允许将大型表中的数据拆分成较小的成员表。根据其中一列中的数据值范围,将数据在各个成员表之间进行分区。每个成员表的数据范围都在为分区列指定的 CHECK 约束中定义。然后定义一个视图,以使用 UNION ALL 将选定的成员表组合成单个结果集。引用该视图的 SELECT 语句为分区列指定搜索条件后,查询优化器将使用 CHECK 约束定义确定哪个成员表包含这些行。
?例如,记录 1998 年销售额的 sales 表分区成 12 个成员表,每个月是一个成员表。每个成员表在 OrderMonth 列上都定义了约束:
?CREATE TABLE May1998Sales
????(OrderID???INT??????PRIMARY KEY,
????CustomerID??????INT?????????NOT NULL,
????OrderDate??????DATETIME??????NULL
???????CHECK (DATEPART(yy, OrderDate) = 1998),
????OrderMonth??????INT
???????CHECK (OrderMonth = 5),
????DeliveryDate??????DATETIME??????NULL,
???????CHECK (DATEPART(mm, OrderDate) = OrderMonth)
????)
?填充 May1998Sales 的应用程序必须确保所有行在 OrderMonth 列中均为 5,并且订购日期指定 1998 年 5 月的某个日期。该表上定义的约束强制实现这一要求。
?然后定义一个视图,以使用 UNION ALL 选定全部 12 个成员表中的数据作为单个结果集:
?CREATE VIEW Year1998Sales
?AS
?SELECT * FROM Jan1998Sales
?UNION ALL
?SELECT * FROM Feb1998Sales
?UNION ALL
?SELECT * FROM Mar1998Sales
?UNION ALL
?SELECT * FROM Apr1998Sales
?UNION ALL
?SELECT * FROM May1998Sales
?UNION ALL
?SELECT * FROM Jun1998Sales
?UNION ALL
?SELECT * FROM Jul1998Sales
?UNION ALL
?SELECT * FROM Aug1998Sales
?UNION ALL
?SELECT * FROM Sep1998Sales
?UNION ALL
?SELECT * FROM Oct1998Sales
?UNION ALL
?SELECT * FROM Nov1998Sales
?UNION ALL
?SELECT * FROM Dec1998Sales
?例如,下面的 SELECT 语句查询特定月的信息。
?SELECT *
?FROM Year1998Sales
?WHERE OrderMonth IN (5,6) AND CustomerID = 64892
?SQL Server 查询优化器识别出此 SELECT 语句中的搜索条件只引用 May1998Sales 和 Jun1998Sales 表中的行,从而将其搜索范围限制在这些表上。
?分区视图返回正确的结果并不一定非要 CHECK 约束。但是,如果未定义 CHECK 约束,则查询优化器必须搜索所有表,而不是只搜索符合分区列上的搜索条件的表。如果不使用 CHECK 约束,则视图的操作方式与带有 UNION ALL 的任何其它视图相同。查询优化器不能对存储在不同表中的值作出任何假设,也不能跳过对参与视图定义的表的搜索。
?如果分区视图所引用的所有成员表都在同一服务器上,则该视图是本地分区视图。如果成员表在多台服务器上,则该视图是分布式分区视图。分布式分区视图可用于在一组服务器间分布系统的数据库处理工作量。
?分区视图使独立地维护成员表变得更容易。例如,在某个阶段结束时:
?可以更改当前结果的分区视图定义以添加最新的阶段和除去最早的阶段。
?可以更改以前结果的分区视图定义以添加刚从当前结果视图中除去的阶段。也可以更新以前的结果视图以删除或存档该视图所包含的最早阶段。
?将数据插入到分区视图中后,就可以使用 sp_executesql 系统存储过程创建 INSERT 语句,该语句带有在有许多并发用户的系统中重新使用几率较高的执行计划。
?
创建分区视图
?分区视图在一个或多个服务器间水平连接一组成员表中的分区数据,使数据看起来就象来自一个表。Microsoft® SQL Server™ 2000 区分本地分区视图和分布式分区视图。在本地分区视图中,所有的参与表和视图驻留在同一个 SQL Server 实例上。在分布式分区视图中,至少有一个参与表驻留在不同的(远程)服务器上。此外,SQL Server 2000 还区分可更新的分区视图和作为基础表只读复本的视图。
?分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制使您能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,请参见设计联合数据库服务器。
?在实现分区视图之前,必须先水平分区表。原始表被分成若干个较小的成员表。每个成员表包含与原始表相同数量的列,并且每一列具有与原始表中的相应列同样的特性(如数据类型、大小、排序规则)。如果正在创建分布式分区视图,则每个成员表分别位于不同的成员服务器上。为了获得最大程度的位置透明度,各个成员服务器上的成员数据库的名称应当是相同的,但不要求非这样。例如:Server1.CustomerDB、Server2.CustomerDB、Server3.CustomerDB。
?成员表设计好后,每个表基于键值的范围存储原始表的一块水平区域。键值范围基于分区列中的数据值。每一成员表中的值范围通过分区列上的 CHECK 约束强制,并且范围之间不能重叠。例如,不能使一个表的值范围从 1 到 200000,而另一个表的值范围从 150000 到 300000,因为这样将不清楚哪个表包含 150000 与 200000 之间的值。
?例如,正在将一个 Customer 表分区成三个表。这些表的 CHECK 约束为:
?-- On Server1:
?CREATE TABLE Customer_33
???(CustomerID???INTEGER PRIMARY KEY
?????????????????CHECK (CustomerID BETWEEN 1 AND 32999),
???... -- Additional column definitions)
?-- On Server2:
?CREATE TABLE Customer_66
???(CustomerID???INTEGER PRIMARY KEY
?????????????????CHECK (CustomerID BETWEEN 33000 AND 65999),
???... -- Additional column definitions)
?-- On Server3:
?CREATE TABLE Customer_99
???(CustomerID???INTEGER PRIMARY KEY
?????????????????CHECK (CustomerID BETWEEN 66000 AND 99999),
???... -- Additional column definitions)
?在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。
?生成分布式分区视图的方式如下:
?在每一个含有在其它成员服务器上执行分布式查询所需连接信息的成员服务器上添加链接服务器定义。这将使得分布式分区视图能够访问其它服务器上的数据。
?对于在分布式分区视图中使用的每个链接服务器定义,使用 sp_serveroption 设置 lazy schema validation 选项。这确保了只有在实际需要远程成员表的数据时,查询处理器才请求任何链接表的元数据,从而使性能得到优化。
?在每个成员服务器上创建分布式分区视图。这些视图使用分布式 SELECT 语句访问链接成员服务器上的数据,并将分布式行与本地成员表的行合并。
?若要为上一个示例创建分布式分区视图,应当:
?为 Server2 添加一个名为 Server2 的、带有连接信息的链接服务器定义,并添加一个名为 Server3 的链接服务器定义以访问 Server3。
?创建以下分布式分区视图:
?CREATE VIEW Customers AS
????SELECT * FROM CompanyDatabase.TableOwner.Customers_33
?UNION ALL
????SELECT * FROM Server2.CompanyDatabase.TableOwner.Customers_66
?UNION ALL
????SELECT * FROM Server3.CompanyDatabase.TableOwner.Customers_99
?在 Server2 和 Server3 上执行相同的步骤。
?可更新的分区视图
?如果本地或分布式分区视图为不可更新的,则它只能作为原始表的只读复本。可更新的分区视图可展示出原始表的所有功能。
?在下列情况中,视图被视为可更新的分区视图:
?视图是一组 SELECT 语句,这些语句的结果集通过 UNION ALL 语句组合为一个结果集。每个 SELECT 语句引用一个 SQL Server 基表。该表可以是本地表,也可以是使用 4 部分名称、OPENROWSET 函数或 OPENDATASOURCE 函数引用的链接表(不能使用 OPENDATASOURCE 或 OPENROWSET 函数指定直接传递式查询)。
?表规则
?成员表在视图定义中的每个 SELECT 语句的 FROM 子句中定义。每个成员表都必须遵守如下规则:
?在视图中每个成员表只能引用一次。
?成员表不能有任何计算列上创建的索引。
?成员表在数目相同的列上应具有所有 PRIMARY KEY 约束。
?成员表必须有相同的 ANSI 填充设置。有关 ANSI 填充设置的更多信息,请参见 SET ANSI_PADDING。
?列规则
?列在视图定义中的每个 SELECT 语句的选择列表中定义。列必须遵守如下规则。
?每个成员表中的所有列必须包含在选择列表中。
?在选择列表中不能多次使用同一列。
?在选择列表中对列的引用不能多于一次。
?列必须位于选择列表中的相同序号位置处。
?每个 SELECT 语句的选择列表中的列必须是同一类型(包括数据类型、精度、小数位数和排序规则)。例如,以下视图定义失败,这是因为两个 SELECT 语句中首列的数据类型不同:
?CREATE VIEW NonUpdatable
?AS
?SELECT IntPrimaryKey, IntPartNmbr
?FROM FirstTable
???UNION ALL
?SELECT NumericPrimaryKey, IntPartNmbr
?FROM SecondTable
?分区列规则
?分区列存在于每个成员表上,并且通过 CHECK 约束标识特定表中的可用数据。分区列必须遵守如下规则:
?每个基表都拥有键值由 CHECK 约束所强制的分区列。每个表的 CHECK 约束的键范围与其它任何表互不重叠。任何分区列的给定值必须只能映射到一个表。CHECK 约束只能使用以下运算符:BETWEEN、AND、OR、<、<=、>、>=、=。
?在视图中,分区列必须位于每个 SELECT 语句的选择列表中相同的序号位置处。例如,分区列要么总是每个选择列表中的首列,要么总是每个选择列表中的第二列,依次类推。
?分区列不允许为空。
?分区列必须是表的主键的一部分。
?分区列不能是计算列。
?在分区列上必须仅有一个约束。如果有多于一个的约束,SQL Server 会忽略所有的约束并在确定视图是否为分区视图时不考虑这些约束。
?满足所有上述规则的分区列将支持 SQL Server 2000 查询优化器支持的所有优化。有关更多信息,请参见解析分布式分区视图。
?数据修改规则
?除了为可更新的分区视图定义的规则外,引用该视图的数据修改语句还必须遵守为 INSERT、UPDATE 和 DELETE 语句定义的规则。
?
?说明??只有在安装了 Microsoft SQL Server 2000 企业版或 Microsoft SQL Server 2000 开发版时,才可通过分区视图修改数据。
?INSERT 语句
?INSERT 语句通过分区视图将数据添加到成员表中。INSERT 语句必须遵守下列规则:
?所有列必须包含在 INSERT 语句中,即使基表中的列可能为 NULL 或在基表中定义了 DEFAULT 约束。
?不能在 INSERT 语句的 VALUES 子句中指定 DEFAULT 关键字。
?INSERT 语句提供的值必须符合在一个成员表的分区列上定义的 CHECK 约束逻辑。
?如果一个成员表包含具有标识属性的列,则不能使用 INSERT 语句。
?如果一个成员表包含 timestamp 列,则不能使用 INSERT 语句。
?如果存在具有同一视图或任一成员表的自联接,则不能使用 INSERT 语句。
?UPDATE 语句
?UPDATE 语句通过分区视图在一个或多个成员表中修改数据。UPDATE 语句必须遵守下列规则:
?UPDATE 语句不能在 SET 子句中将 DEFAULT 关键字指定为值,即使列在相应的成员表中定义了 DEFAULT 值。
?不能更改具有标识属性的列的值;不过可以更新其它列。
?如果列中包含 text、image 或 ntext 数据,则不能更改 PRIMARY KEY 的值。
?如果基表中包含 timestamp 列,则不能进行更新。
?如果存在具有同一视图或成员表的自联接,则不能进行更新。
?不能在 UPDATE 语句的 SET 子句中指定 DEFAULT 关键字。
?DELETE 语句
?DELETE 语句通过分区视图在一个或多个成员表中删除数据。DELETE 语句必须遵守如下规则:
?如果存在具有同一视图或任一成员表的自联接,则不能使用 DELETE 语句。
?分布式分区视图规则
?除了为分区视图定义的规则外,分布式(远程)分区视图还有下列附加条件:
?将启动分布式事务以确保更新所影响的所有节点间的原子性。
?XACT_ABORT SET 选项必须设置为 ON。
?远程表中的 smallmoney 和 smalldatetime 列分别映射为 money 和 datetime。因此,本地表中的相应列也应为 money 和 datetime。
?任何链接服务器都不能是环回链接服务器,即指向同一 SQL Server 实例的链接服务器。
?如果视图中含有 INSTEAD OF 触发器,则不遵循上述规则而引用分区表的视图可能仍然是可更新的。但是,查询优化器不能总能够为含有 INSTEAD OF 触发器的视图生成和遵循所有上述规则的分区视图一样有效的执行计划。
几乎可以按天分表,然后使用视图连接起来,查询分为三种,当天查询,所有数据查询,历史数据查询
这么庞大的数据量建议使用oracle、db2这样的数据库
oracle里面额可以做表分区,速度快很多