科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航



ZDNet>软件频道>数据库-zhiding>如何利用SQL Server 2005分布式分区视图分解数据表

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

分布式分区视图可以将来自一个或多个SQL Server数据库中的数据连接起来。当开发一个水平分区数据库环境时,你可以使用分布式分区视图将来自不同服务器的分区表连接起来,使得这些数据看起来像来自同一个服务器。

前面的两篇文章中,我们分别介绍了扩大与缩小SQL数据库环境之间的区别以及通过水平数据分区或垂直数据分区分解数据表。在本系列的最后一部分,我们将深入了解如何利用分布式分区视图来分解数据表。

分布式分区视图可以将来自一个或多个SQL Server数据库中的数据连接起来。当开发一个水平分区数据库环境时,你可以使用分布式分区视图将来自不同服务器的分区表连接起来,使得这些数据看起来像来自同一个服务器。

你可以设计这些视图,因此,如果你的潜在数据表结构设计合理的话,查询优化器就可以知道从那个数据表得到查询需要的数据,从而加速运行。一个设计合理的分布式分区视图还可以实现更新、插入和删除。我们将在本文的下一部分深入探讨它是如何实现这样操作的。

示例

本例中,我们假设SalesHistory表非常大,如果水平分割表中的各行记录到不同的服务器上,这将对我们很有利。每个服务器上的SalesHistory表的表结构是一样的,不过,一台服务器上存放该国东部地区的销售信息,而另外一台存放该国西部地区的销售信息。

我们根据Region(地区)字段和SaleID 来区分表中的各条记录。其中SaleID字段是整型数据域,我们为该国不同的地区设定了不同的SaleID。

这个字段对于设计概念来说非常重要,因为这是我们用来作为分区键值字段。(注意:要在缩小场景中进行表的设计,这一点极其重要,因为这样表中的各行是唯一的,从而可区别于其它服务器上的表。)这个字段集合是分区键。

设计很多SaleHistory表,根据所在的表SaleID始终是唯一可区别的。我们可以通过CHECK约束来实现这一点。

我们将使用两个独立的SQL Server实例,对于本例,这两个实例在同一台机器上。服务器的名字叫Chapman,实例分别称为实例A和实例B。这两个实例都是SQL Server 2005开发版,允许远程连接以及Windows和SQL Server认证。

使用脚本创建SalesDB数据库,设置每台服务器的lazy schema validation选项,使用该选项在SQL Server中通过确保在确实需要服务器上的数据时才进行服务器链接请求来提高性能。

列表A中的脚本需要在两个数据库实例上运行。列表B用来创建SalesDB数据库中的读者登录及用户,该脚本也需要在两个数据库实例上运行。

列表C将独自在每台数据库实例上运行。该脚本在每台服务器上创建一个链接到对方的链接服务器。连接服务器允许SQL Server依靠某个OLEDB数据源来执行命令,就像其它的SQL Server。

我们使用上面的脚本中创建的登录作为连接服务器进行连接的安全上下文。这些链接服务器允许我们从一台服务器查询另一台服务器。

列表D的脚本在每台服务器上创建SalesHistory表,并给每个表加载数据。我们为每个表中的SaleID字段创建一个“检查”约束,这个约束用来确保只有确定的SaleID值才能进入SalesHistroy表中。

这个字段将作为我们的分区主键,当我们查询分布式分区视图时,它可以使得查询优化器来决定是从本地表还是远程表中获得数据。

现在需要赋予读者SQL登录的权限,来对SalesHistoty表中的元数据进行插入、更新、删除和浏览等操作。在每台服务器上执行列表E中的脚本即可。

列表F中的脚本在每台服务器上创建分布式分区视图。需要注意的是在服务器A上创建的视图通过查询本地SalesHistory表,然后将结果集聚集到服务器B上的SalesHistoty表中。

优点

使得查询优化器可以很容易的知道使用哪个服务器来查询,在分布式环境中利用分区主键可以大大提高性能。你可以通过查看当你依靠该视图运行查询时的执行计划表来检验一下。

对于需要从远程服务器返回记录的查询,它会返回所有记录,但是当仅用本地数据就可以满足查询时,就根本不需要查询远程服务器。

当你需要插入、更新或删除数据时,又有什么帮助呢?实际上,它以同样的方式给我们提供便利,因为分区键是数据表的主键(至少它总是主键的一部分)。

SQL Server总是知道该在何处插入新记录并且在本地或远程执行相应的动作。这同样适用于更新和删除,SQL Server使用分区键来更新和删除数据,这也是为什么我将本文前面定义的权限赋予用户的原因。

这样,用户就可以在需要的时候对SalesHistory表进行读写。因为该视图存在于每个服务器上,我只要在应用层就可以执行视图上的操作,所以应用层不用知道潜在数据表的结构,只需要关心更新视图就可以。

责任编辑:德东

查看本文国际来源

CREATE DATABASE SalesDB;

EXECUTE sp_serveroption @server = 'CHAPMAN\ServerA,@optname = 'lazy schema validation',@optvalue = 'true'
CREATE LOGIN reader WITH Password = '654asod3e**!!'

USE SalesDB
CREATE USER reader FROM LOGIN reader
ServerA:
EXECUTE sp_addlinkedserver
'CHAPMAN\ServerB',
'SQL Server'

EXEC sp_addlinkedsrvlogin 'CHAPMAN\ServerB',
'false',NULL,'reader','654asod3e**!!'

ServerB:
EXEC sp_addlinkedserver
'CHAPMAN\ServerA',
'SQL Server'

EXEC sp_addlinkedsrvlogin 'CHAPMAN\ServerA', 'false',NULL,'reader','654asod3e**!!'
ServerA:
IF OBJECT_ID('SalesHistory','U') > 0
DROP TABLE SalesHistory
GO
CREATE TABLE SalesHistory
(
SaleID INT PRIMARY KEY,
Product VARCHAR(30) NOT NULL,
SaleDate DATETIME,
SalePrice MONEY,
Region VARCHAR(5) NOT NULL,
CONSTRAINT chk_Region CHECK (SaleID <20000)
)
GO

DECLARE @i SMALLINT, @Region VARCHAR(5)
SET @i = 1
SET @Region = 'West'

WHILE (@i <=6000)
BEGIN
INSERT INTO SalesHistory
(SaleID, Product, SaleDate, SalePrice, Region)
VALUES
(@i, 'Computer', DATEADD(mm, @i, '3/11/1919'), DATEPART(ms, GETDATE()) + (@i + 57), @Region )
SET @i = @i + 1
INSERT INTO SalesHistory
(SaleID, Product, SaleDate, SalePrice, Region)
VALUES
(@i, 'BigScreen', DATEADD(mm, @i, '3/11/1927'), DATEPART(ms, GETDATE()) + (@i + 13), @Region)
SET @i = @i + 1
INSERT INTO SalesHistory
(SaleID, Product, SaleDate, SalePrice, Region)
VALUES
(@i, 'PoolTable', DATEADD(mm, @i, '3/11/1908'), DATEPART(ms, GETDATE()) + (@i + 29), @Region )
SET @i = @i + 1
END

ServerB:
IF OBJECT_ID('SalesHistory','U') > 0
DROP TABLE SalesHistory
GO
CREATE TABLE SalesHistory
(
SaleID INT PRIMARY KEY,
Product VARCHAR(30) NOT NULL,
SaleDate DATETIME,
SalePrice MONEY,
Region VARCHAR(5) NOT NULL,
CONSTRAINT chk_Region CHECK (SaleID >=20000)
)
GO

DECLARE @i SMALLINT, @Region VARCHAR(5)
SET @i = 20000
SET @Region = 'East'

WHILE (@i <=26000)
BEGIN
INSERT INTO SalesHistory
(SaleID, Product, SaleDate, SalePrice, Region)
VALUES
(@i, 'Computer', DATEADD(mm, @i, '3/11/1919'), DATEPART(ms, GETDATE()) + (@i + 57), @Region )
SET @i = @i + 1
INSERT INTO SalesHistory
(SaleID, Product, SaleDate, SalePrice, Region)
VALUES
(@i, 'BigScreen', DATEADD(mm, @i, '3/11/1927'), DATEPART(ms, GETDATE()) + (@i + 13), @Region)
SET @i = @i + 1
INSERT INTO SalesHistory
(SaleID, Product, SaleDate, SalePrice, Region)
VALUES
(@i, 'PoolTable', DATEADD(mm, @i, '3/11/1908'), DATEPART(ms, GETDATE()) + (@i + 29), @Region )
SET @i = @i + 1
END
ServerA:
GRANT SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION ON SalesHistory TO reader ;

ServerB:
GRANT SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION ON SalesHistory TO reader ;
ServerA:
CREATE VIEW dpv_SalesHistory
AS
SELECT
SaleID, Product, Region, SaleDate, SalePrice
FROM SalesDB.dbo.SalesHistory
UNION ALL
SELECT
SaleID, Product, Region, SaleDate, SalePrice
FROM ServerB.SalesDB.dbo.SalesHistory

ServerB:
CREATE VIEW dpv_SalesHistory
AS
SELECT
SaleID, Product, Region, SaleDate, SalePrice
FROM SalesDB.dbo.SalesHistory
UNION ALL
SELECT
SaleID, Product, Region, SaleDate, SalePrice
FROM ServerA.SalesDB.dbo.SalesHistory
推广二维码
邮件订阅

如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

重磅专题