Home  >  Article  >  Database  >  SQLServer分布式查询

SQLServer分布式查询

WBOY
WBOYOriginal
2016-06-07 15:40:071131browse

MSSQlServer所谓的分布式查询(Distributed Query)是能够访问存放在同一部计算机或不同计算机上的SQL Server或不同种类的数据源, 从概念上来说分布式查询与普通查询区别 它需要连接多个MSSQL服务器也就是具有多了数据源.实现在服务器跨域或跨服务器访问. 而这

  MSSQlServer所谓的分布式查询(Distributed Query)是能够访问存放在同一部计算机或不同计算机上的SQL Server或不同种类的数据源, 从概念上来说分布式查询与普通查询区别 它需要连接多个MSSQL服务器也就是具有多了数据源.实现在服务器跨域或跨服务器访问. 而这些查询是否被使用完全看使用的需要.

  本篇将演示利用SQlExpress链接远程SQlServer来获取数据方式来详细说明分布式查询需要注意细节.先看一下系统架构数据查询基本处理:
SQLServer分布式查询

  当然如果采用了分布式查询 我们系统采取数据DataBase也就可能在多个远程[Remote Server]上访问时:

SQLServer分布式查询

  如上截取系统架构中关于数据与缓存流向中涉及的分布式查询业务, 当我们从客户端Client发起请求数据时. 首先检查MemCache Server缓存服务器是否有我们想要数据. 如果没有我需要查询数据库.  而此时数据要求查询多个远程服务器上多个数据库中表, 这时利用分布式查询.获得数据 然后更新我们在缓存服务器MemCache Server上数据保持数据更新同步, 同时向客户端Client直接返回数据.那如何来执行这一系列动作中最为关键分布式查询?

  分布式查询方式

  我们知道Microsoft微软公用的数据访问的API是OLE_DB, 而对数据库MSSQlServer 2005的分布式查询支持也是OLE_DB方式.SQL Server 用户可以使用分布式查询访问以下内容:

  A:存储在多个 SQL Server 实例中的分布式数据

  B:存储在各种可以使用 OLE DB 访问接口访问的关系和非关系数据源中的异类数据

  OLE DB 访问接口将在称为行集的表格格式对象中公开数据。SQL Server 允许在 Transact-SQL 语句中像引用 SQL Server 表一样引用 OLE DB 访问接口中的行集,[其实不用关心这个行集概念 它的功能类似SQl中临时表 不过它容积更大 能容纳类型更多 更丰富]

  SQL Server 实例的客户机与 OLE DB 访问接口之间的连接 如下图:

SQLServer分布式查询

  从上图可以看出.客户端借助OLEDB接口可以访问Oracle/MS Jet/MS SQL/ODBC/第三方等这些丰富数据源来我们分布式查询提供数据. 说了这么多关于OLEDB底层支持. 关于在MSSQL2005中则支持两种方式来进行分布式查询:

  使用添加链接服务器方式(Add Link Server)

  使用特定名称及特定数据源来直接指定(Add Host Names)

  其实这两种方式在实际运用中是有区别的:

  方式A:Add Link Server方式建立服务器之间关联.创建一个链接的服务器,使其允许对分布式的、针对 OLE DB 数据源的异类查询进行访问. 一般适用于持久的数据操作 对于数据量偏大 服务器之间交付时间长特点.

  方式B: Add Host Name 利用域来唯一识别数据库以及数据库表对象. 来实现跨服务器访问. 这种方式一般比较简单 主要适用于对数据需求临时性查询是使用偏多. 不适合做大批量数据提取. 有性能瓶颈.

  分布式查询实现

  在进行实现分布式查询之前.本次测试Demo对应的SQL版本:

SQLServer分布式查询

  确定SQLServer版本后如下会演示两种方式来实现分布式查询,并对Distributed Query中详细细节进行说明.

  链接服务器查询

  链接服务器配置使 SQL Server 可以对远程服务器上的 OLE DB 数据源执行命令。链接服务器具有以下优点:

  1. 访问远程服务器。
  2. 能够对企业内的异类数据源发出分布式查询、更新、命令和事务。
  3. 能够以相似的方式确定不同的数据源

  下图显示了链接服务器配置的基础:

SQLServer分布式查询

  现在利用链接服务器方式实现数据访问远程服务器数据库CustomerDB中Users表数据先本地添加LinkServer:

