 TechNet Magazine April 2008

TechNet Magazine April 2008

SQL Server 2008: 新增功能

新版的 SQL Server 提供了众多的新功能和增强功能，不但改进了性能、提高了安全性，还承诺可以使数据库管理员的工作更加轻松。本文将概述一些主要变更以及 SQL Server 2008 提供的一些新功能。

Randy Dyess SQL Server 2008: 安全性

安全性一直都是 SQL Server 致力改善的一个领域。通过研究 SQL Server 2008 中一些最重要的安全性更改，您会发现：无论是加密和身份验证增强功能还是基于策略的管理以及新的审核系统，它们均有助于满足法规要求。

Rick Byham SQL Server 2008: 新数据类型

SQL Server 2008 提供有七种新的内置数据类型，可利用它们来处理更复杂的数据并简化对结构化、半结构化甚至非结构化数据的管理。让我们深入了解这些新数据类型并掌握如何利用它们来改进您基础结构中的数据管理。

Kelly Wilson SQL Server 2008: 数据仓库查询性能

SQL Server 2008 提供了功能更为强大的关系数据仓库。让我们来仔细研究一下与性能相关的关键数据仓库功能，并了解可如何充分利用这些新技术来优化查询性能。

S. Agarwal, T. Grabs, and J. Hammer SQL Server: 最大程度降低 SQL Server 中的阻塞

尽管锁定对支持数据库的并发读写活动至关重要，但阻塞却会对系统性能产生负面影响。学习如何优化 SQL Server 数据库以最大程度降低阻塞，并弄清如何才能对系统进行监视以更好地了解锁定如何对性能产生影响。

Cherié Warren Microsoft Office: Access 数据库与 Sharepoint 集成

Microsoft Access 目前仍是许多企业广为使用的重要软件。而 Microsoft Office SharePoint Server 2007 让您可以轻松集成原有的 Access 数据。我们将为您介绍如何使用这些工具为公司构建新的解决方案。

Peter Serzo 编辑寄语: 致新老朋友

Joshua Hoffman 读者来信: 读者心声

工具箱: 面向 IT 专业人员的新产品

Greg Steen SQL 问题与解答: 数据库增长、使用 IFilter 和远程连接

了解如何以编程方式增长数据库，学习如何使用 IFilter，并探究支持远程 SQL Server 连接的防火墙设置。

Edited by Matthew Graven 实用程序特别推荐: Web 能力分析工具

Web 日志和流量分析能够使您清楚预见会出现何种流量。但如何才能确定您的基础结构能够处理多少流量呢？免费的 Web 能力分析工具可以帮助您查看自己系统的承载量。

Greg Steen 网络专家: NAP 强制故障排除

对网络访问保护平台中的强制行为进行故障排除极具挑战性。网络专家为您解释 NAP 运行状况策略评估的工作原理，以及排除最常见故障的方法。

Joseph Davies Windows PowerShell: 请在此处签名

AllSigned 执行策略提供了最安全的 Windows PowerShell 环境。那么，如何对 Windows PowerShell 脚本进行签名呢？Don Jones 将向您传授此道。

Don Jones 您好，脚本专家！: 再述数据库脚本

数据库可能会存储贵公司最重要的信息。本月，脚本专家将展示如何利用 VBScript 快速读取数据库的信息、添加或删除记录，甚至仅利用几行代码完成更新。

The Microsoft Scripting Guys 安全观察: 我的个人身份信息 (PII) 在哪里？

在您能够有效地保护个人身份信息之前，您必须了解这些信息在 PC 中的存储位置。本文将介绍如何编写脚本来查找存储在计算机上的个人数据。您可能会为使用这些脚本所发现的信息感到惊讶。

Frank Simorjay 桌面文件: 使用 WAIK 部署 Windows XP

Windows 自动安装工具包主要用于 Windows Vista 和 Windows Server 2008。但是，您是否知道它也可以帮助部署 Windows XP 和 Windows Server 2003？为此，您需要了解以下内容。

Wes Miller 领域备注: 绝妙计划

让我们来了解在翻新旧的 PC 时，Microsoft Authorized Refurbisher (MAR) 如何帮助公司处理令其头疼的软件许可问题。

Neil Fawcett Windows 机密: 平均分配

“您确定要删除此共享文件？”Raymond Chen 解释了在删除程序时，卸载程序为什么可能会询问此问题。

Raymond Chen


 SQL Server 2008: 新增功能
SQL Server 2008 Randy Dyess

新增功能
概览:
  • 更强大的管理功能
  • 改进的性能和可伸缩性
  • 更好的安全性和可用性
  • 涉及开发人员的变更

Microsoft 再次发布了新版 SQL Server，它承诺可以使数据库管理员的工作更加轻松。最新版本是 SQL Server 2008，它提供了众多的新
特性和功能，可为管理工作带来一系列的好处。
对于那些曾使用过 SQL Server® 2005 的数据库管理员来说，他们会在新版本中找到日常经常用到的许多相同功能，但是他们会很快发现这些熟悉的工具在 SQL Server 2008 中都得到了增强。在现有功能基础上建立的新功能极大地减少了在复杂的数据库环境中使用各种功能所需的解决方法或自定义方法的数量。
SQL Server 2008 中的新功能涉及了大量的数据库工作角色，因此很难对其进行分类。当我阐述分属不同主题的功能时，我知道有些读者对我为什么将明显属于类别 Z 的功能 X 归入到类别 Y 中感到奇怪。这是角度的问题，并且受到公司业务开展方式的影响。
我知道数据库用户经常发现自己扮演许多不同的工作角色，我会尽量将这些新功能分解，以使其尽可能适合以下常见类别：管理、可伸缩性、性能、高可用性、安全性、开发以及商业智能。

用于管理的新功能有哪些？
对于数据库管理员（比如我）来说，附加的众多管理功能使 SQL Server 2008 成为一种令人激动的新产品。对于经常要负责管理分布在数十台甚至数百台服务器中的数以百计或千计的大型复杂数据库环境的数据库管理员而言，新的策略管理、多服务器查询功能、配置服务器以及数据收集器/管理仓库功能为他们赋予了强大的能力。
SQL Server 2008 策略管理功能（它实际上在社区技术预览 (CTP) 中被称作宣告管理框架）允许您为一台或多台数据库服务器创建和执行配置策略。利用这些策略，您可以确保每台目标服务器和数据库都应用和维持标准配置设置。在图 1 中可以看到此功能的一个示例。
Figure 1 数据和日志文件位置最佳实践策略
Figure 1 数据和日志文件位置最佳实践策略
策略是通过一组预定义的层面创建的。每个层面都包含一个 SQL Server 2008 配置设置的子组以及您可以控制的其他事件。将这些层面和条件相匹配即可创建策略。条件是指能够为层面属性所接受的值、配置设置或该层面中包含的其他事件。
条件还指用于策略筛选器的值。现在假设您希望仅针对某个特定数据库执行策略。在这种情况下，您可以创建一个包含该数据库名称的条件，然后将此条件添加到策略中。现在这一策略将仅会应用到此数据库。在这方面请相信我—SQL Server 2008 策略管理可能听起来很复杂，但在实际尝试后，您会发现它非常直观。
当您需要同时对多台服务器执行查询时，可使用新增的多服务器交互和配置服务器功能。您可在 Management Studio 中注册服务器，然后将这些服务器一同放在某个分组下面。当需要对分组中的所有服务器执行策略或查询时，只需右键单击该分组即可。
作为一项附加优点，您可以对此功能进行配置，以便每台服务器返回一个结果集或将所有结果集合并到一个大结果集中。您还可以指定是否希望将服务器和数据库名称作为结果的一部分，以便能够使各服务器的结果分离出来。能够在配置服务器上而非在每个单独的 Management Studio 中存储注册的服务器，这是一个很大的优势。
另一项不错的新管理功能是数据收集器。数据库管理员经常需要从大量的服务器中收集管理数据，许多 DBA 已经为此类操作创建了自己的自定义解决方案。数据收集器是一种内置机制，它有利于收集与管理相关的数据。它允许您使用 SQL Server 代理和 SQL Server Integration Services (SSIS) 创建一种框架，在收集和存储数据的同时，提供错误处理、审计和收集历史记录功能。
与第三方工具和自定义作业不同，数据收集器非常容易被大多数数据库管理员所理解，因为它使用 SQL Server 代理和 SSIS 创建一组作业和软件包，并使用它们来处理连接、收集以及数据存储（如图 2 中所示）。此数据存储到中心位置后，即可将其作为管理仓库加以引用，可通过一组 T-SQL 语句和 SQL Server 2008 Reporting Services 报告进行查看和组织。这种中心数据存储方式使分析和查看数据库环境的总体管理度量标准更加轻松。
Figure 2 数据收集器磁盘使用情况日志文件
Figure 2 数据收集器磁盘使用情况日志文件

用于可伸缩性的新功能有哪些？
近年来，SQL Server 数据库管理员发现他们的数据库环境变得越来越大。随着数据库环境的增大，您需要采用一些新的方法和工具来实现大多数企业所需的可伸缩性。SQL Server 2008 推出了多种新功能，可在这些方面提供帮助。
SQL Server 2008 拥有内置的压缩功能，允许您压缩数据库文件以及与相应的数据库相关的事务日志文件。SQL Server 2005 引入了压缩只读文件或文件组中的数据的能力，但这种压缩形式只是使用了 Windows® NTFS 的压缩能力。在 SQL Server 2008 中，您可以进行行级和页级压缩，这在数据文件级压缩方面具有前所未有的优势。
行级和页级压缩可减少所需的数据空间量，此外它还可以减少所需的内存量，因为数据在内存中始终保持压缩状态。内存中压缩的数据使内存利用率得到提高，这让许多系统在提高可伸缩性方面受益匪浅。
SQL Server 2008 还推出了备份级压缩。尽管数据库备份仅备份数据库的活动部分，但这仍可能是多达数百 GB 甚至数十 TB 字节的数据量。如果数据库环境存有数 TB 字节的备份文件的多个副本，则这些备份文件通常会占用宝贵的存储空间，而这些空间本来可以得到更有效的利用。在 SQL Server 2008 中，数据库管理员可以压缩其备份文件，从而释放部分此类空间，使其能够用于实时数据。
此外还有资源管理器。这种新功能允许您定义资源的数量，供单独的或成组的工作负载在执行过程中使用。利用资源管理器可以创建一种环境，在这种环境中许多不同的工作负载在一台服务器中共存，而不必担心其中的一个或多个工作负载会使服务器超负荷并致使其他工作负载的性能受到影响。
这种功能的优势在于您可以更有效地使用数据库服务器中可用的资源总量。图 3 显示的是使用资源管理器来限制服务器上的活动的示例。
Figure 3 Limit activity with the Resource Governor (Close Figure 3)
USE master
go

--Drop function
IF OBJECT_ID('rgclassifier_demo','Function') IS NOT NULL
DROP FUNCTION rgclassifier_demo
go

--Create a classifier function for report group
CREATE FUNCTION rgclassifier_demo() RETURNS SYSNAME
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @group_name AS SYSNAME
  IF (USER_NAME() LIKE '%Launch_Demo%')
         SET @group_name = 'demogroup'
    RETURN @group_name
END
GO

--Drop workload group for anything coming from Management Studio
IF EXISTS (SELECT name FROM sys.resource_governor_workload_groups
  WHERE name = 'demogroup')
BEGIN
  DROP WORKLOAD GROUP demogroup
END
GO

--Create workload group
CREATE WORKLOAD GROUP demogroup
GO

--Register the classifier function with
--Resource Governor
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION= dbo.rgclassifier_demo)
GO

--Alter the dbogroup workload group to only
--allow 10% of CPU for each workload request
ALTER WORKLOAD GROUP demogroup
WITH (REQUEST_MAX_CPU_TIME_SEC = 10)
GO

--Create a new resource pool and set a maximum CPU limit for all workloads.
IF EXISTS (SELECT name FROM sys.resource_governor_resource_pools
  WHERE name = 'pooldemo')
DROP RESOURCE POOL pooldemo
GO

CREATE RESOURCE POOL pooldemo
WITH (MAX_CPU_PERCENT = 40)
GO

--Configure the workload group so it uses the
--new resource pool.
ALTER WORKLOAD GROUP demogroup
USING pooldemo
GO

--Apply the changes to the Resource Governor
--in-memory configuration.
ALTER RESOURCE GOVERNOR RECONFIGURE
GO

用于性能的新功能有哪些？
在 SQL Server 2008 中，数据库的一般性能得到了改进。借助 SQL Server 2008 中的几种新功能，您现在不但可以控制和监视数据库的性能，还可以控制和监视那些依靠这些数据库来执行的应用程序的性能。
如果每秒钟要执行大量的事务处理，则在事务处理期间通常会发生的锁定现象将对数据库应用程序的性能造成负面影响。SQL Server 的设计旨在通过将锁从较小的行级和页级锁升级到较大的表级锁，来减少某个进程持有的锁总数。但是请务必要清楚，这种锁升级可能会导致问题。例如，一个单独的事务处理可能会锁定整个表，致使其他事务处理无法使用该表。
SQL Server 2008 采用了表分区机制（在 SQL Server 2005 中就已引入），允许 SQL Server 引擎在将锁升级到表级之前先升级到分区级。这种中间级别的锁定可显著降低锁升级对每秒处理成百上千个事务的系统的影响。
在处理查询与已分区表的交互操作时，SQL Server 2008 提供了多种新的查询处理器改进功能。查询优化器现在可以针对分区执行查询搜索，就像针对单独的索引执行一样，因为它仅使用分区 ID，而不是表级的分区机制。

用于高可用性的新功能有哪些？
随着数据库环境变得越来越复杂而数据库变得越来越大，确保这些数据库的可用性也就变得越来越困难。SQL Server 2008 中仍然保留了您在过去一直使用的用于实现高可用性的熟悉机制。但是其中有些功能在 SQL Server 2008 中得到了增强，此外还添加了一些新功能。
在 SQL Server 2005 中，许多管理员通过执行数据库镜像来实现高可用性。SQL Server 2008 为数据库镜像方法提供了许多改进功能。例如，过去在将事务日志数据从主体数据库移动到镜像数据库时，数据库镜像有时会出现性能问题。为了解决这一问题，SQL Server 2008 会在将信息发送到镜像事务日志进行强化前先压缩信息，以减少从主体事务日志跨网络移动到镜像事务日志的信息量。
您现在可以修复主体数据库中损坏的数据页面。如果主体数据库由于错误 823 和 824 而出现损坏的数据页面，主体可以从镜像服务器请求这些数据页面的最新副本。这种对正确数据页面的请求是一种自动过程，对当前访问主体数据库的任何用户而言都是透明的。
“热插 CPU”是另一项新功能，它允许您在不影响服务器上驻留的数据库可用性的情况下，在数据库服务器中插入额外的 CPU。但是必须要清楚，热插 CPU 有一些限制，比如它只能用在运行 64 位基于 Itanium 的 Windows Server® 2008 Enterprise Edition 或 Datacenter Edition 的服务器中，并且需要 SQL Server 2008 的 Enterprise Edition 版本。

用于安全性的新功能有哪些？
SQL Server 2005 引入了采用数据加密形式的数据安全性。SQL Server 2008 在加密方面有了极大的增强，这是由于引入了下面两种功能：可扩展密钥管理和透明数据加密。
可扩展密钥管理提供了一种增强的结构，可以安全存储在加密基础结构中使用的密钥—不仅是在数据库自身中，还可以在第三方软件模块或带有硬件安全模块的数据库以外。
透明数据加密可以为加密数据提供更高的灵活性，因为对其而言加密是数据库的一个属性，而非仅仅是代码行中的函数结果。这样在数据级执行加密时，管理员就无需对其数据库结构和应用程序代码进行大量的改动。图 4 中的代码显示的是如何使用透明数据加密方法来加密数据库。
Figure 4 Using Transparent Data Encryption (Close Figure 4)
USE master;
GO

--Create a master key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YouWillNeedToCreateAStrongPassword';
GO

--Create a certificate to use with TDE
CREATE CERTIFICATE TDECERT WITH SUBJECT = 'TDECert'
GO

--Change to the database to encrypt
USE AdventureWorks
GO

--Create your database master key
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128 --Use a strong algorithm
ENCRYPTION BY SERVER CERTIFICATE TDECERT
GO

--Alter the database to encrypt it with the
--master database key
ALTER DATABASE AdventureWorks
SET ENCRYPTION ON
GO

开发人员策略的改变有哪些？
从 SQL Server 2008 的改进中直接受益的不仅只有数据库管理员。对于数据库开发人员，新版本也为他们提供了大量的新功能。从多种全新的 T-SQL 增强功能到可以帮助开发人员创建和利用数据库查询的新组件，不一而足。
许多数据库开发人员负责创建的查询需要用来返回其应用程序所需的数据。您可能熟悉 LINQ（语言集成查询）工具，它允许数据库开发人员使用基于 Microsoft® .NET 的编程语言而非普通的 T-SQL 语句向数据库发出查询请求。SQL Server 2008 向 SQL 提供程序提供了新的 LINQ 命令，可以允许开发人员直接对 SQL Server 表和列发出 LINQ 命令，从而增强了 LINQ 的功能。这将缩短创建新数据查询所需的时间。
对数据库进行开发时，开发人员会使用较高级别对象，将其映射到单独的数据库表和列。这些对象（也称为实体）代表数据库应用程序所需的数据，因此开发人员并不需要了解该数据的实际存储结构以及数据库的架构。新的 ADO.NET 实体框架现在允许开发人员使用这些实体来创建数据库查询。底层数据库结构的抽象化可极大地提高开发人员的生产率。
SQL Server 2008 为 T-SQL 提供了许多不同的增强功能，可以提高数据库开发人员的效率。新的 MERGE 语句就是一个例子，它允许开发人员在试图插入数据前先检查该数据是否存在。执行 INSERT 语句之前所做的这项检查允许数据进行更新。现在不再需要创建复杂的连接来更新已存在的数据并插入不存在的数据，所有这些都可以在一个单独的语句中完成。
此外，从合并的日期/时间数据类型中分离时间和日期数据也变得更加简单。SQL Server 2008 引入了两种独立的数据类型来处理日期和时间数据。不同数据类型的转换可以改进许多查询的性能，因为无需对数据执行任何操作即可将其用于查询。
创建较新的数据库结构时，数据库开发人员经常会发现他们必须要扩展数据库的结构才能执行映射应用程序。SQL Server 2008 使用全新的空间数据类型来帮助解决此问题。GEOGRAPHY 和 GEOMETRY 这两种空间数据类型允许开发人员将位置特定的数据直接存储到数据库中，而无需将这些数据元素细分为适合其他标准数据类型的格式。图 5 中的代码是一个简单的空间表的示例。
Figure 5 A simple spatial table (Close Figure 5)
IF OBJECT_ID ( 'Demo_SpatialTable', 'Table' ) IS NOT NULL
    DROP TABLE Demo_SpatialTable
GO

--Create table to hold spatial data
CREATE TABLE Demo_SpatialTable
    ( SpatialID int IDENTITY (1,1),
    SpatialInputCol geography,
    SpatialOutputCol AS SpatialInputCol.STAsText() )
GO

--Insert data into table
INSERT INTO Demo_SpatialTable (SpatialInputCol)
VALUES (geography::STGeomFromText('LINESTRING(47.656 -122.360, 47.656 -122.343)', 4326));

INSERT INTO Demo_SpatialTable (SpatialInputCol)
VALUES (geography::STGeomFromText('POLYGON((47.653 -122.358, 47.649 -122.348, 47.658 -122.348, 47.658 -122.358, 47.653 -122.358))', 4326));
GO

--View data to see that data has been converted and stored in col2
SELECT * FROM Demo_SpatialTable
过去，数据库开发人员经常会遇到如何存储及利用大型二进制对象（例如文档和介质文件）的问题。常用的方法是将文件存储在数据库以外，而只在数据库中存储一个到外部文件的指针。但是使用这种方法时，在移动文件时必须要记得同时更新指针。
SQL Server 2008 使用新的 FILESTREAM 数据类型来解决此问题。使用这种数据类型，文件仍可以存储在数据库以外，但是数据被视为数据库的一部分从而实现事务的一致性。这将允许使用常规的文件操作方法，同时保持数据库在性能和安全方面的优势。

什么是业务智能？
过去几年 SQL Server 使用量增加的原因主要是由于采纳了业务智能策略。业务智能功能对于 SQL Server 而言并不新鲜，但 SQL Server 2008 为其赋予了一些新的内涵。
例如，当数据在数据仓库中存储时，经常会由于 NULL 值的存在而浪费空间。存储 NULL 值的列占据着列中定义的最大允许数据大小的空间。也就是说，如果某列有数千个 NULL 值，它实际上会占用许多 MB 的空间而不存储任何数据。
SQL Server 2008 引入了稀疏列的概念，允许存储的 NULL 不占用磁盘上的任何物理空间。因为稀疏列不消耗实际空间，因此包含稀疏列的表可以不受 1,024 列的限制。
SQL Server 2008 还引入了“变更数据捕获”这种新机制，用于管理那些需要载入到数据仓库中的增量变更。它捕获变更的数据并将其放入一组变更表中。相对于建立自定义插入语句、然后在更新数据仓库前千方百计弄清对现有数据行所做变更的方法而言，在容易消耗的存储架构中捕获更新、删除和插入的数据可允许这些表通过增量方式载入数据仓库。

结束语
以上只是对 SQL Server 2008 内容的简单概述。SQL Server 2008 不但引入了众多新功能，还对许多现有功能进行了更新，可使数据库管理员和数据库开发人员的工作更加轻松。总而言之，对于当今需求时刻都在变化的数据库而言，它可以提供更出色的性能和可伸缩性。

Randy Dyess 是 Solid Quality Mentors 的顾问。他对 SQL Server OLTP 系统十分精通。Randy 是《TransactSQL Language Reference Guide》 的作者、《MCTS Self-Paced Training Kit:Microsoft SQL Server 2005 Implementation and Maintenance》(Exam 70-431) 的合著者，此外他还为各种杂志和报刊撰写过很多文章。Randy 是北得克萨斯 SQL Server 用户组织的程序主管，他还是一位 SQL Server MVP。请通过 blogs.solidq.com/EN/rdyess/default.aspx 访问他的博客。
© 2007 Microsoft Corporation 与 CMP Media, LLC.保留所有权利；不得对全文或部分内容进行复制.


 SQL Server 2008: 安全性
SQL Server 2008 Rick Byham

安全性
概览:
  • 加密增强功能
  • 身份验证增强功能
  • 安全审核
  • 基于策略的管理

SQL Server 2008 提供了许多旨在改善数据库环境的总体安全性的增强功能和新功能。它增加了密钥加密和身份验证功能，并引入了新的审核系统，以
帮助您报告用户行为并满足法规要求。
在本文中，我将向您简要介绍 SQL Server® 2008 的存储安全性方面的最重要变化。您首先可能会注意到的是已不再提供 SQL Server 2005 外围应用配置器工具。外围应用配置器工具所提供的协议选项现由配置管理器工具提供。但是，现在是使用新的 SQL Server 2008 基于策略的管理框架来执行启用和禁用功能。

加密增强功能
在加密方面有两个主要改进。第一，SQL Server 现在可以使用存储在外部第三方硬件安全模块上的加密密钥。第二，对于存储在 SQL Server 中的数据，可采用对连接到该数据库的应用程序透明的方法来对其进行加密。即意味着数据库管理员可轻松地对整个数据库中存储的所有数据进行加密，而不必修改现有的应用程序代码。
第一个改进是通过新的可扩展密钥管理 (EKM) 功能来实现的，在 SQL Server 2008 Enterprise、Developer 和 Evaluation 版本中提供有该功能。EKM 使企业密钥管理和硬件安全模块 (HSM) 解决方案的第三方供应商可在 SQL Server 中注册其设备。一旦注册了这些设备，用户便可使用这些模块中存储的加密密钥。
此类供应商甚至还可在这些模块中提供高级加密功能（如密钥老化和密钥轮换）。在某些配置中，它允许使用并非系统管理员组成员的数据库管理员所提供的数据保护。随后，T-SQL 加密语句可使用存储在外部 EKM 设备上的密钥来加密和解密数据。
另一新功能是透明数据加密，它允许您在不必更改任何应用程序的情况下加密数据库文件。它可对数据和日志文件执行实时 I/O 加密和解密。加密所使用的数据库加密密钥 (DEK) 存储在数据库引导记录中，以便在恢复时仍可使用。DEK 的安全则由存储在服务器主数据库中的一个证书来保证。图 1 中的图表显示了实现透明数据加密的体系结构。
Figure 1 透明数据加密的体系结构
Figure 1 透明数据加密的体系结构
它对于保护空闲数据非常有用。尽管可使用多种防范措施来帮助保护数据库的安全（如加密机密资产和为数据库服务器安装防火墙），但存储数据库的物理介质（甚至备份磁带）还是有其他漏洞。恶意用户可盗取该介质，并且有可能访问到介质中存储的数据。
但是，透明数据加密可加密数据库中的敏感数据，并且使用证书来保护用于加密数据的密钥。它可帮助您的组织遵循与正确保护数据相关的众多法律、法规和行业准则。
透明数据加密允许软件开发人员使用高级加密标准 (AES) 和三重数据加密标准 (3DES) 加密算法来加密数据。数据库文件的加密是在页面级执行的，在写入磁盘之前加密页面，然后在读入内存时进行解密。对于启用了透明数据加密的数据库备份文件，也使用数据库加密密钥进行了加密。
要恢复已加密的数据库，您必须有权访问用于加密数据库的证书或非对称密钥。如果没有证书或非对称密钥，您将无法恢复数据库。因此，请务必保留访问相关备份所需的任意密钥。

身份验证增强功能
您可能知道，Kerberos 是一种网络身份验证协议，用于为网络中的客户端和服务器实体（或安全主体）进行相互验证提供一种高度安全的方法。Kerberos 可帮助用户减少安全漏洞（如引诱攻击和中间人攻击。与 Windows® NTLM 身份验证相比，Kerberos 更安全、更可靠，并且提供更好的性能。
要使用 Kerberos 对连接进行相互身份验证，必须在 Active Directory® 中注册 SQL Server 实例的服务主体名称 (SPN)，并且客户端驱动程序必须在连接时提供已注册的 SPN。在 SQL Server 2008 中，Kerberos 身份验证已扩展到所有网络协议，包括 TCP、命名管道、共享内存和虚拟接口适配器 (VIA)。默认情况下，客户端驱动程序会自动推断出所连接 SQL Server 实例的正确 SPN。还可在连接字符串参数中显式指定 SPN，以提供更好的安全性、控制和故障排除功能。
Internet 信息服务 (IIS) 不再提供对 ASP.NET、报表管理器或报表服务器 Web 服务的访问。在 SQL Server 2008 中，报告服务通过新的身份验证子系统来处理所有的身份验证请求，该子系统支持基于 Windows 的身份验证和自定义身份验证。
报告服务现在包含内置到 SQL Server 公共语言运行库 (CLR) 中的 Microsoft® .NET Framework 和 ASP.NET 技术，并且报告服务还可以使用操作系统的 HTTP.SYS 功能。报表服务器包括一个 HTTP 侦听程序，以接受定向到在服务器配置过程中所定义的 URL 和端口处的请求。URL 保留和注册现由报表服务器通过 HTTP.SYS 直接管理。

安全审核
SQL Server Audit 是一项新功能，可通过它来创建自定义的数据库引擎事件审核。该功能使用扩展事件来记录审核信息，并且提供在各种服务器和数据库对象上启用、存储和查看审核所需的工具和过程。
SQL Server Audit 还比 SQL Server Trace 更快，并且 SQL Server Management Studio 使审核日志的创建和监控变得简单。现在，审核级别更加精细，甚至可以捕获单个用户的 SELECT、INSERT、UPDATE、DELETE、REFERENCES 和 EXECUTE 语句。另外，SQL Server Audit 可通过 T-SQL 语句 CREATE SERVER AUDIT 和 CREATE SERVER AUDIT SPECIFICATION 以及相关的 ALTER 和 DROP 语句来实现完全脚本化。
要建立审核，需创建审核并指定记录所审核事件的位置。审核可保存到 Windows 安全日志、Windows 应用程序日志或指定位置的文件中。为审核命名并配置其特征（如审核文件的路径和最大大小）。还可选择在审核失败时关闭 SQL Server。如果需将所审核事件记录到多个位置，只需创建多个审核即可。
下一步是创建一个或多个审核规范。服务器审核规范收集有关 SQL Server 实例的信息，并且包括服务器范围内的对象（如登录和服务器角色成员身份）。它还包括在主数据库中管理的数据库信息（如数据库访问权限）。在定义审核规范时，需指定由哪个审核来接收监控事件。可定义多个服务器审核和多个服务器审核规范，但每个服务器审核每次仅可包含一个已启用的服务器审核规范。
也可创建用于监控单个数据库中事件的数据库审核规范。可向一个审核添加多个数据库审核规范，但一个服务器审核一次仅可为每个数据库启用一个数据库审核规范。
用于服务器审核规范的 SQL Server 审核操作事件被分组到相关审核操作事件集合中。它们以审核操作组形式公开。当把某个组添加到审核规范时，您将监控到该组中包含的所有事件。例如，有一个名为 DBCC_GROUP 的审核操作组，它使用 DBCC 命令。但是，无法单独审核 DBCC 命令。
服务器可用的审核操作组有 35 个，其中一些组又彼此密切相关。例如，有 SUCCESSFUL_LOGIN_GROUP、FAILED_LOGIN_GROUP 和 LOGOUT_GROUP。还有一个 AUDIT_ CHANGE_GROUP，包含可用于对审核过程进行审核的审核操作类型。
数据库审核规范也可指定收集到数据库级别审核操作组中的审核操作事件组。除审核操作组外，数据库审核规范还可包括对审核数据操作语言语句进行审核的单独审核操作事件。可将这些事件配置为监控整个数据库，或仅监控特定数据库对象。例如，SELECT 审核操作可用于审核对单个表或整个架构的 SELECT 查询。也可将这些事件配置为监控特定用户或角色（如所有 db_writer）的操作。
例如，可使用 SELECT 审核操作来审核用户 Mary 或 FINANCE_DEPT 数据库角色或公共数据库角色对单个表的 SELECT 查询。很明显，它在创建所需审核方面提供了极大的控制功能和灵活性。

依赖关系报告
依赖关系报告有所改进，包括有新的目录视图和新的系统功能。如果使用 sys.sql_expression_dependencies、sys.dm_sql_referencing_entities 和 sys.dm_sql_referenced_entities，可针对架构绑定对象和非架构绑定对象的服务器之间、数据库之间以及数据库 SQL 依赖关系提供报告。

新的数据库角色
msdb 数据库中包含的数据库角色发生了一些变化。db_dtsadmin 角色已重命名为 db_ssisadmin，db_dtsltduser 角色已重命名为 db_ssisltduser，并且 db_dtsoperator 角色已重命名为 db_ssisoperator。为支持向后兼容性，在服务器升级时，将把原来的角色添加为新角色的成员。
除这些更改外，还添加了新的数据库角色来支持 SQL Server 2008 的新功能。特别地，msdb 数据库包含用于服务器组的新角色（ServerGroupAdministratorRole 和 ServerGroupReaderRole）、用于基于策略的管理的新角色 (PolicyAdministratorRole) 和用于数据收集器的新角色（dc_admin、dc_operator 和 dc_proxy）。并且，管理数据仓库数据库也包含用于数据收集器的新角色（mdw_admin、mdw_writer 和 mdw_reader）。

FILESTREAM 安全性
现在，SQL Server 支持 FILESTREAM 存储，因而 SQL Server 应用程序可在文件系统中存储非结构化数据（如文档和图像）。反过来，它意味着客户端应用程序可从文件系统的流式 API 和性能获益，同时仍维持非结构化数据和对应结构化数据之间的事务一致性。
FILESTREAM 数据必须存储在 FILESTREAM 文件组中 — 它是包含文件系统目录而非实际文件的特殊文件组。这些称为数据容器的目录提供数据库引擎存储和文件系统存储之间的接口。
从安全性方面看，FILESTREAM 数据与所有其他数据的安全性相同 — 在表级别或列级别授予权限。授予对 FILESTREAM 容器的 NTFS 权限的唯一帐户是运行 SQL Server 服务的帐户。当数据库处于打开状态时，SQL Server 会限制对 FILESTREAM 数据容器的访问，使用 T-SQL 事务和 OpenSqlFilestream API 进行的访问除外。

基于策略的管理
SQL Server 2008 基于策略的管理为管理 SQL Server 提供了一个新系统。可创建策略来测试和报告 SQL Server 的多个方面，并且可将策略应用于单个数据库、单个 SQL Server 实例或所管理的所有 SQL Server。
通过使用基于策略的管理，可测试 SQL Server 配置选项和许多安全设置。并且，对于某些安全设置，可创建策略来检测不符合法规的数据库服务器，并采取措施强制其遵守法规。
在 SQL Server 2008 中，默认禁用了许多不必要的功能，以最小化遭受攻击的风险。可使用基于策略的管理来有选择性地启用所需的任何其他功能。然后，可定期评估配置，如果发现配置设置与策略不匹配，会收到警报。
基于策略的管理将相关属性归纳成组，并将其放到称为层面的组件中。例如，外围应用配置器层面包含用于即席远程查询、CLR 集成、数据库邮件、OLE 自动化、远程 DAC、SQL 邮件、Web 助手和 xp_cmdshell 的属性。可创建策略来启用 CLR 集成但禁用所有其他功能。策略可包含复杂的条件语句，如禁用除名为 Customer_Response 以外的所有 SQL Server 实例的数据库邮件。
创建完策略后，可在所有服务器上评估该策略，以生成报告来告知您哪些服务器不遵守该策略。按“Configure”（配置）按钮，所有不符合策略的实例都将配置该策略设置。还应制定计划定期运行该策略，以监控服务器的状态。为数据库引擎、分析服务和报告服务提供了外围应用配置器层面。
但是，请注意，基于策略的管理并不旨在用作安全强制执行机制。在大多数情况下，拥有足够特权的用户可发出违反策略的语句，或忽略策略并执行可能违反安全策略的重新配置操作。SQL Server 2008 基于策略的管理仅应视为监控 SQL Server 安全设置方面的助手。
层面强制执行设置的能力各有不同，具体取决于其相关 DDL 语句能否在非自动提交模式下运行。有时，层面可强制在数据库引擎实例上实施某个配置设置，但管理员仍可重新配置设置。有些层面可通过服务器触发器来强制实施 — 从而可以防止低权限用户更改设置，并降低管理员意外地更改设置的机率。此时，管理员必须先暂时禁用该策略，然后才能更改设置。其他一些层面仅报告属性的状态，而无法更改属性。例如，检查对称或非对称密钥长度的策略（如图 2 所示）。
Figure 2 非对称密钥的层面
Figure 2 非对称密钥的层面
大部分数据库对象类型都有层面，其中许多层面都可用于安全设置。例如，登录层面可确定是否针对每个登录强制执行密码策略，而存储过程层面则可检测所有过程是否已加密。其他层面可测试用户、架构、加密提供程序、通用标准符合性和 C2 审核的属性。

Windows Server 2008
SQL Server 2008 已在开启防火墙的 Windows Server® 2008 中经过完整测试。现在正好来回顾一下如何配置防火墙设置。Windows Server 2008 还提供用户访问控制（如果使用过 Windows Vista®，您可能对其已经有所了解）。它限制了您作为管理用户而自动获得的权限。这些功能将影响所有版本的 SQL Server。

总结
安全性一直都是 SQL Server 致力改善的一个领域。加密和身份验证增强功能提供了新的功能，而新的审核系统和 SQL Server 2008 基于策略的管理则为您提供新工具来监控安全合规性的状态。

Rick Byham 于 1995 年加入 Microsoft。他先是一名“客户支持服务”的 SQL Server 支持工程师，后来又加入 Microsoft Learning 的 SQL Server 团队。在 2003 年，他调到“SQL Server 联机丛书”团队担任技术撰稿人，目前负责安全性文档。可通过 rick.byham@microsoft.com 与 Rick 联系。


 SQL Server 2008: 新数据类型
SQL Server 2008 Kelly Wilson

新数据类型
概览:
  • 新日期和时间数据类型
  • 代表在层次结构中的位置
  • 用于处理空间数据的两种模型

在全球经济环境下开展业务这一趋势越来越要求各公司使用新型的数据、应用程序以及复杂的计算。SQL Server 2008 内置的七种新数据类型
提供了处理和简化更复杂数据管理的方法。

日期和时间
使用旧的 datetime 数据类型时，SQL Server® 用户无法分别处理日期和时间信息。四种新数据类型（date、time、datetime2 和 datetimeoffset）则改变了这一状况，从而简化了日期和时间数据的处理，并且提供了更大的日期范围、小数秒精度以及时区支持。新数据库应用程序应使用这些新数据类型，而非原来的 datetime。让我们进一步了解一下这些新类型。
Date 数据类型仅存储日期，不存储时间。范围是从 1000 年 1 月 1 日到 9999 年 12 月 31 日（0001-01-01 到 9999-12-31）。每个日期变量都需要 3 个存储字节，且精度为 10 位。Date 类型的准确性仅限于单天。
看一看图 1，它显示了如何在 T-SQL 脚本中创建和初始化 Date 变量。变量 @myDate1 初始化为 'MM/DD/YYYY' 格式的字符串。变量 @myDate2 则未初始化，它的值将为 NULL。变量 @myDate3 初始化为本地计算机系统的日期。可随时使用 SELECT 或 SET 语句来更改变量的值，示例中更改了 @myDate2 的值。也可在表格中创建日期列。图 2 展示了如何创建包含三个日期列的表格。
Figure 2 Create a table with three date columns (Close Figure 2)
USE TempDB
GO

CREATE TABLE myTable
(
    myDate1 date,myDate2 date,myDate3 date
)
GO

INSERT INTO myTable
VALUES('01/22/2005',
       '2007-05-08 12:35:29.1234567 +12:15',
       GetDate())

SELECT * FROM myTable

--Results
--myDate1    myDate2    myDate3
------------ ---------- ----------
--2005-01-22 2007-05-08 2007-11-20
Figure 1 Create and initialize date variables in T-SQL scripts (Close Figure 1)
DECLARE @myDate1 date = '01/22/2005'
DECLARE @myDate2 date
DECLARE @myDate3 date = GetDate()

SELECT @myDate2 = '2007-05-08 12:35:29.1234567 +12:15'

SELECT @myDate1 AS '@myDate1',
       @myDate2 AS '@myDate2',
       @myDate3 AS '@myDate3'

--Results
--@myDate1   @myDate2   @myDate3
------------ ---------- ----------
--2005-01-22 2007-05-08 2007-11-20
Time 数据类型仅存储一天中的时间，不存储日期。它使用的是 24 小时时钟，因此支持的范围是 00:00:00.0000000 到 23:59:59.9999999（小时、分钟、秒和小数秒）。可在创建数据类型时指定小数秒的精度。默认精度是 7 位，准确度是 100 毫微秒。精度影响着所需的存储空间大小，范围包括最多 2 位的 3 个字节、3 或 4 位的 4 个字节以及 5 到 7 位的 5 个字节。
图 3 中的 T-SQL 脚本展示了字符串初始化值的隐式转换将如何影响变量的精度。T-SQL 代码首先创建八个单独的时间变量，并将其初始化为相同值。每个变量的小数精度等于其名称。例如，@myTime3 的小数精度为 3 位。结果显示每个时间数据类型的精度均等于声明的小数精度。超出的位数将被截断。
Figure 3 Display time data type's variable precision (Close Figure 3)
DECLARE @myTime  time = '01:01:01.1234567 +01:01'
DECLARE @myTime1 time(1) = '01:01:01.1234567 +01:01'
DECLARE @myTime2 time(2) = '01:01:01.1234567 +01:01'
DECLARE @myTime3 time(3) = '01:01:01.1234567 +01:01'
DECLARE @myTime4 time(4) = '01:01:01.1234567 +01:01'
DECLARE @myTime5 time(5) = '01:01:01.1234567 +01:01'
DECLARE @myTime6 time(6) = '01:01:01.1234567 +01:01'
DECLARE @myTime7 time(7) = '01:01:01.1234567 +01:01'

SELECT @myTime  AS '@myTime',
       @myTime1 AS '@myTime1',
       @myTime2 AS '@myTime2',
       @myTime3 AS '@myTime3',
       @myTime4 AS '@myTime4',
       @myTime5 AS '@myTime5',
       @myTime6 AS '@myTime6',
       @myTime7 AS '@myTime7'

--Results
--@myTime          @myTime1   @myTime2    @myTime3     @myTime4
------------------ ---------- ----------- ------------ -------------
--01:01:01.1234567 01:01:01.1 01:01:01.12 01:01:01.123 01:01:01.1235
--
--@myTime5       @myTime6        @myTime7
---------------- --------------- ----------------
--01:01:01.12346 01:01:01.123457 01:01:01.1234567

DROP TABLE myTable
可将 time 数据类型创建为表格中的一列。图 4 中的 DROP TABLE myTable T-SQL 脚本创建了一个名为 myTable1 的表格并向表格添加了三个时间列。然后，使用 SELECT 语句来将记录插入到表格中并且显示表格的内容。
Figure 4 Create myTable1 (Close Figure 4)
USE TempDB
GO

CREATE TABLE myTable1
(
    myTime1 time(1),
    myTime2 time(2),
    myTime3 time(3)
)
GO

INSERT INTO myTable1
VALUES('01:30:01.1234567',
       '02:34:01.1234567',
       '03:01:59.1234567')

SELECT * from myTable1

--Results
--myTime1    myTime2     myTime3
------------ ----------- ------------
--01:30:01.1000000 02:34:15.1200000 03:01:59.1230000

DROP TABLE myTable1

Datetimeoffset 和 Datetime2
Datetimeoffset 数据类型提供了时区信息。time 数据类型不包含时区，因此仅适用于当地时间。然而，在全球经济形势下，常常需要知道某个地区的时间与另一地区的时间之间的关系。时区偏移值表示为 + 或 - hh:mm。
以下代码创建了一个 datetimeoffset 变量并将其初始化为时间值 8:52 A.M.太平洋时间：
DECLARE @date DATETIMEOFFSET = '2007-11-26T08:52:00.1234567-08:00'
PRINT @date
--Results
--2007-11-26 08:52:00.1234567 -08:00
初始化 datetimeoffset 变量（脚本中的 @date）的字符串为特殊格式，从最重要的元素到最不重要的元素。单个大写字母 T 分隔了日期和时间元素。减号将时间元素与时区分隔开来。减号与时间或时区元素之间并无空格。该格式是 datetimeoffset 数据类型所支持的两种 ISO 8601 格式中的一种（ISO 8601 是日期和时间值表示的国际标准）。
时间组件的精度指定为与 time 数据类型一样，并且如果未指定则默认为同样的七位。支持的范围也相同。
Datetime2 数据类型是原始 datetime 类型的扩展。它支持更大的日期范围以及更细的小数秒精度，同时可使用它来指定精度。datetime2 类型的日期范围是 0001 年 1 月 1 日到 9999 年 12 月 31 日（原始 datetime 的范围则是 1753 年 1 月 1 日到 9999 年 12 月 31 日）。与 time 类型一样，提供了七位小数秒精度。原始 datetime 类型提供了三位精度，且时间范围为 00:00:00 到 23:59:59.999。以下代码显示了如何创建一个 datetime2 变量并将其初始化为本地服务器日期和时间：
DECLARE @datetime2 DATETIME2 = GetDate();
PRINT @datetime2

--Results
--2007-11-26 09:39:04.1370000
接下来看看新的 hierarchyid 数据类型。该数据类型用于处理表中数据元素之间的关系，而非具体的日期或时间数据。

Hierarchyid 数据类型
Hierarchyid 数据类型可用于构建表中数据元素之间的关系，专门代表在层次结构中的位置。为研究该数据类型，首先通过使用图 5 中的脚本来创建 MyCompany 数据库并在其中填写员工数据。
Figure 5 Create and populate the MyCompany database (Close Figure 5)
USE MASTER
GO

CREATE DATABASE MyCompany
GO
USE MyCompany
GO

--Create a table called employee that will store
--the data for the employees for MyCompany.

CREATE TABLE employee
(
    EmployeeID int NOT NULL,
    EmpName    varchar(20) NOT NULL,
    Title      varchar(20) NULL,
    Salary     decimal(18, 2) NOT NULL,
    hireDate   datetimeoffset(0) NOT NULL,
)
GO

--These statements will insert the data for the employees of MyCompany.

INSERT INTO employee
VALUES(6,   'David',  'CEO', 35900.00, '2000-05-23T08:30:00-08:00')

INSERT INTO employee
VALUES(46,  'Sariya', 'Specialist', 14000.00, '2002-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(271, 'John',   'Specialist', 14000.00, '2002-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(119, 'Jill',   'Specialist', 14000.00, '2007-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(269, 'Wanida', 'Assistant', 8000.00, '2003-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(272, 'Mary',   'Assistant', 8000.00, '2004-05-23T09:00:00-08:00')
GO
--Results
--EmployeeID  EmpName Title      Salary   hireDate
------------- ------- ---------- -------- --------------------------
--6           David   CEO        35900.00 2000-05-23 08:30:00 -08:00
--46          Sariya  Specialist 14000.00 2002-05-23 09:00:00 -08:00
--271         John    Specialist 14000.00 2002-05-23 09:00:00 -08:00
--119         Jill    Specialist 14000.00 2007-05-23 09:00:00 -08:00
--269         Wanida  Assistant  8000.00  2003-05-23 09:00:00 -08:00
--272         Mary    Assistant  8000.00  2004-05-23 09:00:00 -08:00
图 6 显示了生成的简单数据库，仅包含一个员工表。MyCompany 数据库中的该员工表不包含任何强加结构。这对于关系型数据库而言非常正常，因为结构是由应用程序通过其查询和处理代码来动态强加的。
Figure 6 MyCompany 员工表
Figure 6 MyCompany 员工表
但是，企业数据通常都具有内在结构。例如，每个企业都具有报告结构，如图 7 中所示的 MyCompany 的报告结构。MyCompany 的所有员工都向 CEO David 报告。某些员工为直接报告（如 Jill）。其他人（如 Mary）则通过中间人报告。在编程术语中，MyCompany 的报告结构称为树，因为其形状非常像树。最上方的 David 无需向任何人报告，他是父级或祖先。其下为向 David 报告的员工。此类节点称为子级或后代。David 可拥有任意多个后代，以代表其直接下属。
Figure 7 MyCompany 的组织结构
Figure 7 MyCompany 的组织结构
图 8 中的脚本使用 hierarchyid 数据类型重构了 MyCompany 数据库，构建了一个符合 MyCompany 报告结构的关系。先使用 ALTER TABLE 语句添加一个 hierarchyid 列。然后使用 hierarchyid 的 GetRoot 方法插入 David 的节点。接着使用 GetDescendant 方法将 David 的直接下属添加到树中。
Figure 8 Rebuild the database using hierarchyid (Close Figure 8)
DELETE employee
GO
ALTER TABLE employee ADD OrgNode hierarchyid NOT NULL
GO

DECLARE @child hierarchyid,
@Manager hierarchyid = hierarchyid::GetRoot()

--The first step is to add the node at the top of the
--tree. Since David is the CEO his node will be the
--root node.

INSERT INTO employee
VALUES(6,   'David',  'CEO', 35900.00,
       '2000-05-23T08:30:00-08:00', @Manager)

--The next step is to insert the records for
--the employees that report directly to David.

SELECT @child = @Manager.GetDescendant(NULL, NULL)

INSERT INTO employee
VALUES(46,  'Sariya', 'Specialist', 14000.00,
       '2002-05-23T09:00:00-08:00', @child)

SELECT @child = @Manager.GetDescendant(@child, NULL)
INSERT INTO employee
VALUES(271, ‚John',   ‚Specialist', 14000.00,
       '2002-05-23T09:00:00-08:00', @child)

SELECT @child = @Manager.GetDescendant(@child, NULL)
INSERT INTO employee
VALUES(119, ‚Jill',   ‚Specialist', 14000.00,
       ‚2007-05-23T09:00:00-08:00', @child)

--We can now insert the employee that reports to
--Sariya.
SELECT @manager = OrgNode.GetDescendant(NULL, NULL)
FROM employee WHERE EmployeeID = 46

INSERT INTO employee
VALUES(269, ‚Wanida', ‚Assistant', 8000.00,
       ‚2003-05-23T09:00:00-08:00', @manager)

--Next insert the employee that report to John.
SELECT @manager = OrgNode.GetDescendant(NULL, NULL)
FROM employee WHERE EmployeeID = 271

INSERT INTO employee
VALUES(272, ‚Mary',   ‚Assistant', 8000.00,
       ‚2004-05-23T09:00:00-08:00', @manager)
GO
添加数据库记录且构建好层次结构后，就可使用类似以下的查询来显示员工表的内容：
SELECT EmpName, Title, Salary, OrgNode.ToString() AS OrgNode
FROM employee ORDER BY OrgNode
GO
--Results
--EmpName  Title      Salary    OrgNode
---------- ---------- --------- -------
--David    CEO        35900.00  /
--Sariya   Specialist 14000.00  /1/
--Wanida   Assistant  8000.00   /1/1/
--John     Specialist 14000.00  /2/
--Mary     Assistant  8000.00   /2/1/
--Jill     Specialist 14000.00  /3/
OrgNode 是 hierarchyid 列。结果中的每个斜线 / 字符表示层次结构树中的一个节点。David 位于根节点，因此显示一个斜线。Sariya、John 和 Jill 向 David 报告，因此有两个斜线，表示他们是层次结构中的第二层节点。数字 1、2 或 3 显示各子节点的顺序。该系统非常灵活。可根据需要删除、插入或添加子节点。例如，如果在 John 和 Jill 之间添加一名员工，该员工在结果集中将列为：/2.1/.
要回答问题（如“谁向 Sariya 报告？”），可创建以下 T-SQL 代码中所示的查询：
DECLARE @Sariya hierarchyid

SELECT @Sariya = OrgNode
FROM employee WHERE EmployeeID = 46

SELECT EmpName, Title, Salary, OrgNode.ToString() AS 'OrgNode'
FROM employee
WHERE OrgNode.GetAncestor(1) = @Sariya
GO
--Results
--EmpName Title     Salary  OrgNode
--------- --------- ------- -------
--Wanida  Assistant 8000.00 /1/1/
此查询使用 hierarchyid 的 GetAncestor 方法，它会返回当前 hierarchyid 节点的父项。在之前的代码中，将变量 @Sariya 设为 Sariya 的层次结构节点。因为 Sariya 是向她报告的所有员工的直接前辈。因此，要编写一个返回直接向 Sariya 报告的员工的查询，需从树中检索 Sariya 的节点，然后选择前辈节点为 Sariya 节点的所有员工。
Hierarchyid 列应非常紧凑，因为代表树中节点所需的位数取决于节点的平均子项数（通常称为节点的扇出）。例如，拥有 100,000 名员工且平均扇出为六级的组织层次结构中的新节点需五个存储字节。
Hierarchyid 数据类型提供了多个便于处理层次数据的方法。图 9 概要显示了这些方法。有关所有方法的详细信息，请参阅 SQL Server 联机丛书 (msdn2.microsoft.com/ms130214)。
Figure 9 Methods provided by the hierarchyid data type (Close Figure 9)

方法 | 说明
GetAncestor | 返回代表该 hierarchyid 节点第 n 代前辈的 hierarchyid。
GetDescendant | 返回该 hierarchyid 节点的子节点。
GetLevel | 返回一个整数，代表该 hierarchyid 节点在整个层次结构中的深度。
GetRoot | 返回该层次结构树的根 hierarchyid 节点。静态。
IsDescendant | 如果传入的子节点是该 hierarchyid 节点的后代，则返回 true。
Parse | 将层次结构的字符串表示转换成 hierarchyid 值。静态。
Reparent | 将层次结构中的某个节点移动另一个位置。
ToString | 返回包含该 hierarchyid 逻辑表示的字符串。

空间数据类型
空间数据是用于确定地理位置和形状（主要是在地球上）的数据。它们可以是界标、道路甚至企业所在地。SQL Server 2008 提供了 geography 和 geometry 数据类型来处理此类数据。
Geography 数据类型处理圆地信息。圆地模型在计算时考虑了地球的曲面。位置信息是由经度和纬度组成。该模型极其适合越洋运输、军事规划等应用程序以及涉及地球表面的短程应用程序。如果数据是按经度和纬度存储的，则使用此模型。
Geometry 数据类型处理平地或平面模型。在此模型中，将地球当作从已知点起的平面投影。平地模型不考虑地球的弯曲，因此主要用于描述较短的距离，如映射建筑物内部的数据库应用程序。
Geography 和 geometry 类型从矢量对象构建，格式为 Well-Known Text (WKT) 或 Well-Known Binary (WKB)。它们是开放地理空间联盟 (OGC) SQL 简单特征规范描述的空间数据传输格式。图 10 列出了 SQL Server 2008 支持的七种矢量对象类型。
Figure 10 Vector objects supported by SQL Server 2008 (Close Figure 10)

对象 | 说明
Point | 一个位置。
MultiPoint | 一系列点。
LineString | 由直线连接的零个或多个点。
MultiLineString | 一组 linestring。
Polygon | 一组封闭 linestring 形成的相连区域。
MultiPolygon | 一组多边形。
GeometryCollection | geometry 类型集合。
要使用一个或多个矢量对象构建一个 geography 类型，首先在 T-SQL 脚本中声明 geography 类型（如图 11 所示）。然后调用图 12 中列出的一个方法，并传入矢量对象字符串和空间参照 ID (SRID)。SRID 是欧洲石油调查组定义的空间参照标识系统。它是针对绘图、调查和测量数据存储制定的一组标准的组成部分。每个 SRID 标识地理计算中使用的一个具体椭圆体类型。因为地球并非标准的球体，所以这是必须的。SQL Server 2008 仅能对相同 SRID 执行计算。
Figure 12 Construct objects for geography and geometry (Close Figure 12)

方法 | 说明
STGeomFromText | 根据输入文本构建任意类型的 geography 实例。
STPointFromText | 根据输入文本构建一个 geography 的 Point 实例。
STMPointFromText | 根据输入文本构建一个 geography 的 MultiPoint 实例。
STLineFromText | 根据输入文本构建一个 geography 的 LineString 实例。
STMLineFromText | 根据输入文本构建一个 geography 的 MultiLineString 实例。
STPolyFromText | 根据输入文本构建一个 geography 的 Polygon 实例。
STMPolyFromText | 根据输入文本构建一个 geography 的 MultiPolygon 实例。
STGeomCollFromText | 根据输入文本构建一个 geography 的 GeometryCollection 实例。
Figure 11 Create points, lines, and polygon geometry (Close Figure 11)
DECLARE @geo1 geometry
SELECT @geo1 = geometry::STGeomFromText('POINT (3 4)', 0)
PRINT @geo1.ToString()

DECLARE @geo2 geometry
SELECT @geo2 = geometry::Parse('POINT(3 4 7 2.5)')
PRINT @geo2.STX;
PRINT @geo2.STY;
PRINT @geo2.Z;
PRINT @geo2.M;

DECLARE @geo3 geography;
SELECT @geo3 = geography::STGeomFromText(
    'LINESTRING(47.656 -122.360, 47.656 -122.343)', 4326);
SELECT @geo3.ToString();

--Results
--POINT (3 4)
--3
--4
--7
--2.5

DECLARE @gx geometry;
SET @gx = geometry::STPolyFromText(
    'POLYGON ((5 5, 10 5, 10 10, 5 5))', 0);
PRINT @gx.ToString();
--Results
--POLYGON ((5 5, 10 5, 10 10, 5 5))

Geography 和 Geometry 之间的差别
Geography 和 geometry 数据类型专用于处理不同类型的数据，因此必须了解一些关键差别。使用 geometry 数据类型时，距离和面积的度量单位需与实例的坐标一致。例如，点 (0,0) 和点 (6,8) 之间的距离将始终为 10 个单位。使用 geography 类型时则不一样，它使用的是以经度和纬度表示的椭圆体坐标。
当坐标以经度纬度对表示时，GEOMETRY 数据类型返回的是不同的结果。以下 T-SQL 代码计算点 (90 0) 和点 (90 180) 之间的距离。这两个点均代表北极，因此它们之间的距离应为 0。在使用 GEOMETRY 时，计算后的距离为 180。
DECLARE @g1 GEOMETRY, @g2 GEOMETRY, @g3 GEOGRAPHY, @g4 GEOGRAPHY
SELECT @g1 = GEOMETRY::STGeomFromText('POINT (90 0)', 0)
SELECT @g2 = GEOMETRY::STGeomFromText('POINT (90 180)', 0)

SELECT @g3 = GEOGRAPHY::STGeomFromText('POINT (90 0)', 4326)
SELECT @g4 = GEOGRAPHY::STGeomFromText('POINT (90 180)', 4326)
SELECT @g2.STDistance(@g1) AS 'GEOMETRY',
       @g4.STDistance(@g3) AS 'GEOGRAPHY';

--Results
--GEOMETRY               GEOGRAPHY
------------------------ ----------------------
--180                    0
两种数据类型的空间数据方向也不同。在 geometry 数据类型所使用的平面系统中，多边形的方向并非重要因素。例如，坐标为 ((0, 0), (10, 0), (0, 20), (0, 0)) 的多边形被视为等同于多边形 ((0, 0), (0, 20), (10, 0), (0, 0))。但是，在 geography 数据类型所使用的数据模型中，如果没有指定方向，则并不能确定多边形。例如，假定有个环绕赤道的环。那么，该环所形成的多边形代表的是北半球还是南半球？因此，在使用 geography 数据时，必须准确指出方向和位置。
SQL Server 2008 对 geography 数据类型还设有一些限制。例如，每个 geography 实例均必须位于单个半球内。不允许更大的空间对象，否则会抛出 ArgumentException。如果方法的结果并不位于单个半球内，则需要两个输入的 Geography 数据类型会返回 NULL。
SQL Server 提供了多个可针对 geography 和 geometry 实例执行操作的方法。图 13 显示了使用 SQL Server 2008 提供的方法来处理空间数据的一些示例。鉴于篇幅有限，在此就不再详述该主题，SQL Server 联机丛书中提供有完整说明。
Figure 13 Working with spatial data (Close Figure 13)
DECLARE @gm geometry;
DECLARE @gg geography;
DECLARE @h geography;

SET @gm = geometry::STGeomFromText('POLYGON((0 0, 13 0, 3 3, 0 13, 0 0),(2 2, 2 1, 1 1, 1 2, 2 2))', 0);
SELECT @gm.STArea();

--Results
--38

SET @gg = geography::STGeomFromText('LINESTRING(0 0, 5 5)', 4326);
--Calculate the distance to a point slightly offset from the LINESTRING.
SET @h = geography::STGeomFromText('POINT(4 4)', 4326);
SELECT @gg.STDistance(@h);

--Results
-- 430.182777043046

--Calculate the distance to a point on the LINESTRING.
SET @h = geography::STGeomFromText('POINT(5 5)', 4326);
SELECT @gg.STDistance(@h);

--Results
-- 0

DECLARE @temp table ([name] varchar(10), [geom] geography);

INSERT INTO @temp values ('Point', geography::STGeomFromText('POINT(
5 10)', 4326));
INSERT INTO @temp values ('LineString', geography::STGeomFromText(
'LINESTRING(13 5, 50 25)', 4326));
--Calculate the distance to a point on the LINESTRING.
--Display the number of dimensions for a geography object stored in a --table variable.
INSERT INTO @temp values ('Polygon', geography::STGeomFromText(
'POLYGON((47.653 -122.358, 47.649 -122.348, 47.658 -122.348, 47.658 -122.358, 47.653 -122.358))', 4326));

SELECT [name], [geom].STDimension() as [dim]
FROM @temp;

--Results
--name       dim
------------ -----------
--Point      0
--LineString 1
--Polygon    2
希望在此介绍的 SQL Server 2008 中的七种新数据类型能对您有所帮助。

Kelly Wilson 从事软件工程方面的工作已有 20 余年。他擅长的是 SQL Server、3D 图形、游戏以及颜色科学方面的应用程序。Kelly 目前是 Microsoft SQL Server 组的程序员。


 SQL Server 2008: 数据仓库查询性能
SQL Server 2008 Sunil Agarwal and Torsten Grabs and Dr. Joachim Hammer

数据仓库查询性能
概览:
  • 星型联接查询优化
  • 分区表并行处理
  • ROW 和 PAGE 压缩
  • 分区对齐的索引视图

较前期同类产品相比，SQL Server 2008 将提供功能更为强大的关系数据仓库，但是您可能仍希望了解如何充分利用这项新技术来构建性能良好的数据仓库，以便对数十亿行的数据进行决策支持查询。或者您可能希望了解哪些功能将有助于您获取针对决策支持查询和报告的最佳查询性能，或者该新版本的 SQL Server® 可实际带来哪种性能改进。
越接近实际产品发布，越会产生许多问题。我们在此深入探讨 SQL Server 2008 中一些与性能相关的最重要数据仓库功能，希望能对您有所裨益。

逻辑数据库设计：维度建模
事务性业务线应用程序通常使用规范化数据库架构。关系数据仓库的逻辑数据库架构设计不太注重规范化。现在的许多关系数据仓库设计都使用维度建模方法，这种方法的流行得益于 Ralph Kimball 和 Margy Ross 合著的《The Data Warehouse Toolkit:The Complete Guide to Dimensional Modeling》。
如果经常与数据仓库打交道，您可能已经熟悉关系数据仓库的常见架构模式（如星型架构和雪花型架构）。维度建模将维度表与事实表区分开来。维度表存放主数据（如产品、客户、商店或国家），而事实表则存储事务性数据（如销售、订单、采购或利润）。
维度表和事实表是通过主键 (PK)/外键 (FK) 关系链接在一起的。您会发现许多数据仓库并未强行要求将 FK 约束作为降低存储要求的方法。这就节省了基础索引的存储开销，降低了事实表的维护成本。数据仓库中的维度表通常非常的小 — 一般最少几千行，最多几百万行。事实表则非常大，存放着上亿到十几亿行。因此，事实表的存储要求是逻辑设计的真正重点。
在确定应从维度表中选择哪个键来维护事实表/维度表关系时，这一大小因素也在考虑之内。基于维度业务键的组合键（表示维度所代表实体的实际标识符）通常包含多个列。请注意，对于事实表中的对应外键而言，这是个问题，因为会对每个事实表行重复这一多列组合键。
为此，一种常见的方法是使用小的代理键在事实表及其维度之间建立关系。代理键是一个整数型标识列，用作维度表的虚拟主键。事实表引用更小的代理键后，大型事实表的存储要求得以显著降低。图 1 说明了使用维度表和代理键型事实表的维度建模数据仓库架构。
Figure 1 包含一个事实表和两个维度表的星型架构示例
Figure 1 包含一个事实表和两个维度表的星型架构示例
雪花型架构设计将一个或多个维度散布到多个级别（例如，某个客户维度的客户、国家和地区），从而规范化数据中存在过度冗余的大型维度。各级别由单个表代表，从而使该架构呈雪花状。而星型架构设计则不将其任何维度散布到多个表内。星型架构形状象星星，其中维度表围绕四周，中心是事实表。
通过使用维度建模的星型架构或雪花型架构，决策支持查询采用以下典型模式：查询从事实表选择多个感兴趣的度量、通过代理键联接事实行和一个或多个维度、针对维度表的业务列应用筛选谓词、按一个或多个业务列分组，并统计在一段时间内从事实表检索的度量。以下即是该模式的示例，它有时也被称为星型联接查询：
select ProductAlternateKey,
CalendarYear,sum(SalesAmount)
from FactInternetSales Fact
     join DimTime
on Fact.OrderDateKey = TimeKey
     join DimProduct
on DimProduct.ProductKey =
   Fact.ProductKey
where CalendarYear between 2003 and 2004
      and ProductAlternateKey like 'BK%'
group by ProductAlternateKey,CalendarYear

物理设计
关系数据仓库中的许多 SQL 查询都遵循星型联接查询结构。然而，决策支持查询通常应时而变，因为决策者们总是希望通过新方法来更好地了解其基础业务数据。这就是数据仓库要面对大量临时查询的原因。这也使得决策支持查询和维度建模数据仓库架构的物理设计富有挑战性。
通过使用 SQL Server，数据仓库设计人员通常首先建立一个蓝图或物理设计，它可根据工作负载的变化进行精细调整。可根据您数据仓库环境的实际情况自由使用或更改该蓝图。如果是这样，请谨记数据库物理设计的最佳实践，如索引更新维护所引起的性能影响以及索引的存储要求。

事实表
蓝图设计旨在预计典型的星型查询形状并构建事实表的索引。事实表的聚集索引将多个维度代理键列（外键列）作为索引键。最常用的列应出现在索引键列表中。您可能希望确认它确实为工作负载中最常执行的查询提供了一个不错的访问路径。
此外，蓝图为事实表中的每个维度代理（外键）列创建了一个单列非聚集索引。从而为某一维度极具选择性的查询提供了一个高效访问路径。
聚集索引的目标是为提高工作负载中大部分查询的性能。非聚集索引组的目标是为特定客户或产品检索事实表度量的查询。这些非聚集索引可帮您提高效率，例如，您不必扫描事实表来检索单个客户的销售数据。

维度表
在对维度表应用蓝图设计时，需为每个维度表创建索引。它们包括针对维度代理键列的非聚集主键约束索引，以及针对维度实体业务键列的聚集索引。对于大型维度表，还应考虑增加针对高选择性谓词中常用列的非聚集索引。
聚集索引在数据仓库维护期间可提高提取、转换和加载 (ETL) 效率，而维护对于时间要求往往很严格。例如，通过缓慢地更改维度，现有行得到适当更新，同时尚未出现在维度中的行则附加到维度表。为成功达到目标，该访问模式要求在 ETL 期间维度表的查询和更新一切顺利。
要对利用 SQL Server 构建的关系数据仓库进行物理设计，我们提到的蓝图设计是个不错的起点。根据该典型关系数据仓库设置，我们可研究 SQL Server 2008 中包含的重要新功能。

星型联接查询优化
处理事实表通常是在维度建模关系数据仓库中执行星型联接查询时最大的开销。这一点显而易见，因为即使是高选择性的查询，从事实表检索的行数都远比从任何维度表检索出的要多得多。因此，针对事实表使用最好的访问路径对于实现良好的查询性能而言至关重要。
通过使用 SQL Server，查询优化器可自动从一组备选方案中选择开销最低的访问路径。在数据仓库环境中，主要目标是确保查询优化器为星型联接查询的执行计划选择最佳的备选访问途径。SQL Server 的查询优化器中使用多种功能自动提供性能良好的星型查询执行计划。
可将星型联接查询视为分成三个不同的类别（如图 2 所示）。这几大类还有助于 SQL Server 引擎找出适用于这些查询的正确计划。SQL Server 所依据的主要概念是这些查询相对事实表的选择性。查询从事实表提取的行越少，越具选择性。事实表检索行的百分比用作这些查询类的直观区分标准。这些百分比代表来自典型客户部署的值，但它们并非用于生成访问路径定义的严格分界线。
Figure 2 星型联接查询的选择性范围
Figure 2 星型联接查询的选择性范围
第一类为高选择性查询，最多处理事实表中 10% 的行。第二类为中等选择性，所包含的查询处理事实表行的 10% 到 75% 。第三类是低选择性查询，在事实表中处理的行超过 75%。图中的方框还着重指出了每个选择性类别中的基本查询执行计划选项。

基于选择性的计划选项
由于高选择性星型查询检索的事实表行通常不超过 10%，因此这些查询可随机访问事实表。所以，该类的查询计划主要依赖于嵌套循环联接以及对事实表的（非聚集）索引搜索和书签查询。由于它们对事实表执行随机 I/O，因此如果需要检索大部分事实表，可通过连续 I/O 获取更好的性能。由于从事实表检索的行数超过了一定数量，所以需要另一种查询计划。
由于中等选择性的星型查询会处理事实表中相当多的行，哈希联接和事实表扫描或事实表范围扫描通常是对事实表的首选访问路径。SQL Server 使用位图筛选器来改善这些哈希联接的性能。
图 3 显示了 SQL Server 如何使用这些位图筛选器来改善星型联接查询执行期间的联接性能。该图显示了针对 Product 和 Time 两个维度表的一个查询计划，这两个表通过代理键与事实表联接。查询针对两个维度表使用筛选谓词（如 WHERE 子句），以便只能有一行符合所有维度。两个联接运算符旁边的小红表格是这一特征的指示符。
Figure 3 减少了联接的星型联接查询计划
Figure 3 减少了联接的星型联接查询计划
每个联接的联接实施都是哈希联接，它允许 SQL Server 从维度表将有关合格行的信息提取到两个维度表的联接减少信息中。图中的绿色方框代表联接减少信息数据结构。从底层维度表取得数据后，SQL Server 会在查询执行期间自动把这些数据结构移到处理事实表的运算符（如表扫描）。该运算符使用有关维度表行的信息来除去不满足维度联接条件的事实表行。
从事实表检索行后，SQL Server 在查询处理期间的前期就会剔除这些事实表行。这样，在查询计划的后续运算符中无需再处理已剔除的行，从而可节省 CPU 甚至磁盘 I/O 的开销。SQL Server 使用位图表示来有效表达查询执行期间的联接减少信息数据结构。

星型联接优化管道
优化过程使用标准的试探法来实现联接查询优化，以生成最初的一组查询执行计划备选方案。然后调用特殊的扩展项来生成其他查询计划备选方案。
对于数据仓库，扩展项会检测星型架构、雪花型架构以及星型查询模式，并评估查询相对事实表的选择性。如果架构和查询形式与模式匹配，SQL Server 会自动向计划空间添加更多的查询计划，然后基于开销的优化会对其进行处理以选择最有前景的查询执行计划。
在查询执行期间，SQL Server 还会监视联接减少在运行时的实际选择性。如果选择性发生变化，SQL Server 会动态重新排列联接减少信息数据结构，以便首先应用具有最大选择性的计划。

星型联接试探法
数据仓库的许多物理设计均遵循星型架构，但并不完全指定事实表和维度表之间的关系（例如之前提到的外键约束）。如果缺少明确指定的外键约束，SQL Server 必须依赖试探法来检测星型架构查询模式。可使用以下试探法来检测星型联接查询模式：
  1. 参与 n 元联接的最大表被视为是事实表。对于事实表的最小大小还有一些限制。例如，如果即使是最大的表也并未超过指定的大小，则不将 n 元联接视为星型联接。
  2. 星型联接查询中二元联接的所有联接条件必须为单列等式谓词。联接必须为内部联接。尽管可能听起来比较具有限制性，但是它涉及典型星型架构中使用代理键的事实表和维度表之间的绝大多数联接。如果联接拥有更复杂的联接条件且不符合以上所述模式，则将从星型联接排除该联接。例如，如果其中两个联接具有更复杂的联接谓词，五路联接可生成三路星型联接（其他两个联接以后再用）。
请注意，存在试探法规则。在实际情况中，很少会让试探法将维度表选作事实表。它会影响计划选择，但不会影响所选计划的正确性。然后，按选择性降序排列星型联接中的二元联接。本文中联接选择性定义为事实表的输入基数与联接的结果基数的比率 — 联接选择性表示具体维度减少了多少事实表基数。通常，我们希望首先考虑具有更高选择性的联接。
如果结果查询计划的估计查询花销适合，SQL Server 中的查询处理器会针对符合星型号联接模式和上述条件的查询自动应用优化。因此，您无需更改应用程序即可受益于这一显著的性能改进。但要注意，某些星型联接优化（如联接减少）只有 SQL Server Enterprise Edition 才提供。

星型联接性能结果
在开发 SQL Server 2008 中的星型联接优化时，我们根据基准和实际客户工作负载进行了大量性能研究。其中三种工作负载产生的结果颇具价值。
Microsoft 销售组织数据仓库 该工作负载跟踪用于 Microsoft 销售组织内部决策支持的数据仓库的性能。我们列出了一个示例快照，其中的数据库约为 750GB（包括索引）。在此工作负载中，许多查询的联接数都大于 10，因此处理起来有一定难度。
零售客户 这组试验针对零售行业中的数据仓库客户（包括常规店铺和在线展示）。客户的特点是维度建模的雪花型架构和规范的星型联接查询。我们使用约 100GB 的原始数据来填充试验用仓库快照。
决策支持工作负载 这组试验调查针对 100GB 维度建模数据库的决策支持工作负载的性能。图 4 显示这三个工作负载的结果。该图显示了工作负载中所有查询的查询响应时间标准几何平均数。它明确指出了从工作负载运行任意查询时所期望的查询性能。图中的柱条比较了未使用星型联接优化时的基准性能 (1.0) 和星型联接优化后的性能。它们均是使用的 SQL Server 2008。
Figure 4 星型联接优化后的性能改进
Figure 4 星型联接优化后的性能改进
如图所示，所有工作负载均有显著改进（12% 到 30%）。尽管具体的优势可能不尽相同，但是我们期望在 SQL Server 2008 中引入新的星型联接特定优化扩展项后，针对 SQL Server 引擎的决策支持工作负载可改善约 15%–20%。

分区表并行处理
为加快大型数据仓库的查询处理速度，数据库管理员常常按日期对大型事实表进行分区。它将数据放到不同的文件组内，从而减少了处理某一数据范围内的行时所必须搜索的数据量，并且当文件组被部署到多个物理磁盘上时，可利用底层磁盘系统的并发性能。
SQL Server 2005 可以将大型关系分成较小的逻辑块，大型表的管理因而得以改善。它还被成功用于改善查询处理，尤其是对于大型决策支持应用程序而言更显成效。
遗憾地是，某些使用 SQL Server 2005 的客户发现针对这些分区表的查询存在性能问题 — 尤其是在并行共享内存多处理器机器上运行时。在 SQL Server 2005 中针对分区表处理并行查询时，仅分配可用线程的一个子集执行查询时会出现上述情况。
试想有一台查询最多可并行使用 64 个线程的 64 核机器，并且查询会涉及两个分区。使用 SQL Server 2005 时，它仅接收 64 个线程中的 2 个，因此可能仅使用了机器 CPU 能力的 2/64（3.1%）。据报告称，对于相同的事实表，分区情况下的查询性能可能比未分区时在相同机器上运行相同查询时的性能要差 10 倍甚至更多。
需要注意的是，SQL Server 2005 针对涉及单个分区的查询进行了专门优化。此时，查询处理器会分配所有可用线程来执行扫描。这种特殊优化为在多核机器上执行的单分区查询带来了显著的性能提高，对于那些查询涉及多个分区的客户而言，他们当然也期待获得这一提高。
SQL Server 2008 引入了新的分区表并行处理 (PTP) 功能，通过更好地利用现有硬件的处理能力（而不管查询涉及多少个分区或者各个分区的相对大小如何），改进了分区情况下的查询性能。在包含分区事实表的典型数据仓库情形中，用户会发现并行计划的执行查询有了显著的改进，尤其是当可用处理器核数大于查询所涉及的分区数时。该新功能默认启用，无需任何调整或配置。
假设我们有一个分布在四个分区中的事实表，它代表按销售日期组织的销售数据。图 5 中的图表将有助于您形象地描述该示例。请注意，这里使用的并非针对整个日期范围的单个聚集索引（就像在非分区时一样），而是为事实表中每个分区的日期列设定一个聚集索引。现在假设查询 Q 汇总最近七天的销售数据。由于新的销售数据始终通过最后一个分区（即 P4）进入事实表，因此查询很可能会涉及到不同的分区，具体视其执行时间而定。如图表第一行所示，Q1 查询仅涉及单个分区，而 Q2 查询则涉及两个分区，因为执行时相关数据分布在 P3 和 P4 分区上。
Figure 5 可用新 PTP 功能
Figure 5 可用新 PTP 功能
现在假设有八个可用线程。在 SQL Server 2005 上执行 Q1 和 Q2 可能产生一些意外的行为。SQL Server 2005 具有一个优化功能，如果优化器知道在编译时查询仅涉及一个分区，则会将该分区当作单个非分区表，并生成一个使用所有可用线程来访问表的计划。
这样，涉及单个分区 (P3) 的 Q1 将生成由八个线程进行处理的计划（未显示）。对于涉及两个分区的 Q2，执行程序向每个分区分配一个线程，即使底层硬件还有其他可用线程。因此，Q2 仅利用了可用 CPU 能力中极小的一部分，并且很可能执行速度明显慢于 Q1。
在 SQL Server 2008 上执行 Q1 和 Q2 时，可用硬件利用率更高、性能更好并且对于行为的预测能力也更强。对于 Q1，执行程序仍分配全部八个可用线程来处理 P2 中的数据（未显示）。同时，Q2 则会产生一个并行计划，其中的执行程序将以轮叫方式将所有可用线程分配给 P3 和 P4，因而产生图中最下面一行所示的效果，其中两个分区中的每个分区各获得四个线程。CPU 得以充分利用，且 Q1 和 Q2 的性能不相仲伯。
通过该线程轮叫分配，如果处理器核数多于查询所涉及的分区数，查询的性能将更好。然而，遗憾地是，有时为分区分配线程并不象示例中这么简单。
对于多核处理器机器上的分区表，图 6 进一步显示了从 SQL Server 2005 到 SQL Server 2008 所产生的性能改进。该图表着重指出了分区表的扫描性能。对于这个在 64 核且 RAM 为 256GB 的系统上执行的特殊测试，我们将 121GB 的单个表分成 11 个分区，每个均为 11GB。对于该图中所示的测试组，我们使用堆文件组织以及冷缓冲区和热缓冲区启动。所有查询均对数据执行简单扫描。
Figure 6 启用了新 PTP 功能的 SQL Server 的扫描性能
Figure 6 启用了新 PTP 功能的 SQL Server 的扫描性能
y 轴显示了响应时间（秒），x 轴表示并行度 (DOP)，它模拟分配给查询的线程数。如您所见，在冷启动和热启动两种情况下，响应时间持续减少，直到 DOP 达到 22。此时，I/O 系统对于冷启动情形变为满负荷状态。其原因是本示例中使用的查询受 I/O 限制。如果是受 CPU 限制的工作负载，该限制可能不存在，或者仅在 DOP 更高时才会发生。
然而，代表热启动情形的曲线则随着 DOP 级别的增加，其响应时间仍在继续降低。对于 SQL Server 2005，在 DOP 11 附近，两条曲线都开始变平，因为在处理多个分区时，每个分区的线程数仅限于 1。
必须指出的一点是，实际上，增加 DOP 所取得的响应时间提高永远不可能是线性的。预期的行为更类似于阶跃函数 — 它反映出查询必须等待最慢的子件。因此，例如，仅向扫描再添加一个线程并不会加快查询，除非所有其他扫描也获得了能加快速度的其他线程。
对于其他各种硬件和文件配置，我们也通过其他试验测试了新的 PTP 行为。此时，在当 DOP 超过 1 线程/分区时，我们在吞吐量范围中观察到了类似行为。
最后（但同样重要），SQL Server 2008 中的新 PTP 功能还改善了查询计划的可读性，并允许深入洞察具体工作负载的执行。例如，作为 PTP 功能的一部分，在 showplan XML 中表示并行和串行计划的方式已得到改进，并且编译时和运行时执行计划中提供的分区信息也已增强。

数据压缩
随着商业智能的日益普及，企业将越来越多的数据灌入到其数据仓库中进行分析。这使得所管理的数据量呈指数级增长。在 1995 年，Winter Corporation 的第一份数据库容量调查指出，当时全球最大的系统包含的数据量是 TB。十年之后，最大的数据库扩大了近 100 倍。更令人惊讶的是数据仓库的大小每两年即增至原来的三倍。要管理如此大的数据并为数据仓库查询提供可接受的性能，难度可想而知。这些查询通常都非常复杂（涉及多个联接和累计），并要访问大量数据。工作负载中的许多查询还都受 I/O 限制。
本机数据压缩是这一问题的解决方案。SQL Server 2005 SP2 为小数和数字型数据引入了一个新的可变长度存储格式，即 vardecimal 存储格式。这一新存储格式可显著降低数据库的大小。而空间的节省又有助于在以下两方面改善受 I/O 限制查询的性能。首先，要读取的页面更少，其次，由于数据是以压缩格式存储在缓冲池中，因而提高了页面预期寿命（换句话说，它加大了在缓存中找到所请求页面的机率）。当然，由于需压缩和解压缩数据，从数据压缩获得的空间节省确实会产生一定的 CPU 开销。
SQL Server 2008 基于 vardecimal 存储格式构建，提供以下两类压缩：ROW 压缩和 PAGE 压缩。通过用可变长度存储格式存储所有固定长度的数据类型，ROW 压缩扩展了 vardecimal 存储格式。
固定长度数据类型示例包括：整数、字符和浮点数据类型。即使 SQL Server 将这些数据类型存储成可变长度格式，数据类型的语义仍保持不变（从应用程序角度看，数据类型仍为固定长度数据类型）。因此，既能从数据压缩受益，又无需对应用程序做任何更改。
PAGE 压缩将给定页面上一行或多行的列数据冗余降至最小。它使用 LZ78 (Lempel-Ziv) 算法的专有实现方法，在页面上仅存储一次冗余数据，然后从多个列对其进行引用。请注意，在使用 PAGE 压缩时，实际也包括了 ROW 压缩。
可针对表、索引或者分区表和索引的一个或多个分区启用 ROW 和 PAGE 压缩。因此，可极其灵活地选择要压缩的表、索引和分区，在空间节省和 CPU 影响之间取得巧妙的平衡。图 7 显示了针对销售表（通过对齐索引分区）实现的这一平衡。
Figure 7 具有不同压缩设置的分区表
Figure 7 具有不同压缩设置的分区表
每个分区代表一个季度，其中“十月-十二月”为最后一个季度。假设头两个分区的访问频率不高，第三个分区为中等频率，最后一个分区的访问频率最高。此例中，一个可能的配置为前两个分区启用 PAGE 压缩，这样空间节省最大且对工作负载性能造成的影响最小，对第三个分区使用 ROW 压缩，最后一个分区不使用任何压缩。
可使用 Alter Table 或 Alter Index 数据定义语言 (DDL) 语句来联机或脱机启用压缩。SQL Server 还提供用于估计空间节省量的存储过程。所获得的空间节省取决于压缩对象的数据分布和架构。
许多客户数据库的测试结果均显示，大部分客户都可将其数据库的大小缩小 50–65%，并且受 I/O 限制的查询的性能得到了显著改善。然而，估计对受 CPU 限制查询的性能影响则有点棘手，具体取决于查询的复杂程度。在 SQL Server 中，仅当访问索引或表时才会发生解压缩开销。如果扫描运算符的相对 CPU 开销低于查询的整体 CPU 开销（数据仓库情形通常都是这样），您会发现对 CPU 利用率的影响少于 20-30%。

分区对齐的索引视图
在 SQL Server 2008 中，分区对齐的索引视图允许您更加有效地在关系数据仓库中创建和管理摘要汇总，并在之前无法有效使用它们的情形中使用它们。因而改进了查询性能。通常，您会有一个按日期分区的事实表。会针对该表定义索引视图（或摘要汇总）以加快查询速度。如果切换到新的表分区中，针对该分区表定义的分区对齐的索引视图的匹配分区也会相应切换，并且为自动切换。
它是优于 SQL Server 2005 的一个重大改进，在 SQL Server 2005 中，必须丢弃针对分区表定义的所有索引视图，然后才能使用 ALTER TABLE SWITCH 操作来切换入或切换出分区。SQL Server 2008 中的分区对齐索引视图功能向您提供了针对大型分区表定义的索引视图的各项好处，而不必对整个分区表重新构建汇总。这些好处包括自动维护汇总以及索引视图匹配。

分区级锁升级
SQL Server 支持范围分区，即允许针对可管理性分区数据，或根据其使用模式对数据进行分组。因此，可按月度或季度等标准对销售数据进行分区。可将分区映射到自身的文件组，再将文件组映射到一组文件。它提供了两大好处。首先，可将分区作为独立的单元进行备份和恢复。第二，可根据使用模式或查询负载将文件组映射到慢速或快速 I/O 子系统。
数据访问模式是这里非常有趣的特点。查询和 DML 操作可能仅需访问或处理分区的一个子集。举例而言，如果要分析 2004 年度的销售数据，仅需访问相关的分区，理想情况下，不应受到并发访问其他分区数据的查询的影响（系统资源除外）。在 SQL Server 2005 中，并发访问其他分区中的数据可能导致将表锁定，从而影响对其他分区的访问。
为将该干扰降至最低，SQL Server 2008 引入了表级选项来控制分区级或表级的锁升级。默认情况下，启用表级的锁升级（如 SQL Server 2005）。但，您可覆盖表的锁升级策略。例如，可按以下所示设置锁升级：
Alter table <mytable> set (LOCK_ESCALATION = AUTO)
该命令指示 SQL Server 选择适合于表架构的锁升级粒度。如果表并未分区，则锁升级为表级。如果表已分区，则锁升级粒度为分区级。该选项还用作 SQL Server 反对表级锁粒度的提示。

结束语
SQL Server 2008 中提供了诸多有助于关系数据仓库决策支持查询提高性能的增强功能，本文仅做了简要阐述。但是，请记住，尽管决策支持查询的竞争性响应时间至关重要，仍存在其他关键要求，只是它们并不在本文讨论范围之内。
与关系数据仓库相关的一些其他功能包括：
  • 支持 T-SQL 中的 MERGE 语法，以使用一个语句更新、删除或插入（维度）数据并浏览数据库。
  • 优化了 SQL Server 引擎的日志记录性能，从而提高了 ETL 效率。
  • 将设置进行了分组，以便于在 T-SQL 中编写汇总决策支持查询。
  • 对备份进行压缩，以降低完整备份和增量备份的 I/O 需求。
  • 对资源进行监管，以控制对不同工作负载的系统资源分配。
请浏览 SQL Server 网页，以查看有关所有此类出色功能的详细信息，网址为 microsoft.com/sql。
在此，我们要特别感谢 Boris Baryshnikov、Prem Mehra、Peter Zabback 以及 Shin Zhang 为本文提供的技术与专业知识。

Sunil Agarwal 是“Microsoft SQL Server 存储引擎组”的高级项目经理。他负责并发性、索引、tempdb、LOBS、可支持性以及批量导入/导出。
Torsten Grabs 是 Microsoft SQL Server 团队“核心存储引擎”的高级项目经理主管。他拥有数据库系统方面的博士学历，并且在使用 SQL Server 方面有 10 年经验。
Dr. Joachim Hammer 是“Microsoft 查询处理组”的项目经理。他专门研究大型数据仓库应用程序的查询优化以及分布式查询、ETL 和信息集成。


 SQL Server: 最大程度降低 SQL Server 中的阻塞
SQL Server Cherié Warren

最大程度降低 SQL Server 中的阻塞
概览:
  • 发生锁升级的原因
  • 避免不必要的阻塞
  • 优化查询
  • 监视锁定对性能的影响

锁定对支持数据库的并发读写活动而言是必需的，但阻塞却会对系统性能产生负面影响，有时让人难以觉察。在本文中，我将介绍如何优化 SQL Server 2005 或 SQL Server 2008 数据库以最大程度降低
阻塞，以及如何监视系统以更好地了解锁定如何对性能产生影响。

锁定和升级
SQL Server® 根据受影响的记录数和系统中存在的并发活动来选择最合适的锁粒度。默认情况下，SQL Server 会选择尽可能小的锁粒度，如果它可以更高效地使用系统内存，则仅选择粗粒度锁。只有当锁升级会对总体系统性能带来好处时，SQL Server 才会升级锁。如图 1 所示，当特定扫描中锁的数量超过 5,000 或者系统用于锁的内存数超过可用容量时，将会开始升级：
Figure 1 促使锁升级的条件
Figure 1 促使锁升级的条件
  • 当锁设置为 0 时，数据库引擎使用 24 % 的非地址窗口化扩展（非 AWE）内存
  • 当锁设置非 0 时，数据库引擎使用 40 % 的非 AWE 内存
如果确实发生了升级，则始终会升级到表级锁。

避免不必要的阻塞
阻塞在任何锁粒度情况下都可能发生，但阻塞的显现程度却在升级后增加。锁升级可能是一个信号，说明您的应用程序在设计、编码或配置方面的效率不高。
遵循数据库设计基本原理（例如，使用采用窄键的标准化架构以及避免在事务性系统中执行大量数据操作）是避免发生阻塞的重要手段。如果未遵循这些原理（例如，将报告系统从事务性系统中分离出来，或在非工作时间处理数据馈送），则系统优化将会很困难。
索引编制可能是决定访问数据所需锁数量的关键因素。索引可以通过减少数据库引擎必须执行的内部查找次数来减少查询访问的记录数。例如，如果您从一个表的非索引列选择一行，则表中的每一行都需要被临时锁定，直到确定了所需的记录为止。但是，如果对该列编制了索引，则仅需要单个锁。
SQL Server 2005 和 SQL Server 2008 都包含动态管理视图（sys.dm_db_missing_index_group_stats、sys.dm_db_missing_index_groups、sys.dm_db_missing_index_details），这些视图根据累计使用情况统计来显示那些将会得益于索引的表和列。
碎片也可能是一个隐含的性能问题，如果碎片过多，数据库引擎可能需要访问比采用其他方式更多的页面。此外，不正确的统计信息也可能会导致查询优化器选择效率不高的计划。
请记住，尽管索引可以加快数据访问速度，但它们也会降低数据修改速度，因为不但基础数据需要修改，而且索引也需要更新。动态管理视图 sys.dm_db_index_usage_stats 重点强调索引的使用频率。一个常见的低效索引编制示例是复合索引，其中对同一列分别以单独和组合方式编制了索引。由于 SQL Server 从左到右访问索引，因此只要最左侧的列有用即可使用该索引。
分区表既可以优化系统（以便减少暴露的块），也可以将数据分成可以分别争取的单独物理对象。尽管启用行分区是一种较为直观的数据分离方法，但水平分区数据也是一种可供考虑的选项。您可能想通过将一个表分成多个行数和键值相同而列数不同的分离表的方式来选择进行反规范化，以降低不同进程在相同时刻试图独占访问数据的机会。
应用程序访问特定数据行的方法越多、该行中可能包含的列越多，列分区方法就越有吸引力。应用程序队列和状态表有时可以从这种方法中受益。SQL Server 2008 新增了按分区（如果没有为表启用分区则按表）禁用锁升级的功能。

查询优化
查询优化在提高性能方面起着举足轻重的作用。下面是可以采用的三种方法：
缩短事务 要想降低阻塞并改进整体性能，最重要的方法之一是确保事务尽可能小。任何不是很看重事务完整性的处理过程（如查找相关数据、编制索引以及擦除数据）都可以考虑减小其大小。
SQL 将每个语句都作为隐式事务。如果该语句影响大量的行，则单一语句仍可构成一个大型事务，尤其是当涉及许多列时或列中包含大数据类型时更是如此。如果填充因子较高或 UPDATE 语句要填充的列的宽度大于所分配的值，则单一语句可能还会导致页面分割。在这种情况下，将事务分割成行组非常有用，分割完后，每次处理一个直到全部处理完为止。仅当单个语句或语句组可以分成较小的批次（无论成功或失败，都可以视为完成了一个工作单元）时，才应考虑采用批处理方式。
对事务进行排序 在事务中，人为对语句进行排序可以降低发生阻塞的可能性。有两条规则应牢记。首先，应该以相同的顺序访问系统中所有 SQL 代码内的对象。如果顺序不一致，当两个竞争进程以不同顺序访问数据时就可能会出现死锁，导致其中一个进程出现系统错误。其次，将访问频繁或访问代价高昂的对象放置在事务末端。当事务中需要这些对象时 SQL 才会锁定它们。通过延迟对“热点”的访问，可以减少这些对象持有锁的时间。
使用锁定提示 锁定提示可在会话级别或语句级别用于特定的表或视图。使用会话级别提示的一种典型情况是数据仓库中的批处理操作，在此操作中，开发人员知道该进程将是在给定时间运行该数据集的唯一进程。通过在存储过程的开头使用诸如 SET ISOLATION LEVEL READ UNCOMMITTED 等命令，SQL Server 将不会保留任何读取锁，从而降低整体锁定开销并提高性能。
使用语句级别提示的一种典型情况是当开发人员知道脏读可以安全进行时（例如当从表中读取某一行而其他并发流程肯定不会需要该行时）或者当所有其他性能调整努力均失败（架构设计、索引设计和维护以及查询调整）而开发人员希望强制编译器使用特定类型的提示时。
如果监视结果表明已出现较大粒度锁，而其中很少有记录受到查询的影响，则行级锁提示可能会很有效，因为这可以减少阻塞的发生。如果监视结果表明当表中几乎所有记录都受查询影响时，较小粒度锁正处于被持有状态（而非升级），则表级锁提示可能会很有效，因为这可能会减少持有锁所需的系统资源。请注意，指定锁定提示并不能保证当锁数量达到系统内存阈值时不会升级。但是，这样做会阻止所有其他升级。

调整您的配置
如图 2 所示，配置 SQL Server 系统时需要考虑很多因素。
Figure 2 SQL Server 如何确定可用于锁定的内存量
Figure 2 SQL Server 如何确定可用于锁定的内存量
内存 锁始终保留在非 AWE 内存中，因此增加非 AWE 内存的大小会增强系统持有锁的能力。
由于 32 位体系结构受限于 4GB 非 AWE 内存而 64 位却无任何限制，因此应将 64 位体系结构作为尝试增强锁定能力时的首选。
在 32 位系统中，可以通过在 Boot.ini 文件中添加 /3GB 开关来从 SQL Server 的操作系统中获取 1 GB 的额外内存。
SQL Server 配置设置 影响锁定的各种设置均可通过 sp_configure 进行调整。锁设置可以配置在引发错误之前系统可以持有的锁数量。默认情况下设置为 0，这意味着服务器将动态调整其他竞争内存的进程所保留的锁。SQL 开始时将保留 2,500 个锁，每个锁占用 96 字节的内存。分页内存不会被使用。
最小和最大内存设置将保留 SQL Server 所使用的内存量，因此将服务器配置为静态占有内存。由于锁升级与可用内存有关，因此在判断是否会发生升级时，竞争进程所保留的内存量会对此产生影响。
连接设置 默认情况下，被阻塞的锁不会超时，但您可以使用 @@LOCK_TIMEOUT 设置，如果超过指定的释放锁等待阈值，则该设置会引发错误。
跟踪标记 两个跟踪标记都与锁升级密切相关。一个是跟踪标记 1211，它可以禁用锁升级。如果消耗的锁数超过可用内存，则会引发错误。另一个是跟踪标记 1224，它可以禁用单个语句的锁升级。

查看您的系统
更多参考资料
  • Inside Microsoft SQL Server 2005:The Storage Engine，作者：Kalen Delaney
  • 如何监视 SQL Server 2005 和 SQL Server 2000 中的阻塞
  • SQL Server 2005 性能统计脚本
  • 如何解决由 SQL Server 中锁升级导致的阻塞问题
  • 锁升级（数据库引擎）

对于块和锁，要监视其中的锁定对整体系统性能的影响，可在每次经过给定时间间隔（可能是一小时）后，轮询状态数据并捕捉被持有锁上的运行统计信息。要捕捉的关键信息包括：
  • 受影响对象、粒度和锁类型
  • 锁和块的持续时间
  • 发出的 SQL 命令（存储过程名称、SQL 语句 within）
  • 有关阻塞链的信息（如果相关的话）
  • 系统消耗其可用锁定能力的方式
您可以运行类似于图 3 所示的脚本来捕捉此信息，并将其写入具有相应时间戳的表中。要进一步降低被阻塞数据的 ResourceId，您可以运行类似于图 4 所示的脚本。
Figure 4 Learning more about blocked data (Close Figure 4)
DECLARE @SQL                           nvarchar(max)
      , @CallingResourceType           varchar(30)
      , @Objectname                    sysname
      , @DBName                        sysname
      , @resource_associated_entity_id int

-- TODO: Set the variables for the object you wish to look up

SET @SQL = N'
USE     ' + @DbName + N'
DECLARE @ObjectId int

SELECT  @ObjectId = CASE
                    WHEN @CallingResourceType = ''OBJECT''
                    THEN @resource_associated_entity_id
                    WHEN @CallingResourceType IN (''HOBT'', ''RID'', ''KEY'',''PAGE'')
                    THEN (SELECT  object_id
                          FROM    sys.partitions
                          WHERE   hobt_id = @resource_associated_entity_id)
                    WHEN @CallingResourceType = ''ALLOCATION_UNIT''
                    THEN (SELECT  CASE
                                     WHEN type IN (1, 3)
                                     THEN (SELECT  object_id
                                           FROM    sys.partitions
                                           WHERE   hobt_id = allocation_unit_id)
                                     WHEN type = 2
                                     THEN (SELECT  object_id
                                           FROM    sys.partitions
                                           WHERE   partition_id = allocation_unit_id)
                                     ELSE NULL
                                     END
                          FROM    sys.allocation_units
                          WHERE   allocation_unit_id = @resource_associated_entity_id)
                    ELSE NULL
                    END

SELECT  @ObjectName = OBJECT_NAME(@ObjectId)'

EXEC    dbo.sp_executeSQL
        @SQL
      , N'@CallingResourceType varchar(30)
      , @resource_associated_entity_id int
      , @ObjectName sysname OUTPUT'
      , @resource_associated_entity_id = @resource_associated_entity_id
      , @CallingResourceType = @CallingResourceType
      , @ObjectName = @ObjectName OUTPUT
Figure 3 Capturing locking stats (Close Figure 3)
SELECT  er.wait_time                      AS WaitMSQty
      , er.session_id                     AS CallingSpId
      , LEFT(nt_user_name, 30)            AS CallingUserName
      , LEFT(ces.program_name, 40)        AS CallingProgramName
      , er.blocking_session_id            AS BlockingSpId
      , DB_NAME(er.database_id)           AS DbName
      , CAST(csql.text AS varchar(255))   AS CallingSQL
      , clck.CallingResourceId
      , clck.CallingResourceType
      , clck.CallingRequestMode
      , CAST(bsql.text AS varchar(255))   AS BlockingSQL
      , blck.BlockingResourceType
      , blck.BlockingRequestMode
FROM    master.sys.dm_exec_requests er WITH (NOLOCK)
        JOIN master.sys.dm_exec_sessions ces WITH (NOLOCK)
          ON er.session_id = ces.session_id
        CROSS APPLY fn_get_sql (er.sql_handle) csql
        JOIN (
-- Retrieve lock information for calling process, return only one record to
-- report information at the session level
              SELECT  cl.request_session_id                 AS CallingSpId
                    , MIN(cl.resource_associated_entity_id) AS CallingResourceId
                    , MIN(LEFT(cl.resource_type, 30))       AS CallingResourceType
                    , MIN(LEFT(cl.request_mode, 30))        AS CallingRequestMode
-- (i.e. schema, update, etc.)
              FROM    master.sys.dm_tran_locks cl WITH (nolock)
              WHERE   cl.request_status = 'WAIT' -- Status of the lock request = waiting
              GROUP BY cl.request_session_id
              ) AS clck
           ON er.session_id = clck.CallingSpid
         JOIN (
              -- Retrieve lock information for blocking process
              -- Only one record will be returned (one possibility, for instance,
              -- is for multiple row locks to occur)
              SELECT  bl.request_session_id            AS BlockingSpId
                    , bl.resource_associated_entity_id AS BlockingResourceId
                    , MIN(LEFT(bl.resource_type, 30))  AS BlockingResourceType
                    , MIN(LEFT(bl.request_mode, 30))   AS BlockingRequestMode
              FROM    master.sys.dm_tran_locks bl WITH (nolock)
              GROUP BY bl.request_session_id
                    , bl.resource_associated_entity_id
              ) AS blck
           ON er.blocking_session_id = blck.BlockingSpId
          AND clck.CallingResourceId = blck.BlockingResourceId
        JOIN master.sys.dm_exec_connections ber WITH (NOLOCK)
          ON er.blocking_session_id = ber.session_id
        CROSS APPLY fn_get_sql (ber.most_recent_sql_handle) bsql
WHERE   ces.is_user_process = 1
        AND er.wait_time > 0
您还可以通过 SQL Profile（Lock:Escalation 事件）、dm_db_index_operational_stats 动态管理视图 (index_lock_promotion_count) 或系统锁定信息的定期轮询来监视系统升级。需要从升级监视中收集的信息主要是该流程能否保证升级；如果不能，相应的存储过程将查明产生性能问题的根源。具有大量数据或高并发使用量的表应作为主要升级对象。
在收集了有关锁定、阻塞和升级的数据后，可以对该数据进行分析以确定每个对象的累积块和锁时间（发生次数乘以发生时的持续时间）。通常，这可以启动性能调整的迭代循环，在此过程中将部署、监视、分析和修复变更。有时，它只需进行一个简单的改动（例如添加一个索引）即可显著改善性能并改变系统中会导致最令人头疼的性能瓶颈问题的区域。
有关降低 SQL Server 阻塞的更多信息，请参阅“更多参考资料”侧栏。如果在整个设计、编码和稳定阶段中始终注意尽可能使事务保持最小，则可以将许多阻塞问题降至最低。使用合适的硬件也可以显著降低出现不必要升级的可能性。不管怎样，系统中的当前阻塞评估都可以迅速确定其实际的性能问题。

Cherié Warren 是 Microsoft IT 的高级开发主管。她目前正负责领导 Microsoft 一个大型事务数据库的开发。Cherié 还经常探究阻塞产生的根本原因并着手解决与阻塞相关的性能问题。她作为一名企业级 SQL Server 数据库专家已有 10 年的时间。


 Microsoft Office: Access 数据库与 Sharepoint 集成
Microsoft Office Peter Serzo

Access 数据库与 Sharepoint 集成
概览:
  • Access 与 SharePoint 集成的优势
  • 向 Sharepoint 迁移 Access 数据
  • 使用 Sharepoint 扩展 Access 的功能

我与最终用户讨论 Microsoft Office SharePoint Server (MOSS) 2007 时，通常会请他们告诉我使用何种工具及如何使用这些工具。我发现的一个普遍现象是：
公司内一定会有部分人在使用 Microsoft® Office AccessTM 处理重要的业务。对于许多公司而言，Access 仍是主要的工具和重要的资产。
MOSS 2007 能让基于 Access 的应用程序充分发挥功效，并可将其集成到 SharePoint® 之中，从而产生一个功能突飞猛进的新解决方案。本文重点介绍 MOSS 如何与 Access 实现集成、两者的集成位置以及最终用户怎样配置它们形成解决方案。
MOSS 为 Access 引进的基础技术中包括工作流、常用存储库 (SQL Server®) 和 基于 Web 的界面（浏览器）。SharePoint 的功能包括文档管理、工作区、设置自定义列表、利用内置的工作流和现成的 Web 部件，其内容包罗万象：从广告活动、建立联系人列表或事件列表，到管理用户创建的表单，应有尽有。此外，由于采用的是最终用户所熟悉且使用便利的 Office 技术，使其感觉能运用自如。由此可见，MOSS 对正在使用的解决方案有益无损。由于不必重新编写应用程序，最终用户可以将精力集中在解决业务问题上，无需顾虑技术问题，从这个角度上，MOSS 还使效率大为提高。
受益的不只是最终用户。IT 部门和管理员需要帮助公司内各个最终用户维护其五花八门的自定义数据库，这是他们面临的一项艰巨任务。许多人只有在出现一定问题时（例如存储限制、多用户访问、安全、修复损坏的数据库、Web 使用、Access 版本不兼容及部署跨多个桌面的更改等），才意识到是在使用 Access 达成重大的业务目标。SharePoint 是解决上述症状的一剂良药。
虽然 Access 有其自身的局限性，但它的确有强大的功能且使用方便，尤其是对于不编写代码的人来讲更是如此。它为您汇集了可配置的关系表、简单查询（和复杂查询）、拖放式前端窗体创建器、基于数据的报告和配置多用户的功能。以 Access 和 SharePoint 为基础创建解决方案既适合需要集中资源和技能的组织，也适合想要利用原有应用程序和技能的个体。

入门
Access 2007 可通过几种途径与 MOSS 2007 集成。如图 1 所示，其中包括：从 SharePoint 列表导入数据、向 SharePoint 站点发布数据、创建 SharePoint 列表、使用 SharePoint 数据做为外部资源、将 Access 数据库迁移到新的或现有的 SharePoint 站点及脱机访问 SharePoint 数据。
Figure 1 Access 2007 可轻松与 SharePoint 实现集成。
Figure 1 Access 2007 可轻松与 SharePoint 实现集成。
最好先通过 Access 表创建 SharePoint 列表。SharePoint 列表与 Access 中的表格极为相似。它保存在 SQL Server 内容数据库中，包含特定的字段属性并支持查询。
创建 SharePoint 列表时请牢记一些限制条件：Microsoft 建议每个视图最多包括 2,000 项目以便取得最佳性能，SharePoint 不强制要求参考完整性，OLE 对象不会导入 SharePoint 且数据的验证受到限制。
要通过 Access 表创建 SharePoint 列表，首先选择“外部数据”选项卡，然后单击“导出”组下启用的“SharePoint 列表”按钮。现在您必须通过填写“导出 - SharePoint 站点”对话框来指定激活此列表的 SharePoint 站点（如图 2 所示），或在表上单击右键，然后选择“导出到 SharePoint 列表”。注意：如果表格是关系中的子项，还会导出所有父项表格。
Figure 2 Access 数据将导出至您指定的 SharePoint 站点
Figure 2 Access 数据将导出至您指定的 SharePoint 站点
导出完成后，您可选择保存导出步骤，这样就无需再重复这些步骤。此时，您可转到 SharePoint 站点并看到已上载的数据。通过这个简单的操作就能将数据移入 SharePoint 并使用户可以访问这些数据。由于数据现在保存于 SQL Server 数据库内，安全性得以提高；并且由于可通过浏览器访问信息，便利性也大为改进。
但是，事实证明将 SharePoint 中的表格链接为 Access 中的表格这种方法对于集成 Access 和 SharePoint 而言效率更高。要采用这种方法，单击 Access 中的“外部数据”选项卡，然后选择“导入”组下的“SharePoint 列表”。随即出现图 3 中所示的对话框。
Figure 3 将 Access 链接至 SharePoint
Figure 3 将 Access 链接至 SharePoint
选择将用做链接数据源的 SharePoint 列表所在的站点，然后选择想要链接的列表。完成此操作后，列表将显示为 Access 中的链接表，在应用程序的右下角您将看到“与 SharePoint 联机”指示符。现在 Access 与 SharePoint 之间是双向同步，支持从 SharePoint 或 Access 进行添加、更改和删除。如您所见，可以根据表格编写代码来支持更多的功能。
在 Access 中链接 SharePoint 列表后，您会发现默认还导入并链接了 Windows® SharePoint Services (WSS) 用户信息列表。同时创建一个称为“向 SharePoint 站点转移问题”的问题表。表格会为您显示所有数据冲突。
有关迁移数据和在转换期间如何处理数据类型的更多信息，请参阅“Access 如何转换 Access 和 SharePoint 数据类型”(office.microsoft.com/en-us/access/HP010477131033.aspx) 和“将 Access 数据库中的表格移动至 SharePoint 站点并建立链接”下的“迁移限制”一节 (office.microsoft.com/en-us/access/HA101314681033.aspx)。
集成表格和列表的第三种方式是通过 SharePoint 启动。选择列表，并单击“操作”选项卡下的“使用 Access 打开”。随即弹出对话框，询问数据库的名称（新的或现有的）。输入数据库的名称后，您可以选择仅链接到 SharePoint 站点上的数据，或将数据直接导出到 Access（请参阅图 4）。
Figure 4 让 Sharepoint 数据成为 Access 可访问的数据
Figure 4 让 Sharepoint 数据成为 Access 可访问的数据

将数据库移至 SharePoint
至此，我们已经研究了将 SharePoint 导入成链接的表格和将表格导出成 SharePoint 的列表，但是如果您需要访问整个数据库又该如何呢？许多组织都有在 Access 中运行的针对关键任务的应用程序，这些应用程序需要能远程访问以便个人能运行报告和查询并输入数据。在这种情况下，重新编写应用程序通常既不经济，也不是现有技能可完成的。SharePoint 和 Access 对此的解决方案是使用“访问 SharePoint 列表”选项卡下的“移至 SharePoint”选项。它类似于使用升迁向导移动至 SQL Server（最初于 Access 97 中引入）。
将 Access 数据库完整移至 SharePoint 的益处是：所有表格均转换成 SharePoint 列表；生成 Access 数据库的副本；列表自动成为 Access 中链接的表格；您可移动整个数据库，而不只是表格且数据库保持原有的工作方式。
单击“Move to SharePoint”（移动到 SharePoint）按钮之后，显示图 5 中所示的对话框。指定站点后，您需要决定是否选择保存数据库。如选择，会将整个数据库保存到选定的文档库中。这意味着整个数据库（包括表单、报告、查询和宏）保存在 SharePoint 中并可通过服务器访问。如果用户想要访问数据库，他只需浏览找到它所在的库并单击，数据库就会自动部署到用户的桌面上。
Figure 5 指定数据库移动的目标 SharePoint 站点
Figure 5 指定数据库移动的目标 SharePoint 站点
如果选择移动整个数据库，会在功能区下出现“发布更改”消息栏。这样，您可使对设计和数据的本机更改与服务器上的副本同步。如果不选择此选项，则只会将表格转换成列表并链接到 Access。在这种情况下，用户社区无法使用整个数据库，也不会将数据库备份为 SharePoint 中的对象。
选择其中一个选项后，可在您选择的整个 SharePoint 站点使用数据库及其相关信息。这也将自动创建一个名为“向 SharePoint 站点转移问题”的表格。该表会记录迁移导致的任何冲突。您可查看 Access 在向 SharePoint 站点上载表格时遇到的任何问题。

视图、窗体和报表
数据库移动完毕后，您会想测试其功能。首先确保显示了“与 SharePoint 联机”指示符。注意：Access 查询成为了 SharePoint 视图，SharePoint 视图与 Access 查询极为相似。
如果移动整个数据库，现有查询会复制到 SharePoint 内，成为视图。Access 用户知道编写查询可以查看数据的子集。了解如何在 SharePoint 视图中执行此操作有助于您理解 SharePoint 列表中数据的组织方式。
你可以创建的一个最有用的视图是 Access 视图。为此，请浏览找到您将创建视图的列表，选择“Views”（视图）>“Create View”（创建视图）。您会看到“Access 视图”选项，您可使用该选项根据列表创建窗体和报表。单击此选项并选择 Access 数据库，会弹出如图 6 中所示的对话框。如您所见，现在您可定义格式（窗体类型、PivotChart、PivotTable 或报表），完成后，它们会成为 Access 数据库中的链接窗体或报表。
Figure 6 创建 Access 视图
Figure 6 创建 Access 视图

脱机访问
在现实中，关键任务应用程序能力的扩大会带来投资回报。为扩大集成 Access/SharePoint 应用程序的使用范围，可以指出不必连接 SharePoint 就能进行使用。为了能提高灵活性，Access 2007 引进了脱机工作功能。在连接服务器前，信息缓存在数据库的本机副本中。要使用脱机数据库，单击功能区中“外部数据|SharePoint 列表”组内的“Work Offline”（脱机工作）按钮。
做好重新连接 SharePoint 的准备后，可选择“脱机工作”或“同步”。它们均会上载数据并提交冲突以供审核，选择“同步”时会上载数据，但应用程序仍是脱机状态。
对于“SharePoint 列表”组，您还需要了解其“丢弃更改”功能，它有两个选项：第一个是丢弃所有更改，但不更新 Access 中的 SharePoint 数据。第二个是丢弃所有更改并更新 SharePoint 数据（链接的列表）。

Access 模板
Access 2007 有几个预建的模板，用于帮助用户快速创建业务解决方案，单击表格组中“Create”（创建）选项卡下的“SharePoint Lists”（SharePoint 列表）按钮后，您就可以看到这些模板（如图 7 所示）。选择其中一项会为链接到 SharePoint 的表格自动定义架构。当前仅支持“联系人”、“任务”、“问题”和“事件”。这意味着如果您导出包含其中一种信息的表格，数据最终会成为对应的 WSS 内容类型（例如，事件对事件）。
Figure 7 选择列表的类型
Figure 7 选择列表的类型
您还可创建供 SharePoint 列表使用的自定义模板，或创建自身链接 Access 2007 数据库的 SharePoint 站点模板。这需要安装 Access 2007 Developer Extensions 并设置表格的 WSSTemplateID。此属性跟踪那个表格有等效的 SharePoint 列表模板。

Access 和元数据
使用增强型 Access 应用程序的企业通常不能或不愿将其所有应用程序移至 SharePoint。在这种情况下，可能有时需要在 Access 中编写代码以更新 SharePoint。您可以使用代码将 SharePoint 和 Access 结合在一起。
Northwind Trader 的数据库就是一个简单的示例，它存储着有关产品、供应商和客户订单的信息。每个产品一般都有供应商提供的一个 .pdf 格式的产品数据表。Access 数据库会跟踪产品数据表中包含的所有信息，例如地理位置、产品号、修订记录和公司部门代码。供应商和卖方应能通过 SharePoint 外联网访问此信息。
建立一个 SharePoint 站点，所有文档都会移至链接的文档库，但元数据字段没有内容（请参阅图 8），因为是在 Access 中跟踪数据（对此进行监控的人员非常熟悉 Access，不希望有变化）。
Figure 8 在 SharePoint 中查看 Northwind 文档，没有元数据
Figure 8 在 SharePoint 中查看 Northwind 文档，没有元数据
如图 9 所示，您可以使用 Access 应用程序添加 Visual Basic® for Applications (VBA) 代码来更新元数据。不必重新编写应用程序。员工既可以访问 Web，又能继续使用其所熟悉的工具，供应商可以依据其权限访问外联网（他们仅能看到有权看到的事项），不会出现并发或数据库大小问题。
Figure 9 使用代码更新元数据
Figure 9 使用代码更新元数据

内置安全性
将 Access 应用程序移入 SharePoint 的一个最大益处是能够充分利用 SharePoint 安全模型，它内置了 Active Directory® 验证。这样，就无需担心怎样通过创建架构和表格，然后添加用户来在 Access 应用程序中实现安全性。有了 SharePoint 列表，您就可以利用安全修整，用户只能看到允许看的项目，这是 SharePoint 中固有的属性。此外，如果有您不想移动到 SharePoint 的数据库元件，您可以不移动它们。
SharePoint 提供了基于角色的精细安全模型。确定数据库移动方法和目标位置时，您应在迁移前先设计站点和安全性。设置和测试权限也变得更为简单。此外，迁移的故障更少且 Access 数据库的效率也大为提高。

引用完整性
如果我漏掉了引用完整性，那就是我的疏忽。实际上，SharePoint 并不象 Access 那样强制要求引用完整。许多安装都在一定程度上做了规格化处理。要使这些用于关键任务的 Access 数据库正常工作，必须考虑到这一点。幸运的是，我们已经有了一些能增强现有系统的解决办法。
我在前面提到过，在您将数据库移动到 SharePoint 时，如果您移动子表，父表也会移动。此外，当 SharePoint 认识到字段选项是基于另一表格时，它会使用查询字段。例如，假定选择了一个客户且在 Northwind Trader 数据库中放入了订单。如果这些表格移入了 SharePoint，客户字段将成为订单列表中的查询。
级联更新/删除和更多复杂操作又会是怎样的情况呢？在这种情形下，可以考虑使用 SharePoint 及其工作流。还是以 Northwind Trader 数据库为例，假定客户调用后又取消了一份现有订单，这一操作会随后触发几个操作。必须恢复库存、通知供应商、与订单有关的员工必须跟踪客户、取消送货并更新帐目。其中涉及大量移动部件和协调工作。
通过使用 SharePoint Designer，可以在 SharePoint 中创建工作流，在订单状态更改时协助完成上述所有步骤。共有 22 个现成的工作流，它们可以组合并入数百项操作中。SharePoint Designer 对于推广站点和创建工作流而言都是很好的工具
如使用 SharePoint Designer 创建工作流，了解 Access 编程的用户可以使用其熟悉的技巧，这是它的一项最大优势。.这意味着创建 Access 应用程序的用户可轻松将其技能过渡并用于工作流创建。使用 SharePoint Designer 创建工作流时，不必编写代码，并且这些工作流的部署也非常简单。

Peter Serzo 是 CDW Berbee 的高级工程师。他的专长是为全球各家公司构建 SharePoint Enterprise 解决方案。


 编辑寄语: 致新老朋友
编辑寄语
致新老朋友

我们不得不在 本月伊始发布一条喜忧参半的消息。我们要向网络专家 Joseph Davies 道别了，他刚完成了自己在本期《TechNet 杂志》的专栏文章。能在无数 Windows 网络连接主题中得到 Joseph 这样专家的教诲令我们深感荣幸。Joseph 近期已在 Microsoft 担当新职，所以不得不与月刊告别了。《TechNet 杂志》的所有工作人员在此对他多年来做的贡献深表感谢，并祝他前程似锦。
虽然我们的网络专家离开了，但我们的刊物还要继续。下一期，我们将会推出一个新专栏，名为“深入剖析 SharePoint”。去年，我们收到了大量反馈，要求给予更多有关 SharePoint 的培训和指导。由于 SharePoint 是一项发展迅猛的新奇技术，发行月刊是一种理想的方法。Pav Cherny 将负责第一期，首先整体回顾 SharePoint 的基础结构。随后，我们将讨论安全性、可用性、性能、故障排除等。如果您有任何 SharePoint 方面的话题想与我们交流，请发给我们！请发送电子邮件至 tnmag@microsoft.com。
我们还要对两位资深编辑 Terrence Dorsey 和 Nancy Michell 表示深深感谢。Terry 和 Nancy 是我们的元老，在《TechNet 杂志》的成长历程中贡献了非凡的才智和经验。但是，从本期起，两人就要转到我们的姐妹刊物《MSDN 杂志》工作了。而我们将迎来《MSDN 杂志》的两位资深编辑：Matthew Graven 和 Sharon Terdeman，这两位编辑将在《TechNet 杂志》一展身手。幸运的是，Terry 和 Nancy 与我们相距不远，在《TechNet 杂志》今后的成长过程中，我们还会时常借助他们的才智和经验。
讲完这些家务事后，仍请您关注本期内容。即将发行的 SQL Server 2008 是本期的重点，我们讨论了它的各种新功能，这些功能可以帮助您存储、保护、管理和利用数据，随着数量和作用范围的增长，数据会成为您最重要的业务资产。 —Joshua Hoffman


 读者来信: 读者心声
读者来信
读者心声

强弱主机
2007 年 9 月的网络专家专栏 (technetmagazine.com/issues/ 2007/09/CableGuy)“强弱主机模式”提及启用或禁用弱主机的功能，但没有指出如何使用。它只是启用或禁用防火墙或设置注册表参数吗？有与其相关的注册表参数吗？
此外，本地访问配置需要两项信息：IP 地址和 IP 掩码。为何 Microsoft 将没有包含可选网关参数的配置视为无效？
—Milt B.
您可在 Windows Vista® 和 Windows Server® 2008 中使用图中所示命令配置强主机或弱主机行为（最先在 2007 年 9 月刊中发表）。没有对应的注册表项。在 Windows® XP 和 Windows Server 2003 中无法配置强主机或弱主机。IPv4 仅限弱主机；IPv6 仅限强主机。
至于您的第二个问题，界面上的 IPv4 或 IPv6 配置不需要通过用户界面或命令行配置默认网关或路由器。


 工具箱: 面向 IT 专业人员的新产品
工具箱
面向 IT 专业人员的新产品
Greg Steen

管理多台监视器
UltraMon
realtimesoft.com
由于液晶面板价格的下跌，似乎大多数系统管理员的工作台上都摆着至少两个（或者更多个）监视器，以便他们能随时监视不同的管理仪表盘。（如果您没有这样做，那么强烈建议使用这种方法 — 因为它可以让生活轻松许多！）但随着监视器的增多，您也会开始越来越多地使用鼠标，从而大大降低您的效率。因此，一个带键盘快捷方式且简单易用的显示器管理实用程序将大有帮助。Realtime Soft 出品的 UltraMon 即是此类工具中值得一提的一款实用程序，它支持从 Windows® 98 到 Windows Vista® 的各个 Windows 版本，包括 32 位和 64 位版本。
首次启动 UltraMon 时，您可能会注意到在每个应用程序窗口的角落处都出现了两个小图标。第一个图标可将应用程序窗口快速展开到多个监视器上，而第二个图标则可将应用程序转到另一个监视器上。您还会发现任务栏已扩展到每个监视器上，并且包含在该特定监视器上活动的应用程序。即意味着您不必再返回主监视器就可展开应用程序，并且在最大化和最小化应用程序时能立刻知道它将显示在哪个监视器上。
对于每个应用程序快捷方式，新的 UltraMon 选项卡允许您定义该应用程序应在哪个监视器上启动以及启动位置，因此可（例如）始终让 Microsoft® Outlook® 显示在左侧窗口，并让 Internet Explorer® 在右侧窗口中打开。作为 IT 专业人员，您很可能会从不同位置（如便携式计算机或家庭桌面）远程连接到您的工作站；但对于每个此类远程连接，都可能需要稍微修改一下显示器的桌面和分辨率。
幸运的是，UltraMon 还支持显示器配置文件，可利用它来在监视器上快速切换自定义视图。如果与需要或想要使用自定义视图的其他人员共享机器时，或者希望根据活动更改视图时，该功能都可以提供极大的便利。
如果运行的是 Windows 2000 或 Windows XP，则还可启用非常适合于执行演示的“镜像”功能，因为它允许您在主监视器上使用比演示监视器更高的分辨率，但仍在两个屏幕上镜像相同的应用程序活动。并且，如果尚未升级到 Windows Vista，还可利用此应用程序将屏幕拉伸到多个监视器上（Windows Vista 默认如此操作）。
其他显示功能 — 如到 Display Settings 屏幕的快捷方式、快速设置和切换系统主监视器的功能、切换到另一显示器配置文件 — 都可通过 UltraMon 系统任务栏图标进行快速访问。在此处，还可启动 UltraMon Options 窗口，可在该窗口中自定义“Smart Taskbar”、设置用于移动和更改窗口的热键以及将鼠标放到指定的焦点位置等等。

价格：单个许可证起步价为 39.95 美元。
The options window in UltraMon lets you set up hotkeys and manage your Smart Taskbar
The options window in UltraMon lets you set up hotkeys and manage your Smart Taskbar

书评
《Microsoft SQL Server 2005 Analysis Services》
informit.com
拥有大量客户群相关数据是一回事，理解并处理这些数据来得出有关这些客户的有价值且深入的统计数据则另当别论。要获得此类计算后得出的论点和预测，您需要一个动态且功能强大的商业智能解决方案。Microsoft 为商业智能和联机分析处理 (OLAP) 领域提供的一个解决方案是 SQL Server® 2005 Analysis Services。为帮助您充分利用此解决方案，《Microsoft SQL Server 2005 Analysis Services》一书提供了全面的指导。
无论是在考虑新的数据挖掘部署、从 Analysis Services 2000 升级到 Analysis Services 2005，还是由于您是数据库管理员，对这些工具能为您和您的组织实现的功能倍感兴趣，由 Py Bateman、Alexander Berger、Irina Gorbach 和 Edward Melomed 联名撰写的这本书都将是您的最佳选择。本书并未在商业智能的理论方法方面纠缠不清，相反地，它深入而翔实地介绍了如何在实际环境中使用、开发、部署和管理 Analysis Services。它提供的许多示例均以 Food Mart 2005（软件附带的一个示例数据库）为基础，以便您可在自己的测试环境中快速开始进行实验。
本书的简介部分介绍了 2005 版中包含的新功能，其中包括使用 Web 服务 XML for Analysis (XMLA) 通信的客户端-服务器体系结构、统一维度模型和可伸缩性改进。您还将初步了解 Food Mart 示例数据库和多维数据库的基础知识。接下来，通过学习数据定义语言 (DDL) XML、维度属性和层次结构以及多维数据集和多维分析的相关知识，创建数据模型。您还将了解到使用 Business Intelligence Development Studio 设计和开发 2005 Analysis Services 商业智能专家工作站的简介。
掌握这些设计概念后，接下来通过多维表达式 (MDX) 开始进行数据操作。除了解如何通过 MDX 查询数据外，您还将学习如何使用 MDX 函数、成员和单元格属性；处理空集和 null、子查询和子多维数据集；并学习如何创建和使用基于多维数据集的 MDX 计算以及使用存储过程扩展您的查询。本书随后探讨关键绩效指标 (KPI)、钻取和记分卡，它们均有助于深入了解业务增长、度量指标和目标的方方面面。
接着介绍数据的提取、转换和加载 (ETL) 过程，从中您不仅可以了解到如何将数据存入系统，而且还可以了解到如何优化聚合设计并使用主动缓存来提高性能。它还介绍了多维数据集和维度的物理数据模型，并且您将了解到如何使用 2005 Analysis Services 来处理每项工作。另外，您将学习如何扩展您的部署以满足业务需求，包括网络负载平衡、OLAP 场、链接的量度和维度组以及远程分区处理。
随后介绍查询执行的实际本质，使您更好地理解底层操作以帮助您改善应用程序的性能。它研究了从客户角度访问数据的这一过程以及可用于执行该操作的大量选项（如 XMLA、ADOMD.net 和分析管理对象 (AMO)）。您必须具备一定的编程知识，这样才能了解如何利用 Visual Studio 和商业智能 IDE 来创建自定义数据仓库应用程序。
最后一部分详细介绍 Analysis Services 安装的管理，包括使用跟踪工具 flight recorder 和 SQL Server Profiler 来监控系统的性能和运行状况。此外，本书还介绍了用于备份和恢复部署的各种选项，其中包括使用 DDL 命令备份您的数据库、通过 SQL Server 代理或 SQL Server Integration Services (SSIS) 实现自动化以及用于恢复丢失或损坏数据的技术。总之，这本 SQL Server 2005 Analysis Services 指南的内容非常全面且翔实。

价格：59.99 美元。

诊断数据库问题
ApexSQL Audit
apexsql.com/sql_tools_audit.asp
您可能知道故障排除问题或跟踪潜在破坏行为的第一步是收集与导致问题的事件相关的信息。如果参与过最终用户支持，您可能会相当熟悉用户们对“系统丢失数据”的抱怨。ApexSQL 出品的 ApexSQL Audit 可帮助您快速找出与 SQL Server 数据库有关的问题，该工具支持从 SQL Server 7.0 到 SQL Server 2005 的各个版本。
我想您从其名称也已猜出，此应用程序可跟踪所指定数据库的活动，然后可针对审核跟踪创建自定义报告以供分析。审核条目通过 SQL 触发器添加，且存储在一个自动生成的架构中。可选择将审核信息存储到与所监视数据相同的数据库中，或者将其存放到单独的数据库中。
可通过图形界面轻松完成审核架构（或称为体系结构）的安装（和删除）。为数据库建立审核计划相对比较简单：只需选择数据库、选择要监视的数据表和字段，然后单击按钮生成触发器即可。
应用程序允许修改项目的触发器模板，而我非常喜欢的一点是，模板编辑器为审核对象模型提供了类似 IntelliSense® 的功能，从而可轻松地自定义触发器的触发时间以及存储哪些信息。另一项不错的功能是可轻松地引用查找表，这样审计信息变得更加易懂，而不仅仅是一组含义不明的 ID。如果希望映射列，还可以将监视的字段名称映射到审核字段名称。
启动并运行该应用程序后，可通过用户界面快速查看当前应用的审核触发器，并且，如果需要，还可以通过单击来启用和禁用特定触发器。还可通过界面中现有的数据表视图来检查审核的覆盖范围。
如您所知，审核信息通常会非常冗长，因此需要制定一些信息管理计划来存档和修整审核数据库。ApexSQL Audit 提供一款数据管理工具，从而可通过单击删除所有信息、指定一组标准然后再删除或者制定一个基于标准的删除计划。
计划作业被自动创建为数据转换服务 (DTS) 程序包，并通过 SQL 代理定期执行。当然，拥有这些审核信息是一回事，能否使用它则是另一回事。幸运的是，ApexSQL Audit 还包含有非常强大的报告组件，可利用它来针对原子审核数据和该审核数据的聚合视图生成自定义筛选视图。生成报后之后，可轻松地打印报告或将其导出到 HTML、Microsoft Excel 或文本文件中。

价格： 起价 599 美元。
The look-up tables in ApexSQL Audit provide extensive audit information
The look-up tables in ApexSQL Audit provide extensive audit information

密码过期自动提醒
Password Reminder PRO v1.4
sysoptools.com/password-reminder-pro.html
您有没有注意到，从在组织部门中开始实行密码过期策略以来，支持团队的电话就一直响个不停？如果确实是这样，那您可以试试 SysOp Tools 提供的 Password Reminder PRO。这款简单的工具可与 Active Directory® 集成，并提醒您的最终用户其帐户或密码即将过期。
可设置三种不同的提醒，每种提醒都提供不同的基于文本或 HTML 格式的电子邮件模板。还可将最大密码使用期限配置为与 Active Directory 配置相同的天数，并配置提醒的发送时间以确保不会与高峰时间发生冲突。可利用测试模式来在不影响最终用户的情况下预览效果，以确保正确配置所有选项。
本实用工具还提供报告控制台，显示各种用户类别的数据表格视图：过期帐户、非活动用户、新帐户、已禁用帐户等等。可通过该报告控制台将所有信息导出到 XLS 文件中，以供日后查看。为对已发送电子邮件进行审核，Password Reminder PRO 还可以发送每日报告，提供有关哪些提醒已发送给哪位用户的信息。

价格： 100 个用户的许可证起价 249 美元。
Password Reminder PRO previews configurations before deployment
Password Reminder PRO previews configurations before deployment

简化远程故障排除
UltraVnc SC
uvnc.com/pchelpware/sc
执行故障排除或指导用户使用流程的最简单方法通常是实际在该机器上进行操作。但是，对于在世界各地均有分部的公司而言，通常并不可行。Windows 内置的远程桌面连接和远程协助工具可帮助您连接到环境中的某些机器。但要满足所有需求，可试试免费的 UltraVNC SC（由主流项目 UltraVNC 的制造商生产）。
与以前版本类似，UltraVNC SC 允许查看和控制远程机器；但是，此版本是一个仅 166K 的 UltraVNC 服务器，可将其配置并发送给最终用户。它不需要注册表项、不需要作为服务运行，并且不需要安装程序，因此对于最终用户来说，不需要任何安装或配置操作。用户只需双击可执行文件运行此微型 VNC 服务器即可，并且如有必要，可连接到该机器进行支持和管理。
但是标准 UltraVNC 服务器支持文件和目录传输，此 UltraVNC SC 仅支持文件传输。在安全性方面，通信可加密到 Microsoft Crypto API 级别（40 位或 128 位）。而且，此微型服务器不允许传入连接，它仅可由最终用户启动，并且仅能连接到将其发送到最终用户之前在配置中所指定的机器。
要创建自定义查看器，可量身订制几个文本配置文件和图形，然后运行名为 PCHelpware 的另一项目加载项安装中的批处理文件来生成可执行文件。虽然文档并不出色，但它还是向您介绍了如何完成这一相对简单的过程。最后，在使用后关闭连接时，此应用程序会自动卸载，所以它不会留下任何痕迹或安全漏洞。

价格：免费。

Greg Steen 是一位技术专家和企业家，酷爱钻研技术。他总是在寻找各种新工具，以帮助 IT 专业人员更轻松地进行操作、问答和开发。


 SQL 问题与解答: 数据库增长、使用 IFilter 和远程连接
SQL 问题与解答
数据库增长、使用 IFilter 和远程连接
Edited by Matthew Graven

提示：清除缓存
您是否曾想过为什么在测试环境中运行良好的存储过程，部署到生产 SQL Server 后却表现很差？此问题可能与缓存有关。将存储过程部署到生产环境之前，需先清除缓存的查询计划，再在测试环境中测试该过程，这样才能了解该存储过程在“冷”缓存环境中的工作情况。下面是几个非常实用的小技巧。
要清除 SQL Server 上的过程缓存：
DBCC FREEPROCCACHE
Go
通过查询列出所有缓存的计划：
Select * from sys.dm_exec_cached_plans
Go

问：我的数据库每天的流量都非常大，并且我不想使用自动增长，因为如果 SQL Server® 决定在高峰期间执行此操作的话，很可能造成超时。我希望执行一个定期任务来按已用空间的特定百分比扩大数据库文件。我应该如何做呢？
答：文件增长是一个大量磁盘 I/O 操作，并且如果 SQL Server 必须等待数据或日志文件扩展，则肯定会严重影响性能和响应时间。数据文件的默认增量是 1MB，日志文件的默认增量是 10%。对于非常繁忙的系统而言，此类增量可能根本就不够。此外，依赖自动增长可能产生磁盘碎片，因为数据或日志文件在磁盘上并非连续存放 — 这意味着响应时间可能比正常情况更长，因为数据实际分散在磁盘各处。
提供良好性能的关键是预先为数据和日志文件主动分配足够的文件空间。而这通常需要一些趋势分析和增长预测，并且由于文件将在磁盘上连续存储而产生更好的性能，同时避免了在高峰时期执行自动增长而耗费的 I/O 开销。通常应启用自动增长，因为如果数据或日志文件都已完全写满，那么将无法访问数据库。但请记住，应将自动增长视作安全保证而非用于管理数据库的功能。
应避免通过计划任务来定期扩展数据库文件，因为它也会导致在磁盘上出现非连续文件，从而降低性能。通过定期执行一个脚本来确定每个数据库的可用空间百分比（由 SQL 代理作业执行），并随后执行一个操作（如通过数据库邮件发送电子邮件警报），从而可实现主动监控。图中的代码提供了一个示例脚本，它展示了如何收集当前数据库的可用空间百分比。
生成警报后，可使用 ALTER DATABASE 命令通过脚本执行一次文件增长，并可使用 SQL 代理作业来将该操作安排在非高峰时间执行。尝试将文件增长到可预见的未来所需的大小，以避免将来执行很小的增量文件扩展。它还可用于确保所有数据库均未启用自动收缩 — 从而不必增加数据库收缩或增长环节。
—Justin Langford
确定数据库中的可用空间
-- Script to gather size, free space and
-- calculate % free space for current
-- USER database
DECLARE @size DEC(15,2)
DECLARE @free DEC(15,2)
DECLARE @result DEC(15,2)

SELECT @size = SUM(size)*1.0/128
FROM sys.database_files

SELECT @free =
(SUM(unallocated_extent_page_count)*1.0/128)
FROM sys.dm_db_file_space_usage

PRINT 'DB Size ' + CONVERT(VARCHAR(15), @size)
PRINT 'Free Space ' +
CONVERT(VARCHAR(15), @free)

SELECT @result = (@free/@size)*100

PRINT '% Free Space ' +
CONVERT(VARCHAR(15), @result)

问：我们公司在数据库内使用 varbinary 和 image 列存储了不同格式的文件。我听说 SQL Server 集成了可搜索这些不同文件格式的功能。我该如何配置 SQL Server 才能使用该功能呢？
答：该功能已内置于全文索引服务中。可通过此服务灵活使用 IFilter 接口，从而能开发并加载可从专有数据中提取有用信息的筛选器。这些 IFilter 也可用于其他产品（如 Microsoft® Office SharePoint® Server），以收集有关爬网文件的信息。
IFilter 由文件格式的创建者或第三方供应商提供。SQL Server 已包含一些 Ifilter（它们是在安装 FulltextService (FTS) 时加载的）— 包括用于 HTML 和 DOC 文件的筛选器。但是，还可以根据需要添加更多 IFilter。例如，可在 Adobe 网站上找到用于 Adobe PDF 的筛选器，并且 2007 年年底时还发布了用于 2007 Office 系统扩展的新筛选器包。请注意：必须了解需要哪个版本的 IFilter。例如，针对 32 位系统设计的 IFilter 无法用于 64 位的 SQL Server。
在客户端上运行安装程序软件包之后，IFilter 通常会在操作系统体系中注册。在操作系统中注册了位后，需执行以下几个步骤才能使 FTS 可加载 IFilter。启动查询执行工具后，运行以下命令：
  • sp_fulltext_service 'load_os_resources',1.（此语句将使 FTS 加载待处理的注册位，包括如断字器和词干分析器之类的组件。）
  • sp_fulltext_service 'verify_signature',0.（此语句将跳过 SQL Server，以检查所用筛选器是否已经过签名，因为许多供应商都未按标准对其筛选器进行签名。）
  • 重新启动 SQL Server 实例和 FTS 实例。
  • 针对列创建全文索引，将 binary 列作为 IFilter 的爬网内容，并且 SQL Server 使用 extension 列（表示存储扩展类型的列，如 DOCX）来选择将内容重定向到其中的筛选器。
更多信息，请访问 go.microsoft.com/?linkid=7912971。
—Jens Suessmeyer

问：我无法连接到远程 SQL Server。我是否需要在客户端或服务器上配置防火墙？
答：无法远程连接 SQL Server 2005 的原因多种多样，但防火墙配置是最常见的问题之一。SQL 协议博客 (blogs.msdn.com/sql_protocols) 提供了有关建立 SQL 连接的大量信息资源。
SQL Server 2005 的默认安装不允许远程连接。在运行 SQL 的机器上，从“开始”菜单上选择 Microsoft SQL Server 2005 |“配置工具”|“SQL Server 外围应用配置器”。然后，转到“服务和连接的外围应用配置器”，选择“远程连接”，并选中“同时使用 TCP/IP 和 named pipes”单选按钮。要使更改生效，必须重新启动 SQL。
默认情况下，SQL Server 使用端口 1433。要确认端口是否开启，使用以下 telnet 命令，并将 <ipaddress> 替换为运行 SQL Server 的机器的实际 IP 地址：
telnet <ipaddress> 1433
如果收到连接失败的提示，打开 Windows® 防火墙，转到“例外”选项卡，选择“添加端口”，添加 TCP 端口 1433。现在，Telnet 应可以成功连接。（请注意，Windows Vista® 不会默认安装 Telnet。）
—Rick Anderson
衷心感谢以下 SQL Server 专家，感谢他们为本专栏所做出的贡献：
Justin Langford 效力于 Coeo Ltd.，该公司是总部位于英国的一家系统集成商和 Microsoft 认证合作伙伴。Jens Suessmeyer 是 Microsoft 德国的一名数据库顾问。Rick Anderson 在“Microsoft 开发人员用户教育”部工作。Saleem Hakani 是一名 Microsoft 高级数据库工程师和 SQL Server 社区负责人。


 实用程序特别推荐: Web 能力分析工具
实用程序特别推荐
Web 能力分析工具
Greg Steen

Web 日志 和历史流量分析可以让您深入了解会出现何种流量，但如何才能确定您基础结构的实际承载量呢？这时，您需要一种工具来使您的基础结构机器应用程序栈达到临界点。免费的 Web 能力分析工具 (WCAT) 应运而生，它是一种轻量级负载生成实用工具，不仅能够重现对 Web 服务器（或负载平衡服务器场）的脚本 HTTP 请求，同时还可以收集性能统计数据供日后分析之用。其最新版本（撰写本文时为 6.3.1 版）支持 x86 和 x64 Windows 系统（x86：iis.net/downloads/1466/ItemPermaLink.ashx；x64：iis.net/downloads/1467/ItemPermaLink.ashx），而且它还支持 IPv6 网络。另外，WCAT 是多线程应用程序，并且支持从单个源控制多个负载测试客户端，因此您可以模拟数千个并发用户。
该实用工具利用您的旧机器作为测试客户端，其中每个测试客户端又可以产生多个虚拟客户端（最大数量取决于客户端机器的网络适配器和其他硬件）。您可以选择使用 HTTP 1.0 还是 HTTP 1.1 请求，以及是否使用 SSL。并且，如果测试方案需要，您还可以使用脚本执行的基本或 NTLM 身份验证来访问站点的受限部分。（如果您的站点使用 cookie、表单或基于会话的身份验证，那您可以创建正确的 GET 或 POST 请求来对测试用户进行身份验证。）WCAT 还可管理您站点可能设置的任何 cookie，所以配置文件和会话信息将永久保存。
WCAT can help you test the limits of your Web site infrastructure
WCAT can help you test the limits of your Web site infrastructure
WCAT 还提供了非常出色的用户指南，该指南可以帮助快速创建 Microsoft® .NET Framework 控制台应用程序，它可以根据来自站点流量审计历史的用户流量数据生成测试客户端脚本，并能在部署前于新代码库中模拟真正的流量。而且，如果您的同事中有 C 程序员，那您还可以创建自定义函数和响应处理程序，供方案文件调用以便为环境量身定制功能。
要使用 WCAT，您需要配置两个文件：一个包含通用测试设置（如客户端数量、每个客户端上的虚拟客户端数量、用于跟踪的性能计数器和测试需要的 Web 服务器）的控制器文件，以及一个包含测试方案、默认请求参数和自定义函数和库引用的方案文件。
该应用程序将测试结果记录到 XML 文件，您可以应用内置的 XSL 样式表单在 Internet Explorer® 中查看到组织好的结果表格。该报告包含摘要信息，如执行的事务数量、上下文切换次数、CPU 利用率百分比（所有 CPU），以及遇到的错误总数等。您还可以得到在设置文件中配置的性能计数器的结果（参见屏幕快照示例）、响应时间分析、以事务为单位的统计报告、以客户端为单位的明细数据，以及有关如何配置测试设置的信息。另外，您将查看到您所测试的远程 Web 服务器的硬件配置，以及已安装的所有更新的列表。该列表能够很好地帮助您确定并跟踪某个补丁程序是否会对您的站点产生性能影响。
综上所述，如果您负责管理 Web 站点基础结构，那 WCAT 实用工具可以帮助您在下一次大型代码发布之前深入了解您的平台在压力测试下的工作情况。

Greg Steen 是一位技术专家和企业家，酷爱钻研技术。他总是在寻找各种新工具，以帮助 IT 专业人员更轻松地进行操作、问答和开发。


 网络专家: NAP 强制故障排除
网络专家
NAP 强制故障排除
Joseph Davies

新的网络访问保护 (NAP) 平台内置于 Windows Vista、Microsoft Windows 2008 和 Windows Server XP SP3 操作系统，它可以强制实施计算机运行状况要求，帮助保护您的专用 Intranet。NAP 的关键组件是 NAP 客户端、NAP 强制点和 NAP 运行状况策略服务器。
NAP 客户端是一台能够提供运行状态信息的计算机，这些信息将用于评估系统的运行状况。NAP 强制点是一台计算机或网络访问设备，它使用 NAP，或者可以与 NAP 一同使用来要求对 NAP 客户端的运行状况进行评估，并提供受限网络访问或通信。NAP 运行状况策略服务器是运行 Windows Server® 2008 和网络策略服务器 (NPS) 服务的计算机，它可以存储运行状况要求策略并评估 NAP 客户端的运行状况。NAP 运行状况策略服务器和 NAP 强制点与远程身份验证拨号用户服务服务器和代理消息交换系统运行状况信息和受限访问指令。
在本专栏中，我将介绍运行状况要求策略的组件，NPS 服务如何处理 NAP 评估传入请求，以及如何排除 NAP 强制的最常见故障。

运行状况要求策略
NAP 运行状况评估的工作原理
NAP 运行状况策略服务器上的 NPS 服务使用以下流程评估运行状况：
  1. NPS 服务将传入请求消息与为其配置的连接请求策略组进行比较。对于 NAP，请求消息应该与指定 NPS 服务本地执行身份验证和授权的连接请求策略匹配。
    2. 连接请求策略还会影响连接要求。例如，对于 802.1X 和 VPN 强制，连接请求策略要求使用以受保护的可扩展身份验证协议 (PEAP) 为基础的身份验证方法。如果正在连接的客户端不使用 PEAP，则连接请求将被拒绝。
  2. NPS 服务评估请求信息中的运行状况信息，该请求信息由包含运行状况信息的系统运行状况声明 (SSoH) 组成。NPS 服务将运行状况信息传递至其上安装的 SHV，而 SHV 将把运行状况评估信息返回给 NPS 服务。
  3. NPS 服务将请求消息和来自 SHV 的运行状况评估信息与相应的网络策略组进行比较。运行状况评估信息与基于 NAP 的网络策略的运行状况策略条件进行比较。运行状况策略条件指定运行状况兼容或不兼容的条件。NPS 服务将第一个匹配的网络策略应用到请求消息。
  4. 根据基于 NAP 的匹配网络策略及其相关的 NAP 设置，NPS 服务将创建系统运行状况声明响应 (SSoHR)。此响应包括来自 SHV 的运行状况评估信息，并指明 NAP 客户端的访问是否受限制，以及 NAP 客户端是否应该自动尝试修正其运行状况。
  5. NPS 服务将把 RADIUS 响应消息和 SSoHR 发送给 NAP 强制点。如果客户端的访问受限制，则响应消息还可以包含指定 NAP 客户端访问受限情况的指令。
  6. NAP 强制点将 SSoHR 发送到 NAP 客户端。

运行状况要求策略是连接请求策略、一个或多个网络策略、一个或多个运行状况策略和用于 NAP 强制方法的 NAP 设置的组合。要创建一个运行状况要求策略，需要使用“网络策略服务器”管理单元中的“配置 NAP 向导”。（有关评估流程的更多信息，请参阅“NAP 运行状况评估的工作原理”侧栏）。
连接请求策略 这些策略是有序的规则集，它们使 NPS 服务能够确定某个传入连接请求是应该本地处理，还是转发到另一个 RADIUS 服务器。NAP 运行状况策略服务器本地处理连接请求。
从基于 Windows® 的 NAP 强制点传入的 RADIUS 请求可以包含源标记，该标记用于指定 NAP 强制点的类型，如动态主机配置协议 (DHCP) 服务器或虚拟专用网络 (VPN) 服务器。
如果传入请求消息包含源标记，则 NAP 运行状况策略服务器上的 NPS 服务将尝试仅匹配那些带有匹配来源的连接请求策略（忽略所有其他连接请求策略）。如果传入请求消息不包含源标记，则 NPS 服务将尝试匹配那些带有非指定源的连接请求策略（忽略所有其他指定了来源的连接请求策略）。
例如，来自启用 NAP 的 DHCP 服务器的传入请求指定了 DHCP 的源标记。NPS 服务尝试将来自 DHCP 服务器的请求与带有 DHCP 来源的连接请求策略进行匹配。来自启用 802.1X 的交换机和无线接入点的传入请求不指定源标记。NPS 服务尝试将这些请求与不带指定来源的连接请求策略进行匹配。
用于本地或远程处理评估的连接请求策略是应用到传入请求的策略子集有序列表中第一个匹配的连接请求策略。如果请求与所有连接请求策略都不匹配，则该请求将被拒绝。
网络策略 这些策略是有序的规则集，它们指定在何种情况下允许或拒绝与传入请求消息对应的连接尝试。每条规则都包含授权访问或拒绝访问的访问许可、一组条件、一组限制及网络策略设置。如果授权连接，则网络策略限制和设置可以指定一组连接限制。对于 NAP，网络策略可以指定运行状况策略条件以检查运行状况要求和强制行为设置。
正如连接请求策略一样，网络策略使用源标记来确定尝试使用哪条网络策略匹配传入请求。如果传入请求消息包含源标记，则 NPS 服务会尝试将请求仅与那些带有匹配源的网络策略进行匹配（忽略所有其他网络策略）。如果传入请求消息不包含源标记，则 NPS 服务将尝试匹配那些带有非指定源的网络策略（忽略所有其他指定了来源的网络策略）。
用于授权或运行状况评估的网络策略是应用到连接尝试的策略子集有序列表中第一个匹配的网络策略。如果尝试与所有网络策略都不匹配，则该请求将被拒绝。
运行状况策略 这些策略允许您根据已安装的系统运行状况验证器 (SHV) 指定运行状况要求，它们将用于运行状况评估，并确定 NAP 客户端是否必须通过任何或所有选定的 SHV。例如，兼容的 NAP 客户端的运行状况策略可以指定该客户端必须通过所有运行状况检查。而不兼容的 NAP 客户端的运行状况策略可以指定客户端必须有一项或所有运行状况检查未通过。
网络访问保护设置 设置包括安装在 NAP 运行状况策略服务器上用于运行状况要求和错误条件的 SHV 配置，以及修正服务器组，该服务器组指定可供不兼容 NAP 客户端访问的一组服务器，这些客户端对 DHCP 和 VPN 强制方法的网络访问有限制。

确定 NAP 强制故障的范围
逻辑方法对排除任何故障都会很有帮助。故障排除时要询问的一些常见问题包括：什么起作用？什么不起作用？起作用和不起作用的事件如何相关？不起作用的事件是否曾经起过作用？如果是这样，则自上次起作用以来做了什么更改？
显然，当处理有关 NAP 强制故障时，这些问题是当务之急。在部署 NAP 强制方法之前，连接是否正常？例如，在部署 IPsec 强制之前，Internet 协议安全性 (IPsec) 服务器或域隔离是否正常？在部署 802.1X 强制之前，802.1X 身份验证是否正常？部署 VPN 强制之前，VPN 远程访问是否正常？在部署 DHCP 强制之前，DHCP 是否正常？
另外，特定的 NAP 强制方法以前是否正常？如果是，那么 NAP 客户端、NAP 强制点或 NAP 运行状况策略服务器上发生了什么变化？从上述问题的答案中，您能够确定开始排除故障的项目，从而使您能够隔离引发故障的组件、层或配置问题。
为了对 NAP 强制问题进行一般故障排除，您需要确定问题的范围。第一步，指出是否是 NAP 强制出现了问题。对于 IPsec 强制，还需要确定 NAP 客户端是否已为 IPsec 对等协商和数据保护设置了正确的 IPsec 策略组。对于 DHCP 强制，需要确定 NAP 客户端是否能够与 DHCP 服务器交换 DHCP 消息。对于 802.1X 和 VPN 强制，需要确定 NAP 客户端是否能够成功进行身份验证。例如，如果您的 VPN 客户端无法对 VPN 连接进行身份验证，那将需要检验 VPN 客户端的身份验证设置和凭据。
如果您已经确定问题是 NAP 强制，那下一步是确定其范围。是否会影响应用所有 NAP 强制方法的全部 NAP 客户端？是否会影响应用特定强制方法的所有 NAP 客户端？是否会影响应用特定强制方法的所有 NAP 客户端和 NAP 强制点？是否会影响属于特定组成员的所有 NAP 客户端？该问题是否仅影响特定的 NAP 客户端？
例如，如果应用所有 NAP 强制方法的任何 NAP 客户端都遇到了问题，那很可能是因为 NAP 运行状况策略服务器上的配置出了问题。如果在应用特定 NAP 强制方法时，所有 NAP 客户端都遇到问题，则 NAP 客户端的组策略设置可能存在配置问题，或者是 NAP 运行状况策略服务器上特定 NAP 强制方法的运行状况要求策略出现了问题。如果只有特定的 NAP 客户端遇到 NAP 强制问题，则这些 NAP 客户端上可能存在 NAP 强制配置问题。

常见的 NAP 强制故障
NAP 资源
  • 网络访问保护简介
  • 网络访问保护平台体系结构
  • Windows Server 2008 中的网络访问保护策略
  • NPS 网络访问保护

无限制访问 如 NAP 客户端拥有无限制访问权限（即访问不受限制），可能是 NAP 运行状况策略服务器已将该 NAP 客户端评估为兼容的客户端。而这正是您所需要的。但是，也有可能因为 NAP 客户端没有接收到 SSoHR 而获得无限制的访问权限，通常在没有对 NAP 客户端进行运行状况评估时会出现这种情况。如果没有进行 NAP 运行状况评估，就不会有 SSoHR 发回到 NAP 客户端，该 NAP 客户端将会获得无限制访问权限。
例如，针对 DHCP 强制配置的 NAP 客户端会将其 SSoHR 发送给它的 DHCP 服务器。如果运行 Windows Server 2008 的 DHCP 服务器没有针对 NAP 进行配置，它就不会将运行状况评估请求消息发送给 NAP 运行状况策略服务器。此外，为那些无法到达 NAP 运行状况策略服务器的 NAP 配置的 Windows Server 2008 DHCP 服务器默认情况下将为无限制访问分配地址配置。
当 NAP 运行状况策略服务器由于传入请求匹配不需要 NAP 运行状况评估的网络策略而不执行运行状况评估时，也有可能导致无限制的访问。有关确定匹配 NAP 客户端请求的网络策略方面的信息，请参阅本专栏“分步排除 NAP 强制故障”一节。
受限访问 具有受限访问的 NAP 客户端已由 NAP 运行状况策略服务器评估为不兼容。如果 NAP 客户端本来应该获得无限制的访问却只获得了受限访问，那将需要根据与 NAP 客户端请求匹配网络策略对应的运行状况策略设置来检验 NAP 客户端的运行状况。
无自动修正 当正确配置时，NAP 客户端可以自动修正其运行状态。如果 NAP 客户端无法自动修正，则需要检验匹配 NAP 客户端请求的网络策略的 NAP 强制设置是否选中“Enable Auto-Remediation of Client Computers”（启用客户端计算机自动修正）复选框。
另一个可能会影响自动修正的问题是受限 NAP 客户端无法连接修正服务器下载更新。对于 IPsec 强制，需要检验修正服务器是否已应用了正确的 IPsec 策略。对于 802.1X 强制，需要检查匹配网络策略中用于指定访问控制列表 (ACL) 或虚拟局域网标识符 (VLAN ID) 的设置，并检验您的交换机或无线接入点 (AP) 的 ACL 或 VLAN 配置。对于 VPN 或 DHCP 强制，需要检查匹配网络策略中用于修正服务器组的设置，并确保所有修正服务器都配置为该组的成员。对于 DHCP 强制，需要确保 NAP 客户端的 DHCP 作用域选项配置正确，例如用于 NAP 用户类的 “默认网关”选项值。
无 NAP 支持评估 对于任何 NAP 强制方法，需要检验是否已在 NAP 客户端上启用了相应的强制客户端。对于 802.1X 和 VPN 强制，需要检验 NAP 客户端是否已对连接请求策略和 NAP 客户端启用的 PEAP 身份验证方法系统运行了状况检查（即选中“Protected EAP Properties”（受保护的 EAP 属性）对话框中的“Enable Quarantine Checks”（启用隔离检查）复选框）。
NAP 客户端无限制，但无法连接 Intranet 对于 IPsec 强制，需要检验兼容 NAP 客户端的 IPsec 策略和 intranet 计算机的 IPsec 策略是否都包含一组常见的协商和保护设置。对于 802.1X 强制，需要确认用于兼容 NAP 客户端的网络策略是为 intranet 而不是受限网络指定了 ACL 或 VLAN ID。检验您交换机或无线 AP 上用于 intranet 的 ACL 或 VLAN ID 配置。对于 VPN 强制，需要确保没有为兼容 NAP 客户端的网络策略设置限制 VPN 客户端流量的 IP 数据包筛选器。

NAP 强制故障排除分步指南
要为特定 NAP 客户端排除 NAP 强制故障，可以先配置 NAP 客户端，检查 NAP 客户端事件日志，然后转到 NAP 运行状况策略服务器以确定 NPS 服务如何处理 NAP 客户端的请求。
步骤 1：检查 NAP 客户端配置 NAP 客户端配置包含 Windows 服务、强制客户端和 NAP 强制专用设置。要显示 NAP 客户端状态和配置信息，可以使用 netsh nap client show state 和 netsh nap client show configuration 命令。
请注意，如果 NAP 客户端设置由组策略提供，则所有的 NAP 客户端设置都将由组策略指定，且所有本地 NAP 客户端设置都将被忽略。在这种情况下，可以使用 netsh nap client show grouppolicy 命令显示基于组策略的 NAP 客户端配置，并通过组策略进行更改。
对于运行 Windows Vista® 的计算机上的 IPsec 强制，可以使用 net start 命令检验 Network Access Protection Agent、IKE 和 AuthIP IPsec Keying Module，以及 IPsec Policy Agent 服务是否已启动。使用 netsh nap client show configuration 命令检验是否已启用 IPsec 依赖方强制客户端。如果需要，可以使用“NAP 客户端配置”管理单元启用 IPsec 依赖方强制客户端或使用 netsh nap client set enforcement 79619 enabled 命令。应该使用提升的权限从命令提示符下执行 Netsh nap client set enforcement 命令。
对于运行 Windows Vista 的计算机上的 802.1X 强制，可以使用 net start 命令检验 Extensible Authentication Protocol、Network Access Protection Agent、Wired AutoConfig（用于有线连接的 802.1X 强制）和 WLAN AutoConfig（用于无线连接的 802.1X 强制）服务是否已启动。
再次使用 netsh nap client show configuration 命令检验是否已启用 EAP 隔离强制客户端。如果需要，可以使用“NAP 客户端配置”管理单元启用 EAP 隔离强制客户端，或使用 netsh nap client set enforcement 79623 enabled 命令。检验是否已为有线或无线连接“受保护的 EAP 身份验证”方法的属性选择了“Enable Quarantine Checks”（启用隔离检查）复选框。
对于运行 Windows Vista 的计算机上的 VPN 强制，可以使用 net start 命令检验 Extensible Authentication Protocol、Network Access Protection Agent 和 Remote Access Connection Manager 服务是否已启动。
使用 netsh nap client show configuration 命令的输出检验是否已启用远程访问隔离强制客户端。如果需要，可以使用“NAP 客户端配置”管理单元启用远程访问隔离强制客户端或使用 netsh nap client set enforcement 79618 enabled 命令。检验是否已为 VPN 连接“受保护的 EAP 身份验证”方法的属性选择了“Enable Quarantine Checks”（启用隔离检查）复选框。
对于运行 Windows Vista 的计算机上的 DHCP 强制，可以使用 net start 命令检验 Network Access Protection Agent 和 DHCP Client 服务是否已启动。如果需要，可以使用服务管理单元或 Sc.exe 工具启动这些服务，并将其配置为自动启动。
使用 netsh nap client show configuration 命令的显示结果检验是否已启用 DHCP 隔离强制客户端。如果需要，可以使用“NAP 客户端配置”管理单元启用 DHCP 隔离强制客户端或使用 netsh nap client set enforcement 79617 enabled 命令。
步骤 2：检查 NAP 客户端事件日志 使用事件查看器管理单元检查由 Network Access Protection Agent 服务创建的事件日志。在运行 Windows Vista 的计算机上，使用事件查看器管理单元查看 Applications and Services Logs\Microsoft\Windows\Network Access Protection\Operational 中的事件。在运行带有 SP3 的 Windows XP 的计算机上，使用事件查看器管理单元查看系统事件日志中的 NAP 事件。
从 NAP 客户端事件中，能够获得 NAP 客户端运行状况评估的关联 ID。可以使用此关联 ID 或 NAP 客户端的计算机名称在 NAP 运行状况策略服务器上查找对应的运行状况评估事件。图 1 显示带有关联 ID 的不兼容 NAP 客户端事件的示例。
Figure 1 Windows Vista NAP 客户端事件的示例
Figure 1 Windows Vista NAP 客户端事件的示例
步骤 3：检查 NPS 事件日志 在 NAP 运行状况策略服务器上，使用事件查看器管理单元查看由 NPS 服务创建的事件，它位于 Windows Logs\Security log 目录中。要查看 NPS 事件，可以在事件查看器中打开“自定义视图”，“服务器角色”，然后单击“网络策略和访问服务”。要查看与事件相关的联机帮助主题，请单击事件“常规”选项卡中的“事件日志联机帮助”链接。
典型的 NAP 运行状况评估事件的事件 ID 为 6278（无限制访问）或 6276（受限访问）。根据 NAP 客户端的计算机名称（事件描述中“客户端机器”的“帐户名称”字段）或关联 ID（事件描述中“隔离信息”的“会话标识符”字段）找出相应的 NAP 运行状况策略服务器事件。
NPS 事件日志事件 6278 和 6276 包含关于 NAP 运行状况评估的信息，例如匹配的连接请求策略的名称（事件描述中“身份验证详细信息”的“代理策略名称”字段）和匹配的网络策略的名称（事件描述中“身份验证详细信息”的“网络策略名称”字段）。图 2 是事件 ID 6276 的“详细信息”选项卡示例，其中包含“Proxy Policy Name”（代理策略名称）、“Network Policy Name”（网络策略名称）和关联 ID（名为 QuarantineSessionID）。这是与图 1 中 Windows Vista NAP 客户端事件相对应的 NAP 运行状况策略事件。
Figure 2 NAP 运行状况策略服务器事件的示例
Figure 2 NAP 运行状况策略服务器事件的示例
如果没有与 NAP 客户端事件对应的事件，则需要检验 Network Policy Server 服务是否已启动，NAP 强制点是否已针对 NAP 正确进行配置并使用 NAP 运行状况策略服务器作为 RADIUS 服务器。请检验 RADIUS 消息是否可以在 NAP 强制点和 NAP 运行状况策略服务器之间传递。
通过执行这三个步骤，您应该能够顺利找出为什么您的 NAP 强制无法按照预期的方式工作。有关 NAP 的更多详细信息，请参阅“NAP 资源”侧栏。

Joseph Davies 是 Microsoft 的一位技术撰稿人，从 1992 年起一直从事 Windows 网络方面的培训和编写工作。他曾为 Microsoft Press 编写了八本著作，是每月在线 TechNet 网络专家专栏的作者。


 Windows PowerShell: 请在此处签名
Windows PowerShell
请在此处签名
Don Jones

在 2008 年 1 月的 Windows PowerShell 专栏中，我曾强调过为 Windows PowerShell 脚本进行数字签名的重要性。当时我还列举了一些假设情况，以说明任何非 AllSigned 执行策略都可能使您的环境出现重大安全漏洞。
但有一件事我没有详细做介绍，即如何在实际中为脚本签名。您可登录 technetmagazine.com/issues/2008/01/PowerShell 浏览该专栏。猜猜这个月我要讲些什么？

不仅仅是签名
签名一词相对于我要论述的内容而言是一个恰当的技术术语，尽管这个单词本身并没有真正透彻说明将要发生的情况。这里所说的签名脚本并不意味着您要批准或授权它，就像在合同或信用卡上签名那样。在数字化的安全世界里，签名是指一种过程，它将您的身份附加到某个对象上，并确保该“对象”的状态或条件未经过任何方式的修改。它完全以密码学为基础，密码学（至少在这种情况下）是以一对加密密钥开始的。
这些密钥指非对称密钥，因为它们彼此间互不相同。密钥对包括一个私钥（只能由您使用）和一个公钥（任何人都可以使用）。我将其做了一些简化，但基本来说，任何使用私钥加密的内容只能使用匹配的公钥来解密。
下面介绍它的工作原理。同样，在这里我还将使用一些简化的方法以方便讨论。我有一个想要进行签名的 Windows PowerShell® 脚本，同时还有一个证书，其中包含要用于对脚本进行签名的私钥。Windows PowerShell 本身有一个 cmdlet（我将在稍后对其进行讨论），它可以获取脚本和证书并执行实际的签名。当它执行此操作时，Windows PowerShell 会获取脚本并使用我的私钥来加密它。加密的副本显示为一些杂乱的文字，被添加到脚本底部作为一系列注释（请参见图 1）。我的身份信息也被编码（但未加密）加入到这些注释中—身份信息本身不必借助密码学即可读取。
Figure 1 位于脚本底部的签名区块
Figure 1 位于脚本底部的签名区块
稍后，当 Windows PowerShell 查看签名时，它将解码我的身份并使用它来获取我的公钥。由于只有我的公钥可以解密签名的其余内容，因此 Windows PowerShell 知道，如果它能够解密签名，则我肯定已经对其进行过签名。如果其他人也对其进行过签名，则我的公钥将无法解密此签名。签名被解密后，Windows PowerShell 会将脚本与被加密到签名中的副本进行比较。如果它们匹配，则认为签名是未经改动的。如果两个脚本不同，则说明签名被破坏，它将被认为是无效的。
签名就是通过这种方式来防止明文脚本被他人私自篡改的。请记住，尽管脚本自身很容易地就可以被改动，但是如果不使用我的私钥就无法更改签名来匹配更改过的脚本—但只有我有自己的私钥。
这就是最基本的技术流程简要介绍。事实上，签名能够并且的确包含更多的信息，例如我的公钥副本、有关发放该密钥的证书颁发机构 (CA) 的信息等等。但是我在本文中的描述显然指出了该流程的重要部分，并且强调了这一事实：即签名实际上可以防止您的脚本受到未经授权的修改。
关键的安全防范要素是切实保护好您的私钥—绝不要使其落入他人之手。在 Windows 中安装您的密钥时，应立即将其使用密码保护起来，以防恶意进程在您不知情的情况下使用您的密钥。智能卡可以提供更好的安全性，因为它们包含您的私钥。使用智能卡，您的私钥绝不会脱离开该卡片。您想要加密的数据通过其读卡器硬件传送到卡中，卡片自身的电路将执行加密过程并发回结果。

获得证书
本月 Cmdlet：Export-CSV
PowerShellCommunity.org 论坛的人员经常询问 Windows PowerShell 是否能导出到 Microsoft Excel®。当然能！Export-CSV cmdlet 可实现这一目的，因为 Excel 本来就可以打开、编辑和保存 CSV 文件。例如，如果您希望导出一个服务列表，只需运行 Get-Service | Export-CSV MyServices.csv 即可。实际上，您可以将 Export-CSV 附加到任何管道的末尾，该管道中的所有对象都将在您指定的 CSV 文件中终止。在默认情况下，Export-CSV 将标题行添加到文件的顶部，用来指定导出对象的类型。这一行会被注释掉，因此不会对 Excel 打开该文件产生影响。如果不希望导出该类型的信息，只需向 Export-CSV 添加 -notype 参数即可。此外，您可以添加 -force 参数，以便在不提示的情况下（默认是提示）强制覆盖同名的现有 CSV 文件，也可以添加相应命名的 -noClobber 参数以防止覆盖现有文件。

要签名脚本，您需要有一个特定类型的证书，即 Class III Authenticode 代码签名证书，获取该证书的途径主要有三种。第一种是使用组织的内部公钥基础结构或 PKI（如果有的话）。一个正确实施的 PKI 会使其根 CA 在组织的所有计算机中都是受信任的，这对于确保该 CA 所发放的证书在组织中的可用性是必需的。
Windows Server® 自 Windows® 2000 后就开始附带自己的证书服务器，因此您可以使用该软件创建自己的 PKI。一个完善的 PKI 实施需要做大量的规划，但是如果只需要一个以发放代码签名证书为唯一目的的 PKI，则不需要太多的工作。只需使用组策略将 CA 的根证书推送到您的计算机并使其信任该证书即可。
第二个选择是使用商业 CA。使用商业 CA 的一个优势在于，如果您选择其中一个主要 CA，则组织中的计算机可能已经配置为信任来自该 CA 的证书。（注意，Windows XP 在默认情况下信任大量证书，而 Windows Vista® 在默认情况下信任的证书要少得多）。一个常用的商业 CA 是 VeriSign (verisign.com)。还有其他一些也值得考虑，例如 CyberTrust (cybertrust.com) 和 Thawte (thawte.com)。
获得代码签名证书的第三种选择是使用 Makecert.exe 等工具来制作自己的自签名证书。它与 Windows Platform SDK 一起提供，安装在某些版本的 Microsoft® Office 中，在许多其他位置也可以找到它。自签名证书的优势在于它是免费的，并且不需要任何基础结构。但劣势也很明显，它只能在您自己的计算机上使用。但是如果只是出于对代码签名进行测试或进行一般性实验目的在计算机中启用脚本执行，则 Makecert.exe 不失为一种不错的选择。go.microsoft.com/fwlink/?LinkId=108538 提供了有关此工具的文档。请注意，此工具的许多版本在多年前即已存在，因此可能您的计算机运行的是较早的版本，其工作方式与文档说明会有些差异。
有了 Makecert.exe 后，您就可以通过从 Windows PowerShell 命令行运行类似下面的命令来创建自签名证书（在您阅读本专栏时不要让我发现有谁在使用 cmd.exe）：
makecert -n "CN=MyRoot" -a sha1 –eku
1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer
–ss Root -sr localMachine
然后运行以下命令：
makecert -pe -n "CN=MyCertificate" -ss MY
–a sh1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk
–c root.cer
Makecert.exe 将提示您输入用来保护密钥的密码，然后即开始创建证书。您可以在 Windows PowerShell 中运行此代码，以核实此安装过程：
gci cert:\CurrentUser\My -codesigning
这将在 CERT: drive（Windows 证书存储位置）中显示所有代码签名证书项目的列表。此外，所有这一切还将被记录在 Windows PowerShell 自身中。要查找该文档，只需运行 help About_Signing 然后向下翻阅几个屏幕即可。

签名脚本
现在您已获得了证书和脚本（出于测试目的，您可以只快速获取一个，如果需要的话），接下来就可以签名脚本了。使用 Windows PowerShell 非常容易实现，只需输入：
$cert = @(gci cert:\currentuser\my
-codesigning)[0]
Set-AuthenticodeSignature myscript.ps1 $cert
第一部分将检索首次安装的代码签名证书（如果安装了多个证书并希望使用第一个以外的其他证书，只需将 "0" 改为相应的数字即可）。第二部分签名文件（当然，您需要更改文件名以匹配自己的文件）。就这么简单！但是说实话，我发现 Set-AuthenticodeSignature cmdlet 这个名称显得稍微长了一些，这就是我创建一个名为 Sign 的别名的原因。现在，我只需运行：
Sign myscript.ps1 $cert
现在打开脚本，您将看到签名区块被插入到底部。尝试使用执行策略 AllSigned (Set-ExecutionPolicy AllSigned) 运行脚本，它应该能够正常工作。现在您可以修改脚本并保存它，但要确保没有再次对它进行签名。Windows PowerShell 现在应该会拒绝运行修改后的版本，因为签名已被破坏。

值得努力
相对于最终效果而言，这不是显得太过麻烦了吗？想要能为多项管理任务编写脚本,又不想支付 500 美元证书费或实施全新的基础结构要素,这样的要求是不是过分了？我也是一名管理员，我理解您的疑虑。但简单的回答就是：为它所付出的每一份努力绝对是值得的。
实际上要想确保安全几乎都会带来一定程度的麻烦。防病毒软件让人很痛苦，但是没有它您就无法安心工作。防火墙软件无疑是一个麻烦，但正如您所知，没有防火墙就不会有安全。另外 Windows Vista 用户帐户控制 (UAC) 也可能是一个麻烦，但是它可以使您的计算机更安全。我们的种种努力不都是为了得到这种改进的安全性吗？
Windows PowerShell 是一种功能强大的工具，和任何其他工具一样，它始终存在被恶意用户篡改成安全漏洞的可能性。这就是为何采取措施阻止这些恶意用户显得如此重要的原因所在。
代码签名是您可以采取的最佳措施，它不需要过多的投入。例如，我使用的是一个图形化的脚本编辑器，每次在我按“保存”时它都会自动签名我的脚本，因此代码签名对我而言是非常透明的。
即使没有这种别出心裁的编辑器，您也可以通过其他途径让它变得更加透明。例如，您可以为自己创建一个 Windows PowerShell 配置文件（在文档文件夹下名为 WindowsPowerShell 的文件夹中创建文件 Microsoft.PowerShell_profile.ps1），并将此函数添加到其中：
function sign ($filename) {
  $cert = @(gci cert:\currentuser\my
-codesigning)[0]
Set-AuthenticodeSignature $filename $cert
}
现在只需输入以下内容即可签名您的脚本：
Sign c:\scripts\myscript.ps1
当然，该配置文件脚本应该是您签名的第一个文件！最终原则就是通过几个步骤使脚本签名尽可能方便，避免使它成为一件麻烦事。
仅仅为了发布代码签名证书而部署一个专用服务器 PKI 不太值得。（要记住，您实际上不需要研究和规划您的 PKI，包括保护根 CA 和提供灾难恢复，特别是将它用于任何其他项目时）。如果您是需要在环境中运行脚本的唯一人员，则可以始终使用 Makecert.exe。请注意，About_Signing Windows PowerShell 帮助主题还包括有关保护 Makecert.exe 所生成证书的信息。

Don Jones 是《Windows PowerShell:TFM and VBScript, WMI, and ADSI Unleashed》的作者。您可以通过 PowerShellCommunity.org 网站与他联系。


 您好，脚本专家！: 再述数据库脚本
您好，脚本专家！
再述数据库脚本
The Microsoft Scripting Guys
下载这篇文章的代码: HeyScriptingGuy2008_04.exe (151KB)

您知道， 如果脚本专家们有弱项（嘿，我们说的是如果），那就是：我们对于所采取操作或未采取操作的可能后果担忧过多。我们行事时不是以自己为出发点，而是常常从他人的出发点着想。而且并未考虑这些行为对我们意味着什么。
例如，以有关数据库脚本的文章为例。坦白地讲，有关数据库脚本的文章对于脚本专家而言很难下笔。并不是因为数据库脚本很难；它实际上非常简单。问题在于脚本专家们并没有太多机会操作数据库；因此，每次写到数据库时，我们都必须停下来想想我们要做些什么。您可能很早以前就已经看出来了，思考肯定并非成为脚本专家的必要条件。
事实上，如果我们中有任何人开始就有这种想法，脚本专家可能就不会出现了。
那么，既然有关数据库脚本的文章令脚本专家们如此难以下笔，那么为什么还要写呢？答案很简单：我们担心的是如果我们停止撰写这些文章，会对其他人造成怎样的影响。当亚瑟·柯南道尔爵士决定将夏洛克·福尔摩斯写死时（通过在故事“最后一案”中让他坠下悬崖），他认为他只是除去了他不愿意再写下去的一个角色。结果一石激起千层浪。据某些报道称，当伦敦居民听到消息时，他们甚至在帽子和袖子上戴上了丧布。“最后一案”刊登在 1893 年的《海滨杂志》上；文章中止后，有 20,000 人取消了其订阅。
哎，真让人挠头。
脚本专家们担心，如果不再撰写有关数据库脚本的文章也会在全球造成类似的影响。我们不想造成这么多伤心和失望，并且肯定不希望你们中有 20,000 人取消订阅《TechNet 杂志》。因此，我们想要宣布脚本专家们会继续撰写有关数据库脚本的文章。什么时候写？嗯，现在如何？

向数据库添加记录
本月我们将向您展示一些极好的数据库使用小技巧。对，我们在 2007 年 9 月的专栏 (technetmagazine.com/issues/2007/09/HeyScriptingGuy) 中向您展示过一些技巧；但这次是新增的内容，脚本专家们还不至于差到一稿两投。
除非我们存在极大的侥幸心理。
我们首先来介绍通过一个简单的方法向数据库添加记录。假设我们有个名为 C:\Scripts\Inventory.mdb 的数据库，并且该数据库包含一个名为 Computers 的表。Computers 表包含以下字段：
  • ComputerName
  • SerialNumber
  • UserName
  • Department
现在，如何将一台新的计算机添加到该数据库中？请看一看图 1 中的代码。
Figure 1 Adding a record to the Computers table (Close Figure 1)
Const adOpenStatic = 3
Const adLockOptimistic = 3

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

objConnection.Open _
    "Provider = Microsoft.Jet.OLEDB.4.0; " & _
        "Data Source = C:\Scripts\Inventory.mdb"

objRecordSet.Open "INSERT INTO Computers (ComputerName, SerialNumber, UserName, Department)" &  _
    "VALUES ('atl-ws-07', '11234', 'Ken Myer', 'Finance')", _
        objConnection, adOpenStatic, adLockOptimistic
我们并不准备详细介绍该脚本的首行；如果需要该类背景信息，可参阅我们在脚本中心中提供的一些资源，网址为 microsoft.com/technet/scriptcenter。需要说明的是我们使用常量 adOpenStatic 和 adLockOptimistic 来控制记录集的游标类型和记录锁定。（是的，听起来令人印象深刻，但它的确相当简单。）在创建 ADODB.Connection 和 ADODB.Recordset 对象实例之后，我们使用以下命令来打开数据库：
objConnection.Open _
"Provider = Microsoft.Jet.OLEDB.4.0; " & _
"Data Source = C:\Scripts\Inventory.mdb"
顺便提一句，该命令打开的是 Microsoft® Access® 2003 数据库。要打开 Access 2007 数据库，改为使用以下命令：
objConnection.Open _
"Provider = Microsoft.ACE.OLEDB.12.0; " & _
"Data Source = C:\Scripts\Inventory.accdb"
并且，虽说有些跑题，但我们还是要指出：可使用类似以下的命令来打开 SQL Server® 数据库：
objConnection.Open _
"Provider=SQLOLEDB;" & _
"Data Source=atl-sql-01;" & _
"Trusted_Connection=Yes;" & _ "InitialCatalog=Inventory;" & _
"User ID=fabrikam\kenmyer;Password=34DE6t4G!;"
到现在为止，我们向您展示的都是样板代码；您很快就会发现，几乎所有的数据库脚本都始于这几行代码。我们要强调的部分实际是以下这行：
objRecordSet.Open _
  "INSERT INTO Computers " & _
  "(ComputerName, SerialNumber, " & _
  "UserName, Department) " & _
    "VALUES ('atl-ws-07', 'A14B1234', " & _
      "'Ken Myer', 'Finance')", _
        objConnection, adOpenStatic, _
        adLockOptimistic
现在，我们将使用 INSERT INTO 查询来将一条新记录插入到 Computers 表中。请注意，表名之后是拥有值的所有字段的名称，通过逗号分隔这些字段并用括号将所有名称括起来。
您可能会问：脚本专家说“拥有值的所有字段”是什么意思？这是个好问题。好的，我们假设尚未为这台新计算机指定 Department。假定数据库允许在 Department 字段中放入 Null 值，可将 Department 放在列表外并且不指定值。换句话说，可编写类似如下所示的一个查询：
objRecordSet.Open _
  "INSERT INTO Computers " & _
  "(ComputerName, SerialNumber, " & _
  "UserName) " & _
    "VALUES ('atl-ws-07', 'A14B1234', " & _
      "'Ken Myer')", _
        objConnection, adOpenStatic, _
        adLockOptimistic
说到指定值，请注意紧随字段名称之后的是：关键字 VALUES，后面是要指定给每个字段的值（也括在括号中）。请记住：在列出字段名称时，可任意排定其顺序；例如，我们可将 ComputerName 放在最前面，即使它在数据库中可能并非第一个字段。对于字段名称可以这样，但对于值就另当别论。值的顺序必须与字段完全相同。如果列出的第一个字段是 ComputerName，则第一个值必须是计算机的名称。否则就会出问题。（例如，我们最终将用户名或序列号分配给 ComputerName 字段。）
正如您所见，指定值并不太复杂；只需确保根据数据类型格式化值即可：日期和字符串值应用单引号引起来；数字和布尔值则不应用单引号引起来。
对了，如果您的值本身就有单引号（如姓名 O'Brien)，需写两个单引号来“转义”它：
'O''Brien'
很奇怪的表示法，但事实的确如此。

从数据库删除记录
实际上，这相当酷：仅执行一个 SQL 查询就能向数据库添加记录。还有比这更好的事吗？不敢再奢望了。
这就很让人满意了，当然，要是还能使用单个查询来从数据库删除多条记录更就锦上添花了。
假设您的公司决定撤消其人力资源部。（这不是玩笑；Microsoft HR 部就常有这样的难题。）如何从存储数据库删除所有的人力资源计算机？图 2 显示了一种实现方法。
Figure 2 Deleting multiple records (Close Figure 2)
Const adOpenStatic = 3
Const adLockOptimistic = 3

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

objConnection.Open _
    "Provider = Microsoft.Jet.OLEDB.4.0; " & _
        "Data Source = C:\Scripts\Inventory.mdb"

objRecordSet.Open "DELETE * FROM Computers Where Department='Human Resources'", _
    objConnection, adOpenStatic, adLockOptimistic
正如您所看到的，该特定脚本的开头与用于添加新记录的脚本一样：定义一些常量、创建几个对象，然后连接 Inventory.mdb 数据库。 之后，只需使用 DELETE 查询删除 Computers 表的所有记录 (*)，或者至少其 Department 字段等于 Human Resources 的所有记录：
objRecordSet.Open _
  "DELETE * FROM Computers " & _
   "Where Department='Human Resources'", _
    objConnection, adOpenStatic, _
    adLockOptimistic
它就像掉下悬崖一样简单。
对不起，不是故意冒犯您的，福尔摩斯先生。

更新数据库中的记录
毫无疑问，所有人都认同删除人力资源部门的所有相关内容相当有趣。（请 Microsoft HR 部门注意：我们的意思是其他人和他们的 HR 部门感到有趣。不是我们。我们绝没有从中取乐的意思）。但是，从存储数据库删除所有 HR 计算机可能并非上策。为什么呢？嗯，除非您的 HR 员工将所有硬件都藏起来了（听起来他们可能会这么做，哈哈，请别介意；不是闹着玩的），这些计算机仍属于您的公司；即这些计算机应仍然列在数据库中。明确这一点后，执行以下操作。不再从数据库删除这些记录，而是仅更新每条记录；即将每台计算机的部门名称从 Human Resources 更改为 None。换句话说，运行图 3 中所示的脚本。
Figure 3 Updating records (Close Figure 3)
Const adOpenStatic = 3
Const adLockOptimistic = 3

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

objConnection.Open _
    "Provider = Microsoft.Jet.OLEDB.4.0; " & _
        "Data Source = C:\Scripts\Inventory.mdb"

objRecordSet.Open "UPDATE Computers Set Department = 'None' " & _
    "Where Department = 'Human Resources'", _
    objConnection, adOpenStatic, adLockOptimistic
和之前一样，该脚本唯一的不同之处是 SQL 查询。这次，我们使用 UPDATE 查询来更新 Computers 表中的记录。除 UPDATE 关键字外，需添加两个参数来告知查询如何更新记录以及更新哪些记录：
  • Set Department = 'None'.它仅指定了 Department 字段的新值。实际上，可使用类似以下的语法来一次设置多个字段值：Set Department = 'None', UserName = 'None'.正如您所看到的，它将把 Department 和 UserName 字段都设成 None。
  • Where Department = 'Human Resources'.它是一个标准的 Where 语句，指出了应更新哪些记录；在本示例中，即是 Department 字段等于 Human Resources 的所有记录。使用这条语句的原因很简单：我们不想修改数据库中的所有记录，仅修改之前属于人力资源部的那些记录（计算机）。
使用 Update 查询还能完成一件很酷的事。假设您的公司决定为每个人增加 10% 的生活补助。（脚本专家与亚瑟·柯南·道尔爵士至少有一个方面明显相似：在我们的作品中，都是些虚幻的事情。）以下脚本将打开一个名为 Employees 的表并修改每名员工的 Salary 字段。那么它究竟将 Salary 字段设成什么呢？此查询将该字段设置为员工的当前工资乘以 1.1；换句话说，为每名员工提供 10% 的涨幅。（就是这么简单！）具体查询如下：
objRecordSet.Open _
  "Update Employees " & _
  "Set Salary = (Salary * 1.1)", _
    objConnection, adOpenStatic, _
    adLockOptimistic
很酷的事吧？正如您所见，可在 Update 查询中执行计算。您决定要将所有临时雇员的合同期再延长 60 天吗？是的话可以使用类似如下的查询：
objRecordSet.Open _
  "Update TempEmployees " & _
  "Set ContractExpirationDate = " & _
  "(ContractExpirationDate + 60)", _
    objConnection, adOpenStatic, _
    adLockOptimistic

用于检索数据的超酷方法
说到可派上用场的查询，我们再研究研究从数据库检索数据的一些好方法。例如，以下就是一个简单但非常有用的脚本。假设 Inventory 数据库包含一个名为 Price 的字段，该字段从逻辑上足够代表计算机的价格。想知道您组织中最贵的五台计算机是哪些吗？图 4 中的示例脚本会告知您答案。
Figure 4 Sorting the recordset (Close Figure 4)
Const adOpenStatic = 3
Const adLockOptimistic = 3

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

objConnection.Open _
    "Provider = Microsoft.Jet.OLEDB.4.0; " & _
        "Data Source = C:\Scripts\Test.mdb"

objRecordSet.Open "SELECT Top 5 * FROM Computers Order By Price", _
     objConnection, adOpenStatic, adLockOptimistic

objRecordSet.MoveFirst

Do Until objRecordset.EOF
    Wscript.Echo objRecordset.Fields.Item("ComputerName")
    objRecordset.MoveNext
Loop

objRecordSet.Close
objConnection.Close
正如您所见，我们通过该 SQL 查询完成了两件事：按 Price 对记录集进行排序 (Order By Price)，选出前五个（也就是五个最贵的）计算机，即 SELECT Top 5 所实现的功能。如果需要前 10 个最贵的计算机的列表，使用以下查询：
objRecordSet.Open _
  "SELECT Top 10 * FROM Computers " & _
  "Order By Price", _
    objConnection, adOpenStatic, _
    adLockOptimistic
注意：我们还添加了一些代码，以遍历记录集并显示每台计算机的名称。之前的脚本并不需要此代码，因为那些脚本不返回也不显示数据。
也可使用以下查询获取前 10%：
objRecordSet.Open _
  "SELECT Top 10 PERCENT * " & _
  "FROM Computers Order By Price", _
    objConnection, adOpenStatic, _
    adLockOptimistic
现在，如果我们需要了解最便宜的计算机又该怎么办？没问题，只需使用相同的方法，只是此时以降序方式排序记录集（即从最低价格到最高价格）。换句话说，使用以下查询，并使用 DESC 来表示按降序方式排序记录集：
objRecordSet.Open _
  "SELECT Top 5 * FROM Computers " & _
  "Order By Price DESC", _
    objConnection, adOpenStatic, _
    adLockOptimistic
看到了吗？我们说过它们非常有用的。
还有两个您可能会觉得有趣的功能。假设您的数据库有个字段名为 Budgeted，用于跟踪计算机的最初预算金额。想要比较实际价格和预算金额吗？以下查询将返回价格高于预算金额的计算机的列表：
objRecordSet.Open _
  "SELECT * FROM Computers " & _
  "Where (Budgeted < Price)", _
    objConnection, adOpenStatic, _
    adLockOptimistic
同时，该查询会计算所有计算机的平均价格 (SELECT AVG(Price) FROM Computers)，然后返回价格低于平均价格的所有计算机的列表：
objRecordSet.Open _
  "SELECT * FROM Computers " & _
  "WHERE Price < " & _
  "(SELECT AVG(Price) FROM Computers)", _
    objConnection, adOpenStatic, _
    adLockOptimistic
是的，您说对了，我们确实在 Where 语句中使用了一个 SELECT 查询。它的工作原理是什么？那就是另一个故事了。但是，正如您所见，它可让您使用 SQL 查询来检索所有类型的超酷信息。

故事的内涵
正如我们在本月专栏开头提到的，我们并不确定是否会撰写另一篇有关数据库脚本的文章。但是，很高兴我们写了，部分原因是我们认为您会发现某些查询非常有用，但还因为：如果现在不写，迟早我们还是必须得写。就算是亚瑟·柯南道尔爵士，也不得不让夏洛克·福尔摩斯死而复生。亚瑟爵士尝试撰写了一些所谓发生在侦探死亡之前的新夏洛克·福尔摩斯故事。然后，迫于读者的压力，编造了一个有点可疑的故事来解释夏洛克·福尔摩斯谎报了自己的死亡。最终取得了相当圆满的结果。
更有趣的是，当最新的夏洛克·福尔摩斯故事面市后，又有 30,000 名新读者订阅了《海滨杂志》。英国和美国的发行商非常感谢亚瑟爵士，他也因此成为了全球稿酬最高的作者。
亚瑟·柯南道尔爵士带回了倍受喜爱的角色并成为全球最高稿酬的作者；现在脚本专家也带回了倍受喜爱的主题 — 并且无须伪造任何死亡事件。《TechNet 杂志》的忠诚读者们注意到这点了吗？

Scripto 博士的脚本谜题
每月一次的挑战！不仅测试您的解谜技能，还测试您的脚本编写技能。

2008 年 4 月：选择字母
在本月的迷题中，您需要在蓝色区域中插入 A 到 O 之间的字母，从而显示某个 VBScript 函数的名称。每个字母（A 到 O）应仅使用一次，并且字母不以字母顺序出现。插入的字母可位于函数名称开头、函数名称结尾或者函数名称中间的任意位置。例如，可通过以下代码行插入字母 D 以完成函数名称 IsDate：
现在您可以试试；插入 A 到 O 的字母来在此表格中显示 VBScript 函数名称：

Scripto 博士的脚本谜题
答案：选择字母，2008 年 4 月

The Microsoft Scripting Guys 为 Microsoft 工作，也就是受雇于 Microsoft。在玩、教或看棒球（以及各种其他活动）的闲暇之余，他们还负责维护 TechNet 脚本中心。要查看相关信息，请登录 www.scriptingguys.com。


 安全观察: 我的个人身份信息 (PII) 在哪里？
安全观察
我的个人身份信息 (PII) 在哪里？
Frank Simorjay

我们都认为 PII（个人身份信息）是需要保护的最重要的信息。但在您能够保护 PII 之前，您必须全面了解在 PC 上收集到的 PII。计算机上的所有信息都是敏感信息说起来很简单，但所有信息究竟是指哪些信息呢？
为了搞清楚这个问题，我们先稍微仔细地分析该问题，列出可能是敏感信息的数据类型，并找出这些数据最终会存储在计算机上的哪个位置。首先，信息的敏感程度因人而异。例如，某些人会为自己的名字出现在搜索结果中而感到恐惧。当然，除非您隐姓埋名，否则现在某人将您的名字以某种形式张贴在 Internet 上说不定会是很好的机会哦。为了进行调查，您会使用常用的搜索引擎在线搜索您的名字。请记住：您的名字越常见，就越难找到专门针对您的实例。这也许是件好事。
如果要在 Internet 上查找自己的信息，您可能会从一些流行的社交网站查起，例如 LinkedIn、Facebook 和 YouTube。Internet 保存和传播个人信息的能力会令您惊讶，过去这些信息通常需要费力搜索才能发现。
了解需要保护哪些信息是一门日益精深的科学。为了有所帮助，我想查看计算机上是否包含某些您没有意识到且可能希望加以保护的潜在个人信息一定会非常有趣。虽然您可能会说所有可用于窃取身份的个人信息都是敏感信息，但实际上信息确实可分为两种级别。一种是可供阅读的信息，另一种是更为隐密且一般认为与个人身份关系更密切的信息。
可供阅读的信息通常不会视作 PII。此类信息包括您的姓名，还可能包括您的电话号码、街道地址、电子邮件地址、性别、有时还包括您的工作地点以及一些教育信息。这些项目可在 Internet 上和公共目录（如电话本）中找到。泄漏此类信息（例如偶然允许垃圾邮件发送者获得您的电子邮件地址）可能会比较讨厌，但还不致于遭到身份盗用。
敏感信息包含更为隐私的数据，通过这些数据能够联系到您的身份。不希望公开的数据包括您的社会保障号（或其他由政府提供的唯一标识符）、银行帐户号码、信用卡号码（特别是有过期日期和持卡人 ID 的号码）、您的驾照号码和指纹（或其它与生物特征相关的信息）。如果这些项目落入别有用心的人之手，那可能会造成非常严重的后果。控制此类信息在 Internet 上和 PC 中记录和存储的位置及方式非常重要。为此，我现在将讨论两种简单的方法，通过它们可以找出可能存储在您系统硬盘中的所有 PII。

找出计算机中的 PII 数据
PII 信息散布在各个角落。事实上，只要检查一下垃圾，您可能非常容易就能找到一些 PII。保护这些信息需要认真和细心。我建议每个人都投资购买一台好的碎纸机，并把任何包含个人信息的材料都切碎。
但对于潜藏在您 PC 上 的 PII 该怎样做呢？找出这些数据与安全存储它们同样具有挑战性。Windows Vista®，以及其它几种桌面搜索工具可以帮助您找出系统中的此类信息。但您需要清楚要查找哪些信息。
为说明此问题，我将使用几种简单的工具来快速找出那些处于危险当中的信息。我将通过 Windows PowerShell® 使用脚本。Windows PowerShell 可以完成众多工作，字符串匹配就是其中非常出色的一项。我将集中讨论其匹配正则表达式的能力，这是我们所关注的重点。Windows PowerShell（可从 microsoft.com/powershell 下载）是一种功能强大的工具，它已迅速成长为管理任务的标准。
另外，我将使用 findstr.exe 管理误报，即能够忽略那些可能包含看起来很有意思（由于二进制文件中数据字符串的随机性）但是实际上毫无用处的字符串的文件。换句话说，本次练习中将忽略非文本文件。
我选择了两种合适的 PII 数据类型：社会保障号和信用卡信息。如果这些数据以明文形式存储在硬盘驱动器上，那很容易即可找出它们。这两种数据类型的结构和模式非常独特，足以使简单的脚本都能够找到它们。然而，这些数据也非常敏感，以至于我忍不住想问为什么需要将它存储在 PC 上。如果您确实需要存储此类信息，那您应该确保它们得到保护。随后我将介绍保护 PII 的方法。我在本文中的讨论非常有限 — 尚有其他很多重要 PII 数据类型未包含于此，如用户名和密码。

搜索社会保障号
以下是一个简单的字符串示例，它将在文件中查找包含标准美国社会保障号（结构为 XXX XX XXXX 或 XXX-XX-XXXX）的所有信息。使用 Windows PowerShell，您只需输入以下几行：
Get-ChildItem  -rec -exclude *.exe,*.dll |
select-string " [0-9]{3}[-| ][0-9]{2}[-| ]
[0-9]{4}"
也可以使用 findstr.exe，并通过使用以下代码确保搜索时不会读取二进制文件：
Get-ChildItem  -rec | ?{ findstr.exe
/mprc:. $_.FullName } | select-string
" [0-9]{3}[-| ][0-9]{2}[-| ][0-9]{4}"
在此示例中，Get-ChildItem –rec 将从执行该命令的目录开始递归搜索文件。Findstr.exe 在文件中搜索字符串，而 Select-string 是 Windows PowerShell 的字符串搜索函数。（Findstr.exe 也提供此处未讨论的类似功能。）此外，请注意正则表达式中的前置空格是必需的。它可以通过消除不必要的信息（如类似 HKLM\SOFTWARE\tool\XXX-XX-XXXX 的注册表字符串）来帮助减少误报。
该示例运行过程中，搜索模式将返回我放在子目录中的测试示例文件，同时它还找出了 XML 文件中的示例，这些示例指出了信用卡和社会保障号文件模式（请参见图 1）。
Figure 1 搜索号码模式得到的结果
Figure 1 搜索号码模式得到的结果
在第一个示例中，我使用排除功能丢弃了所有 .exe 和 .dll 文件，因为它们可能会产生不必要的干扰结果。您可能还会发现其他一些导致误报的文件类型。如果那样的话，您可以使用排除对搜索过程进行精细调整。
如果仅搜索具体的社会保障号，您可以使用以下代码（用您的社会保障号替换“123 45 6789”）：
Get-ChildItem  -rec | ?{ findstr.exe
/mprc:. $_.FullName } | select-string
"123 45 6789","123-45-6789"
此次搜索的结果如图 2 所示。
Figure 2 搜索具体号码
Figure 2 搜索具体号码

搜索信用卡信息
信用卡信息会麻烦一点，因为它的格式多变。而且我希望减少误报（即那些可能随机得到的类似信用卡号的结果）。尽管如此，此搜索可能还是会找出一些仅类似信用卡号码的随机序列。
在构建这些字符串时，我使用了 Michael Gilleland 在其论文“信用卡号码剖析”中提供的信息作为参考，（请参见 merriampark.com/anatomycc.htm）。例如，我的搜索字符串指定第一个号码必须是 4、5 或 6，因为这些数字通常定义为信用卡行业的主要标识符。
在此我已构造出用于搜索 Discover、MasterCard 和 Visa 卡的简单字符串。在 Windows PowerShell 中，搜索字符串类似如下所示：
Get-CchildItem  -rec | ?{ findstr.exe
/mprc:. $_.FullName } | select-string
 "[456][0-9]{15}","[456][0-9]{3}[-| ][0-9]{4}
[-| ][0-9]{4}[-| ][0-9]{4}"
在图 3 中所示的例子中，我使用 exclude 函数来消除 .rtf、.rbl、和 .h 文件的干扰。另外，示例代码查找的是不包含空格或短划线的信用卡字符串。但这样有可能得到过多的结果。因此可以使用同一函数的以下命令，但此命令不查找无空格或无短划线的卡号：
Figure 3 使用 exclude 函数消除干扰结果
Figure 3 使用 exclude 函数消除干扰结果
Get-ChildItem  -rec | ?{ findstr.exe
/mprc:. $_.FullName } | select-string
"[456][0-9]{3}[-| ][0-9]{4}[-| ][0-9]{4}
[-| ][0-9]{4}"
由于美国运通卡与普通信用卡有很大差异，所以我修改了对应的搜索字符串。在 Windows PowerShell 中，搜索字符串类似如下所示：
Get-ChildItem -rec | ?{ findstr.exe
/mprc:. $_.FullName } | select-string
"3[47][0-9]{13}","3[47][0-9]{2}[-| ][0-9]{6}
[-| ][0-9]{5}"
使用这种方式也可能得到过多的结果数据。因此可以使用同一函数的以下命令，但此命令不查找无空格或无短划线的卡号：
Get-childitem -rec | ?{ findstr.exe
/mprc:. $_.FullName } | select-string
"3[47][0-9]{2}[-| ][0-9]{6}[-| ][0-9]{5}"
当撰写本专栏时，我在自己的系统上运行了这些搜索，我吃惊地发现有几处社会保障号的实例保存在它不应保存的地方。事实证明，我曾记录过这些信息，但后来完全忘记了这件事。这使我重新考虑应该记录哪些内容，不应该记录哪些内容！
如果您确实需要以安全的方式存储这些信息，那请您尝试使用 Password Safe 这类工具（可从 passwordsafe.sourceforge.net 下载）。或使用 BitLockerTM Drive Encryption 这类工具加密硬盘。此外，面向移动 PC 的数据加密工具包提供了对移动 PC 上的数据进行保护的可靠指导。这些解决方案至少可以使那些想在您 PC 上查找个人信息的人较难得逞。

结束语
查找 PII 信息非常简单。保护此类信息是比较棘手的难题。但请时刻谨记：恶意软件或盗取您系统访问权的恶意用户如果能访问您的系统，他们也可以使用相似的发现技术非常容易地找到其中存储的个人信息。无论何时何地输入 PII 信息都需要千万小心，如果不得不存储这些信息，请确保对其加密。
非常感谢 Matt Hainje 帮助我排除 Windows PowerShell 脚本故障。

Frank Simorjay 是 Microsoft 解决方案加速器 — 安全性和法规遵从性小组的技术项目经理。他为 Microsoft 客户设计安全解决方案、在“安全世界博览会”（他是该活动的创始人）等活动中发表演讲、讲解安全课程和培训，并发表了多篇有关安全的文章和书籍。他的最新作品是“恶意软件删除初学者工具包”。


 桌面文件: 使用 WAIK 部署 Windows XP
桌面文件
使用 WAIK 部署 Windows XP
Wes Miller

客户所表现出的多样性实在是让人惊奇（甚至是令人生畏）。理想情况下，所有客户部署 Windows 的进度和版本均相同。这样肯定会使测试轻松得多。当然，事实并非如此。尽管你们中的某些人正在(或已完成)部署
Windows Vista®，或正满腔热情地准备在生产环境中部署首个 Windows Server® 2008 只读域控制器 (RODC)，仍有许多人一直提醒我（感谢他们）你们也在部署规划已久的 Windows® XP 和/或 Windows Server 2003 R2。
几天前，我收到读者的一封电子邮件，问：“Windows 自动安装工具包 (WAIK) 能否用于 Windows XP？在部署 Windows XP 时应如何使用 WAIK 呢？”好吧，我来试着回答这一问题。

再访 WAIK
就在一年前，我撰写过一篇有关 WAIK 的专栏，它是一套功能非常强大的工具，旨在帮助用户部署 Windows Vista (technetmagazine.com/issues/2007/01/DesktopFiles)。WAIK 现在也可处理 Windows Server 2008 部署，这两种操作系统均具有一个新的安装基础结构 — WAIK 中的工具大大有助于有效利用它们。并且，好坏暂且不论，Windows Vista 之前的 Windows 版本无论是使用无人参与安装还是 Sysprep，均要求您使用专门为其设计的工具。但是，我想再来看看 WAIK，重点介绍可用于帮助部署 Windows XP 的工具。
Windows PE 2.0 为了让大家了解一些基础知识，首先来看看我在 2008 年 2 月撰写的有关 Windows PE 2.0 和 Windows XP 双引导的专栏 (technetmagazine.com/issues/2008/02/DesktopFiles)。实质上，如果该情形中的 Windows PE 2.0 对您适用，则它也同样适用我在此描述的情况。您需要问自己的问题是：“对于 RAM 不足 512MB 或 Windows Vista 不支持高级配置和电源接口 (ACPI) 的那些系统，是否要部署 Windows XP？”如果答案为是，则需使用 Windows PE 1.6，并且必须确认它属于软件保障的内容。目前仅 Windows PE 2.0 和 2.1 为免费使用，版本 1.6 和更低版本则仍需要具有软件保障成员资格。
ImageX/WIM ImageX 和 Windows 映像格式 (WIM) 两者均设计用于自 Windows 2000 起的所有 Windows 版本，适用 NTFS 和 FAT 两种格式 — 因此，您当然可用它们来部署 Windows XP（或 Windows Server 2003）。
Windows 部署服务 Windows 部署服务 (WDS) 取代了远程安装服务 (RIS)，最初是作为带外 (OOB) 版本随 WAIK 1.0 提供，之后更新并集成到 Windows Server 2003 SP2 中。现在，Windows Server 2008 中随附了该服务，它具备了更多功能，并且仍然非常适合于 Windows XP 部署。
如果您使用的是 RIS 服务器或运行于旧模式的 WDS 服务器，那它就不太适合您。但是，如果您已开始向运行于混合模式或本机模式的 WDS 过渡，那没问题 — 应将 WDS 看做 Windows XP 部署的备选内容。
Windows 系统映像管理器 (WSIM) WSIM 实际只适用部署 Windows Vista 和 Windows Server 2008。如果要部署 Windows Server 2003 或更低版本，WSIM 的帮助则不大。

Windows XP 部署工具
Windows XP（就像 Windows NT® 4.0 到 Windows Server 2003 的所有 Windows 版本）可通过 unattend.txt 文件或“映像”进行部署。在本专栏中，我将不再讲述无人参与安装，因为它现在确实已经成为过去。如果要利用 WAIK（尤其是 ImageX），您执行的是基于映像的部署。因此，您需要的是 Sysprep.inf（Sysprep 的应答文件格式）而非 unattend.txt。
映像这一术语在此泛指如何获取 OS 图像。您以前很可能是使用 Ghost、PQDI 或其他映像工具。在 ImageX 之前，Microsoft 并未提供任何方法来获取经 Sysprep 处理的 OS 和应用程序，并将它们复制到一个或多个目标计算机中。
在构建 Windows 映像时，必须记住两点：
  • 除非需要在单处理器和多处理器之间转换，否则不能更改硬件抽象层 (HAL)。正如我在之前发布的专栏中提到的，在 ACPI 和非 ACPI 体系结构之间转换时，无法安全地更改映像。
  • 您可更改大容量存储控制器。通常人们都认为不能做此更改，但那是一种误解。但是，为实现这一目标，必须使用 Sysprep 来安装目标计算机可能需要的所有大容量存储控制器；部署后，除了“粘在”目标系统上的驱动器，需使用 Sysprep 删除其他所有控制器。我马上就会讲到这一点。
记住这两点后，就可制作某个系统的映像，并在使用相同或兼容 HAL 的任何目标系统上使用它。

使用的工具
只要在基于映像的部署方案中处理 Windows XP，都需要备妥以下三项以供使用：
Ref.chm 无人参与安装文本文件参照。请记住，在 Windows Vista 之前的任意 Windows 版本中配置可选组件的最佳时机是进行映像之前。然而，如果确实需要在安装后再安装可选组件，可通过运行 sysocmgr.exe 来达此目标（如 support.microsoft.com/ kb/222444 所述）。如果要部署 Windows XP Tablet PC Edition，请遵循 go.microsoft.com/fwlink/?LinkId=108589 中的步骤来创建单个映像，将 Tablet PC 组件安装到适合的系统上。
Sysprep 它是 Microsoft 支持的磁盘复制系统制作方法。我偶尔仍然会看到有人建议使用第三方安全标识符 (SID) 更改程序；我坚持建议使用 Sysprep，因为其他工具容易漏掉关键的 Windows SID 位置（特别是并非打开状态导出的位置）。
安装管理器 创建 sysprep.inf 文件最快捷最轻松的方法。按照惯例，请确保已准备了正确的版本 — 它通常应与要部署的 Windows 版本相同（例如，使用 Windows XP SP2 部署工具来部署 Windows XP SP2）。
Windows XP CD 上提供了以上三项。在 go.microsoft.com/fwlink/?LinkId=107541 上提供了更新版本。
还需准备 tap.exe。该实用程序包含在 Windows XP Embedded 工具中（go.microsoft.com/fwlink/?LinkId=108590），即使是免费的评估版也一样。在 Windows PE 下，tap.exe 会返回有关 Windows PE 找到的所有即插即用 (PnP) 设备的信息；最有趣的是，它会告知您 Windows PE 为设备所选择的 HAL（请参阅图 1）。这一点非常重要，主要原因是 Windows PE 用于选择 HAL 的逻辑与整个 Windows 安装程序用于确定放置哪个 HAL 的逻辑一样 — 因此，Windows PE 中的 tap.exe 非常有助于了解 Windows 为特定系统推荐哪个 HAL。
Figure 1 Tap.exe 实用程序会告知您 Windows PE 为特定系统所选择的 HAL
Figure 1 Tap.exe 实用程序会告知您 Windows PE 为特定系统所选择的 HAL

创建映像
通过完成以下步骤，可使用 ImageX（是的，可使用其他映像工具，但是您很快就会知道为什么 ImageX 是该特定工作流的理想工具）开始制作要部署的 Windows XP 映像。
第一步是收集所有必需的工具和组件，包括 Sysprep、安装管理器、ImageX 和 Windows PE（版本 2.0 或 1.6，具体取决于您的需求以及您的权限。请记住，如果要搭配使用版本 2.0 和 ImageX，则在创建您的分区时需使用 bootsect.exe 和 /nt52 开关，以确保您的引导代码与 Windows XP 兼容）。
当然，还需要安装有 Windows XP（任意 SKU）的 PC，以及 Windows 和任意其他已安装软件的最新更新项。理想情况是该系统之前应从未加入过域，这样以后出现域/网络问题的可能性更小。系统应仅安装了可映像的应用程序，没有会秘密存储机器名、SID、域或用户特定信息的应用程序，更改 SID 时，Sysprep 可能会漏掉或无法替换这些信息。此外，应使用您希望部署时最常用的 HAL。在较新的硬件上，通常是 ACPI 多处理器 (MP) HAL，因为现在基本流行的都是 ACPI 和多核（之前的超线程也使用 MP HAL）。
现在，按您为最终用户设定的方式配置 Windows XP 系统。安装希望大多数用户都具有的全部应用程序（以及无法以无人参与方式安装的应用程序）。安装或删除任意 Windows 可选组件，这样系统就会按您所需的最终用户方式安装。然后配置桌面。以“管理员”身份登录，并对配置文件进行修改，包括桌面背景、屏幕保护程序、“开始”菜单等等。默认情况下（从 Windows XP SP2 起），Sysprep 会将设置从“管理员”帐户复制到“默认用户”帐户。
接下来，运行安装管理器（请参阅图 2），指定要创建一个新的 Sysprep 无人参与文件并且完全自动化安装。请注意，由于您要运行安装管理器，因此需输入一个产品密钥。如果您手边没有或者希望稍后编写一个脚本（并且您没有批量许可证密钥），可指定在 Windows XP 或 Windows Server 2003 CD 上的默认 unattend.txt 文件中所提供的密钥（它允许完成安装但不允许激活）。
Figure 2 使用安装管理器创建 Sysprep 应答文件
Figure 2 使用安装管理器创建 Sysprep 应答文件
还需提供机器名。您可能希望在稍后使用 SQL 或其他方式来自动化这一过程，但是现在，在机器上部署 WIM 之后，只需在运行 Sysprep 之前输入一些值然后使用脚本来替换机器名即可。
请记住，如果要为“管理员”帐户提供密码，仅当映像中的现有“管理员”帐户没有密码时才适用。并且，请注意，域加入部分不允许加密域加入凭据。应尽可能使用最低权限帐户来设置机器帐户。最后，建议使用安装管理器中的“Version String”（版本字符串）选项来跟踪刚创建的映像“版本”。
现在，将 Sysprep.inf 文件放到包含 sysprep.exe 和 setupcl.exe 的 C:\Sysprep 目录中，并且将以下代码添加到 .inf 文件中：
[Sysprep]
BuildMassStorageSection = Yes

[SysprepMassStorage]
然后运行 Sysprep –bmsd。它会修改您的 sysprep.inf，并添加您的 Windows 安装程序所知道的所有大容量存储 ID（如图 3 所示）。如果希望添加其他设备，当然可以，或者可将它们添加到您的 Windows 安装程序并重新运行 sysprep –bmsd。
Figure 3 将大容量存储 ID 添加到 sysprep.inf
Figure 3 将大容量存储 ID 添加到 sysprep.inf
接下来，将 sysprep.inf 文件复制到共享中，然后运行 sysprep.exe –factory 并关闭您的系统。使用以下代码重新启动 Windows PE 并连接 UNC 共享（建议）：
NET USE Y: \\myserver\myshare
/USER:DOMAIN\USER password
现在，使用以下代码捕获映像：
ImageX /capture C: Y:\NewImage.wim
"Factory Mode capture from 4/1/2008"
然后关闭系统。
现在就拥有了可通过 factory 模式更新的映像。在此我就不介绍它的细节，简单地说，factory 模式是映像做好部署准备之前最安全的保存模式。有关详细信息，请参阅之前提及的 Windows XP deploy.cab 文档。
如果准备好制作映像以进行部署时（即一旦准备好实施），引导到 Windows PE 并使用 Diskpart 来创建所需分区。使用 format 命令来格式化分区，并根据需要使用 bootsect.exe 来应用 Windows Vista 之前的引导代码 (/nt52)。现在，使用以下代码连接到 UNC 共享（或使用 cd 命令进入映像所在的目录）：
NET USE Y: \\myserver\myshare
/USER:DOMAIN\USER password
然后按如下方式应用映像：
ImageX /apply Y:\NewImage.wim C: 1
最后，重启到 Windows Factory 模式并对映像进行所有必要的更新（此处需使用 winbom.ini 文件；如需帮助，请参阅 deploy.cab 中的 ref.chm）。Winbom.ini 应始终包含以下行，它们要求它重新密封准备在下次重新启动时运行 Mini-Setup 的映像：
[FACTORY]
ResealMode = Mini
完成后关机。重复之前用于捕获映像的步骤，但现在将 capture 命令修改为：
ImageX /append C: Y:\NewImage.wim "Resealed
and ready for deployment – captured 4/4/2008"
通过使用 /append，可节省相当大的空间。您刚才已将 factory 模式和重新密封映像结合到一起，因此可轻松地在两者之间切换。也可使用 /delete 来丢弃任何不想使用的映像。但是，请记住，这样不会节省空间，因为它只是丢弃对指定卷映像的参照。如果要清理未使用的空间，需导出希望保存的所有卷映像。
无论您要部署的是最新版本还是早期版本的 Windows，WAIK 均会对您有所帮助，尽管其设计目的和支持对象主要是 Windows Vista 和 Windows Server 2008。虽然需要结合使用 Windows XP 工具和 WAIK 工具（主要是 ImageX 和可能使用 Windows PE 2.0），Microsoft 现在提供了开始部署任意版本 Windows 需要的所有一切。

Wes Miller 是位于德克萨斯州奥斯汀市的 CoreTrace 公司 (www.CoreTrace.com) 的高级技术产品经理。在此之前，他在 Winternals Software 公司任职，并曾在 Microsoft 担任项目经理。您可以通过电子邮件 technet@getwired.com 与 Wes 联系。


 领域备注: 绝妙计划
领域备注
绝妙计划
Neil Fawcett

假设您的库房中有 5,000 台已翻新的 PC，并且许多客户已在排队等候购买这些机器。硬件现在有了新的使用期，但操作系统就完全另当别论了。是合法的副本吗？每台 PC 都有操作系统吗？你能转售吗？
新出台的 Microsoft Authorized Refurbisher (MAR) 计划能解决上述所有问题。它看似极其简单：帮助商业公司得到旧 PC，安装合法的操作系统，然后将其售出。
但该计划的目标不只如此。从实用角度讲，这是 Microsoft 和商业 PC 回收机构共有的商机。从法律角度讲，它可防止盗版（无论是有意还是无意）。从环保角度讲，实施这一计划后，不必再将可用硬件当成废品处理。最后，公司还可从中了解 Microsoft 的许可工作流程，特别是如何处理易手的 PC。
不仅是 Microsoft 和 PC 回收机构会从该计划中受益。客户也会从中受益良多：他们得到的 PC 已使用专业方法拭除了数据并预装了正版 Windows® XP Home Edition 或 Windows XP Professional；他们能访问下载项、更新和增强功能；并可访问 Windows 的新版本。要是没有这项计划，这样的机器很可能成为一堆产生污染的废物。
MAR 的适用对象是每月能平均供应 5,000 台翻新 PC 的公司，在加入该计划前，这些公司必须出示证据，表明它们曾翻新过这一数量的 PC。MAR 是一项全球计划，面向大 OEM 回收机构和其他总部位于美国或加拿大且满足条件的回收机构。Redemtech、Techturn 和 Apto Solutions 是参与了该计划的三家回收机构。
新软件产品的许可有时会令买卖双方疑惑，但翻新 PC 的市场还新增了一种复杂性，即您使用 Windows 的到期副本时会受到哪些限制。MAR 为回收机构减轻了这一复杂程度。它提供了一组安装工具，包括 Refurbisher Preinstallation Kit (RPK)，它能帮助各类翻新 PC 预安装 Windows XP。每个许可证都配有 Microsoft 的真实性证书 (COA)。如果翻新的 PC 有与其对应的 COA，且公司有原始恢复媒体或基于硬盘的恢复映像，则不需要新的 Windows 许可证。但是，如果商业回收机构没有恢复媒体或映像，MAR 可以帮助它们顺利完成流程。
通过捐赠、翻新或转售重新使用计算机意味着要不断了解技术，尤其是技术水平较弱的人群更是如此。它还有助于推进技术行业的环保意识。实际上，旧 PC 市场（也称为“二手 PC 市场”）已经为向发展中经济推广技术起到了促进作用。
翻新 PC 的市场一直在扩大，据预测，如果各家公司能找到备用方法，数百万台设备就不必被当成废物处理。MAR 不只是 Microsoft 的一处策略，更重要的是，它能帮助各大公司以低成本处置硬件，这会产生很大的收益。随着环保问题愈发受到重视，PC 的处置也成为重中之重。MAR 这类计划就是要老 PC 重焕活力，让它为寻求低成本技术的人发挥余热，并避免成为毒素之源。只需帮助验证一下软件许可，该计划就能让翻新的 PC 具备更大的吸引力。有关 MAR 计划的详细信息，请登录 microsoft.com/oem/mar。

Neil Fawcett 为多家出版物编著 IT 文章已有 20 余年。他还就这一主题做过多次讲座并出版了 13 本书。在其开始写作生涯前，他是硅谷的软件开发员和硬件工程师。


 Windows 机密: 平均分配
Windows 机密
平均分配
Raymond Chen

您是否曾问过： 为什么是在卸载程序时，Windows® 会问是否应该删除“可能会使其他应用程序无法正常运行”的文件？首先要说的是，此消息（如屏幕快照中所示）并不是来自 Windows 的消息，它实际上来自卸载程序。因此，正确的问题应该是“为什么应用程序卸载程序会显示该对话框呢”？通常用户都很难回答这个问题。那么，是什么造成了这种境况呢？
为了管理由多个应用程序（例如供多个不相关程序使用的 MFC 运行时库）使用的文件的引用计数，安装程序需要在 SharedDLLs 注册键下创建一个项。该项列出文件及其引用计数。如果已经存在文件的项，则引用计数将递增。如果该项尚不存在，则引用计数将设置为 1。反之，当卸载该程序时，引用计数将递减，并且当其减为 0 时，将删除该文件，因为没有程序会再使用该文件。至少理论上讲是这样的。
Should I delete it or not?
Should I delete it or not?
此模型的一个严重的问题是它假定所有程序都遵守此规则。但实际上大量程序并没有遵守此规则，因为即使不遵守此规则，通常也不会带来任何负面结果。
例如，假设某个程序使用了 MFC 运行时库，而该程序的安装程序仅把这些库复制到系统目录，却并未更新引用计数。随后，当卸载该程序时，它只会删除这些库。现在考虑一下当该程序与遵守规则的程序共存时会发生什么情况。以下是基本的工作情况：
  1. 安装遵守规则的程序：它将安装库，并将引用计数设置为 1。
  2. 安装不遵守规则的程序：它将安装库，但不会更新引用计数。
  3. 卸载不遵守规则的程序：库将被删除。
其结果是遵守规则的程序将由于缺少库而无法工作。
以下是另一种情形：
  1. 安装遵守规则的程序：它将安装库，并将引用计数设置为 1。
  2. 安装不遵守规则的程序：它将安装库，但不会更新引用计数。
  3. 卸载遵守规则的程序：引用计数减小到零，库将被删除。
这种情况的结果是不遵守规则的程序将无法工作。
遵守规则程序的编写者指出，“虽然我们无法阻止不遵守规则的程序破坏我们，但至少我们能够尝试使自己不要破坏不遵守规则的程序”。因此，将要删除某个文件时，程序将停止并显示警告消息：“哦，各位，我马上要删除这个文件了，没问题吧？如果还有不遵守规则的程序仍在使用此文件，那可能会破坏这些程序。如果安装了不遵守规则的程序，那您应该单击不删除”。虽然这并不是实际显示出来的内容，但您应该已经知道我指的是哪个对话框。甚至富有远见卓识的 Jeffrey Richter 也曾在 1996 年 Microsoft Systems Journal 文章中推荐采用此方法。
遗憾的是，这样做却给用户们带来了难以正确回答的问题。
当然，所有那些要求 Windows 为其提供涵盖每个事件选项的控制狂们应该会为此对话框喝彩。实际的卸载程序将在卸载过程中为您提供对每个文件的控制。所以对您需要的东西要千万小心啊。

Raymond Chen 的网站“The Old New Thing”及同名著作讲述了 Windows 的发展历程和 Win32 编程。他很想知道自己是否能看到重大的技术改变。