<p><span>1</span><span>:  </span><span>--</span><span> 建立连接服务器  第一步建立连接  IP方式来控制</span><span> </span><span><br>   </span><span>2</span><span>:   <br>   </span><span>3</span><span>:  </span><span>EXEC</span><span> sp_addlinkedserver   </span><span>'</span><span>192.168.10.104</span><span>'</span><span> , </span><span>'</span><span>SQL Server</span><span>'</span><span> <br>   </span><span>4</span><span>:   <br>   </span><span>5</span><span>:  </span><span>--</span><span> 查看链接服务器信息  [测试连接成功]</span><span><br></span><span>6</span><span>:   <br>   </span><span>7</span><span>:  </span><span>select</span><span> name , product, provider, data_source, query_timeout, lazy_schema_validation, is_remote_login_enabled, is_rpc_out_enabled <br>   </span><span>8</span><span>:  </span><span>from</span><span> sys.servers <br>   </span><span>9</span><span>:  </span><span>where</span><span> is_linked</span><span>=</span><span>1</span></p>

  如上市建立连接服务器最简单方式.建立链接服务器过程其实调用了系统存储过程Sp_addlinkedserver. 第一个参数为Name 其实用来唯一标识链接服务器. 当然可以其他任何有意义字符串来定义,但我个人建议使用远程服务器的IP来标识.第二个参数是要添加为链接服务器的 OLE DB 数据源的产品名称. 默认为Null,如果指定”SQlServer“则无需指定其他参数.

  如果你的本地装有多个数据库实例. 第一个种方式就不适用.这是就需要用SQl2005架构来唯一标识:

<p><span>1</span><span>:  </span><span>--</span><span> 含架构名  查询数据两种模式</span><span> </span><span><br>   </span><span>3</span><span>:  </span><span>select</span><span>top</span><span>10</span><span>*</span><span>from</span><span>[</span><span>192.168.10.104</span><span>]</span><span>. wl . 架构名 . 表名<br>   </span><span>5</span><span>:  </span><span>--</span><span> 架构名 [采用默认架构名 ]</span><span> </span><span><br>   </span><span>7</span><span>:  </span><span>select</span><span>top</span><span>10</span><span>*</span><span>from</span><span>[</span><span>192.168.10.104</span><span>]</span><span>. CustomerDB . dbo. Users <br></span></p>

  对于Sql2005架构这个概念很多人比较陌生:

  架构是形成单个命名空间的数据库实体的集合。命名空间是一个集合,其中每个元素的名称都是唯一的。 例如,为了避免名称冲突,同一架构中不能有两个同名的表。两个表只有在位于不同的架构中时才可以同名 例如本次Demo 在CustomerDB后对应DBO既是默认的架构名.

  创建后.如果需要修改连接服务器属性可以通过sp_serveroption系统Proc来设置:

<p><span>1</span><span>:  </span><span>--</span><span> 配置链接服务器属性 sp_serveroption为远程服务器和链接服务器设置服务器选项</span><span><br>   </span><span>2</span><span>:  </span><span>--</span><span> 语法  sp_serveroption [@server =] 'server',[@optname =] 'option_name',[@optvalue =] 'option_value'</span><span><br>   </span><span>4</span><span>:  </span><span>exec</span><span> sp_serveroption </span><span>'</span><span>192.168.10.104</span><span>'</span><span>,</span><span>'</span><span>name</span><span>'</span><span>,</span><span>'</span><span>192.168.10.104</span><span>'</span><span> <br>   </span><span>6</span><span>:  </span><span>--</span><span> 查看连接服务器</span><span><br>   </span><span>7</span><span>:  </span><span>select</span><span>*</span><span>from</span><span> sys.servers<br></span></p>

  建立后我就可以直接来查询远程服务器上数据:

<p><span>1</span><span>:  </span><span>--</span><span> 查询远程服务器数据</span><span><br>   </span><span>3</span><span>:  </span><span>select</span><span>*</span><span>from</span><span>[</span><span>192.168.10.104</span><span>]</span><span>.CustomerDB.dbo.Users   </span><span>--</span><span>[成功]</span><span><br>   </span><span>5</span><span>:  </span><span>--</span><span> sp_droplinkedsrvlogin 删除链接服务器登录名映射 [删除登录映射]</span><span><br>   </span><span>6</span><span>:  </span><span>--</span><span> 如果为 NULL,那么将会删除由 sp_addlinkedserver 创建的默认映射 [第二个参数]</span><span><br>   </span><span>8</span><span>:  </span><span>exec</span><span> sp_droplinkedsrvlogin </span><span>'</span><span>192.168.10.104</span><span>'</span><span> ,</span><span>NULL</span><span> <br>  </span><span>10</span><span>:  </span><span>--</span><span> 删除链接服务器属性 [删除服务器]</span><span><br>  </span><span>12</span><span>:  </span><span>exec</span><span> sp_dropserver </span><span>'</span><span>mytest</span><span>'</span><span>--</span><span>[删除成功 同时也删除了Sys_Server信息]</span><span><br>  </span><span>14</span><span>:  </span><span>--</span><span> 查看服务器详细信息</span><span><br>  </span><span>15</span><span>:  </span><span>EXEC</span><span> sp_helpserver<br></span></p>

  查询结果:
SQLServer分布式查询

  测试查询成功.远程数据成功获取.

  当测试完成后我们不需要这个连接服务器是即可利用SP_DroplinkServer删除掉. 对应参数为创建时Name唯一标识. 通过Sp_helpserver来查看连接服务器详细信息.

  注意如上创建连接服务器时设置srvproduct参数即OLED数据源名称时我们采用了SQlServer方式.

  下面说明这种方式特点.:

  这种方式是最为简单直接的一种建立链接服务器方式. 但是存在前提的. 测试发现:

  在所有数据库的远程连接 dbo 的方式必须建立在 SA 密码相同的基础上 ,否则容易产生无法连接的情况 Sa用户登录失败. 你也就明白这个SQlServer参数其实就是在本地数据拷贝服务器角色SysAdmin下用户SA.来对服务器进行登录. 如果你的本地Sa密码与远程服务器上密码不一致 则无法正常连接.

  经过测试还发现一种情况:

  利用Windows7访问XP(Sp2)系统时始终提示无法解析或拒绝连接SQlServer2005.这个问题我整了好久后来才到官方链接参数中发现.:如果你的XP系统没有打上SP4的补丁包 这个问题会始终出现. 需要特别注意.

  直接指定数据源分布式查询

  其实相对第一种方式, 直接指定方式在SQlServer架构中 其实跳过本地与远程服务器建立映射关系的这一步. 通过链接关系建立 其实就是建立一种内部映射关系. 如果没有映射关系则 大部分设置需要手动控制.

  直接指定数据源方式 需要开启分布式查询的基本权限 来进行查询:

<p><span>2</span><span>:  </span><span>--</span><span> 如果想使用分布式查询,必须先开通分布式查询 [外围配置 这点是所有查询操作前提]</span><span><br>   </span><span>3</span><span>:  </span><span>--</span><span> sp_configure--显示或更改当前服务器的全局配置设置</span><span><br>   </span><span>4</span><span>:  </span><span>--</span><span> reconfigure 指定如果配置设置不需要服务器停止并重新启动,则更新当前运行的值</span><span><br>   </span><span>5</span><span>:  </span><span>--</span><span> SQL2005默认是没有开启’Ad Hoc Distributed Queries’ 组件 </span><span><br>   </span><span>6</span><span>:   <br>   </span><span>7</span><span>:  </span><span>--</span><span> 启用权限</span><span><br>   </span><span>8</span><span>:  </span><span>exec</span><span> sp_configure </span><span>'</span><span>show advanced options</span><span>'</span><span>,</span><span>1</span><span>--</span><span> 显示高级配置</span><span><br>   </span><span>9</span><span>:  </span><span>reconfigure</span><span>--</span><span> 更新值</span><span><br>  </span><span>10</span><span>:  </span><span>exec</span><span> sp_configure </span><span>'</span><span>Ad Hoc Distributed Queries</span><span>'</span><span>,</span><span>1</span><span>--</span><span> 启用分布式查询</span><span><br></span><span>11</span><span>:  </span><span>reconfigure</span><span><br>  </span><span>12</span><span>:  </span><span>go</span><span><br>  </span><span>14</span><span>:   <br>  </span><span>15</span><span>:  </span><span>--</span><span> 关闭分布式查询</span><span><br></span><span>16</span><span>:  </span><span>exec</span><span> sp_configure </span><span>'</span><span>Ad Hoc Distributed Queries</span><span>'</span><span>,</span><span>0</span><span>   <br>  </span><span>17</span><span>:  </span><span>reconfigure</span><span><br>  </span><span>18</span><span>:  </span><span>exec</span><span> sp_configure </span><span>'</span><span>show advanced options</span><span>'</span><span>,</span><span>0</span><span><br>  </span><span>19</span><span>:  </span><span>reconfigure</span><span><br>  </span><span>20</span><span>:  </span><span>go</span><span>  <br>  </span><span>23</span><span>:  </span><span>--</span><span> 开启权限后 另外一种查询方式</span><span><br></span><span>24</span><span>:  </span><span>--</span><span> 查询格式</span><span><br></span><span>25</span><span>:  </span><span>SELECT</span><span>*</span><span>FROM</span><span>OPENDATASOURCE</span><span>(<br>  </span><span>26</span><span>:   </span><span>'</span><span>SQLOLEDB</span><span>'</span><span>,<br>  </span><span>27</span><span>:   </span><span>'</span><span>Data Source=远程ip;User ID=sa;Password=密码</span><span>'</span><span><br>  </span><span>28</span><span>:   ).库名.dbo.表名<br>  </span><span>29</span><span>:   </span><span>WHERE</span><span> 条件<br>  </span><span>31</span><span>:  </span><span>--</span><span> 需要开启权限 </span><span><br></span><span>32</span><span>:  </span><span>--</span><span> 开启权限 提示[远程的SqlServer不允许远程连接]</span><span><br></span><span>34</span><span>:  </span><span>select</span><span>*</span><span>from</span><span>OPENDATASOURCE</span><span>(</span><span>'</span><span>SQLOLEDB</span><span>'</span><span>,</span><span>'</span><span>Data Source=192.168.10.67; User ID=sa; Password=chenkai</span><span>'</span><span>).wl.dbo.Users</span></p>

  开启权限后. 需要里利用ReConfig命令来确认.对目前分布式查询权限的修改. 如果在使用完分布式查询后注意关闭.最后查询结果:

SQLServer分布式查询

  测试成功.

  有些人说使用数据库角色SysAdmin角色下的Sa用户进行远程数据传输和验证. 不安全. 其实在使用过程中应该不难看出. 在从远程服务器拉取数据库过程中. 本地数据库需要对权限,创建连接服务器都需要最大用户权限来操作. 而服务器呢, 只需要能连接上 同时对指定数据CustomerDB具有读写的权限即可. 当然你更多远程操作可以把用户赋予CustomerDB的OWner角色.

  这时我们如何用非SA用户来来连接远程用户?

  我们现在远程服务器上对连接创建一个用户名为Test的用户 服务器角色设置Public即可:

SQLServer分布式查询

  在用户角色设置中需要对指定访问数据CustomerDB具有读写权限:

SQLServer分布式查询

  在远程服务器创建TEst用户时使用SQlServer身份验证方式登录 这时设置密码为RemoteDB.在使用非Sa用户进行远程:

<p><span>1</span><span>:  </span><span>--</span><span> 执行前先删除已经存在数据</span><span><br>   </span><span>2</span><span>:  </span><span>Exec</span><span> sp_droplinkedsrvlogin </span><span>[</span><span>192.168.10.76</span><span>]</span><span>,</span><span>Null</span><span><br>   </span><span>3</span><span>:  </span><span>Exec</span><span> sp_dropserver </span><span>'</span><span>demodb</span><span>'</span><span><br>   </span><span>4</span><span>:   <br>   </span><span>5</span><span>:  </span><span>--</span><span> 创建服务器连接</span><span><br></span><span>6</span><span>:  </span><span>EXEC</span><span>  sp_addlinkedserver<br>   </span><span>7</span><span>:        </span><span>@server</span><span>=</span><span>'</span><span>demodb</span><span>'</span><span>,</span><span>--</span><span> 被访问的服务器别名 </span><span><br></span><span>8</span><span>:        </span><span>@srvproduct</span><span>=</span><span>''</span><span>,<br>   </span><span>9</span><span>:        </span><span>@provider</span><span>=</span><span>'</span><span>SQLOLEDB</span><span>'</span><span>,<br>  </span><span>10</span><span>:        </span><span>@datasrc</span><span>=</span><span>'</span><span>192.168.10.76</span><span>'</span><span>--</span><span> 要访问的服务器</span><span><br></span><span>12</span><span>:   <br>  </span><span>13</span><span>:  </span><span>EXEC</span><span> sp_addlinkedsrvlogin <br>  </span><span>14</span><span>:       </span><span>'</span><span>demodb</span><span>'</span><span>, </span><span>--</span><span> 被访问的服务器别名</span><span><br></span><span>15</span><span>:       </span><span>'</span><span>false</span><span>'</span><span>, <br>  </span><span>16</span><span>:       </span><span>NULL</span><span>, <br>  </span><span>17</span><span>:       </span><span>'</span><span>Test</span><span>'</span><span>, </span><span>--</span><span> 帐号</span><span><br></span><span>18</span><span>:       </span><span>'</span><span>RemoteDB</span><span>'</span><span>--</span><span> 密码</span></p>

  如上我们首先清除已经可能创建服务器数据记录. 然后创建服务器连接.sp_addlinkedSrvlogin系统存储过程用来创建链接服务器上远程登录之间的映射 . 即我们可以详细设置本地与远程服务器详细的映射信息. 例如设置我们特定用户访问的用户名和密码.

  查询数据:

<p><span>1</span><span>:  </span><span>--</span><span> 查询指定用户Test数据</span><span><br>   </span><span>2</span><span>:  </span><span>select</span><span>*</span><span>from</span><span>[</span><span>demodb</span><span>]</span><span>.CustomerDB.dbo.Users </span><span>--</span><span> [如上测试成功]</span></p>

  查询结果:

SQLServer分布式查询

  指定用户Test对CustomerDB访问数据方式测试成功.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn