什么是 SQL Server Express?
SQL Server 2005 Express Edition 是 Microsoft SQL Server 的 Microsoft 桌面引擎 (MSDE) 版本的替代产品。它的体系结构完全重新设计,您可以像使用 Microsoft Access/JET 数据库那样安装和使用它,但是不会出现与该方法相关联的问题。SQL Server 2005 Express Edition 为满足下列应用程序的需要而构建更好的解决方案,这经历了很长的历程:
| • |
替代 JET 数据库。也就是说,如果需要,可以由 IT 部门代替 DBMS,这一方面可以满足 HIPA 安全性的需要,一方面可以使用所有 SQL Server 保护数据和参照安全性的功能,并且无需考虑用户采取的手段。(HIPPA 或 HIPAA(通常简略为 HIPA)指联邦立法部门,该部门要求将可靠的安全性和访问保护用于存储个人医疗卫生信息的数据库中。)
|
| • |
无需升级到 SQL Server Standard Edition,DBMS 即可从单个用户扩展到很多用户,并且 DBMS 无需担心在最需要调控器时,调控器的性能降低。
|
| • |
可以轻松地在小型网站上和客户端/服务器配置中工作的 DBMS。
|
| • |
当 Service Pack 可用时,可以轻松地安装并就地更新的 DBMS 引擎。这意味着安装例程可以轻松地集成到应用程序的部署脚本中。
|
| • |
通过简单地指向安装或传递到应用程序中的 DBMS 文件,就可以对其进行访问的 DBMS。因为 SQL Server Express 旨在允许数据库随时连接,它可以比以前更加简单地使用“松散”的 SQL Server MDF 数据库文件并利用应用程序对它们进行部署。这使得部署独立的 SQL Server Express 数据库 .MDF 文件非常简单,就像利用 JET 数据库完成那样。
|
| • |
引用 SQL Server 的共享实例的标准方法。当安装 SSE 时,默认情况下安装为具有相同的实例名称 SQLEXPRESS。这意味着如果假设应用程序安装例程利用了该功能,无论应用程序的连接字符串是安装在本地系统上还是安装在局域网上,它都可以更简单地针对 SQL Server Express。我会在稍后谈论实例问题。
|
| • |
什么是“安全”的系统?对于小型系统而言,安全性意味着什么呢?
|
| • |
|
| • |
SQL Server Express 如何解决这些问题?
|
| • |
应用程序如何获得对 SQL Server Express 数据库的访问?
|
| • |
如何保护 SQL Server Express 数据库?
|
注 在撰写本文时,SQL Server 2005 Express Beta 2 不应该用于产品系统中,不应该公开在 Web 上或在 EULA 限制外使用。
什么是“安全”的系统?
在我们深入讨论 SQL Server 2005 Express Edition 的技术优点以及如何配置其安全功能之前,我认为有必要定义安全性的实际含义。当然,对于小型企业或部门系统来说,当数据服务器受到安全威胁或其数据丢失或损坏时,该公司与大型公司一样容易面临失败。SQL Server Express 可以驻留在 Web 服务器上,为 ASP 应用程序提供 SQL Server 服务。因此,正常运行时间、可靠性和安全性也意味着对 Web 服务器应用程序公开信息的能力,但同时还不易受到来自 Web 的攻击。对于将编写代码和构建应用程序作为兼职的“经验不足的开发人员”来说,SQL Server Express 也是非常理想的。这些医生、律师、接待员和出租车司机都需要一个用于存储和检索数据的简单、安全、稳定的方式,而不必考虑在后台正在为他们所做的操作。
安全性还包括应用程序设计程序和开发人员要防止数据丢失而采取的这些步骤,无论丢失是由于意外、疏漏或是恶意攻击所致。安全性意味着将那些不应该访问数据的人员拒之门外,并保护物理文件和系统本身。它意味着制作备份并能够无缝地执行还原。利用 SQL Server Express 系统,尤其具有挑战性,因为与通常不同,没有专职系统管理员或 IT 部门介入并执行周期性的备份,或者当系统发生故障时从各个部分中进行还原整个系统。具有安全的系统意味着当发生问题时保持您的工作(并且可能会有提升),然后可以快速、安静、高效地恢复应用程序。我将会指出很多事项,您可以完成它们使应用程序更持久、更不容易受到攻击并且更易于维护。
问题是什么?
相当长时间以来,我一直都在赞美 SQL Server 的 MSDE 版本。这是因为我确信对于需要“少量用户”数据存储区的应用程序,或应用程序不需要对远程 DBMS 引擎进行访问的情况下,MSDE 是非常好的解决方案。尽管 MSDE 已经广泛地被大量关键业务采用,它们通常必须依赖自己来处理很多问题 — 实现非标准解决方案,该解决方案有时与解决相同或不同问题的其他公司的尝试相冲突。这些冲突包括:
部署:如果将 SQL Server 与应用程序一起安装将会怎样?下面就是对相关问题的阐述。例如,如果 SQL Server 已经安装,又该如何呢?如果实例名与其他现有实例冲突,又该如何呢?应用程序应该共享一个现有的 SQL Server 实例还是创建一个独特的实例呢?当卸载安装有共享 SQL Server 实例的应用程序行时会发生什么情况?它还会卸载 SQL Server 实例吗?如果会,那么该实例宿主的其他数据库会发生什么情况呢?
安全性:如果选择共享一个 SQL Server 实例,应该为 SA 使用什么密码呢?如何设置用户帐户?应用程序是否应该只是使用由域控制器管理的集成安全性呢?如果没有 Active Directory,又该如何呢?如何将数据库安装在目标 MSDE 服务器上?安装后,数据库是否对服务器上的其他应用程序可见呢?应用程序如何隐藏专用数据呢?
性能: MSDE 使用限制服务器上并发操作数量的调控器。如果单个用户应用程序需要同时执行几个操作,但是调控器不发挥作用并使其速度下降,又该如何呢?坦白地说,我不确认这个问题是十分普遍的。我曾经听到非常少的人抱怨调控器终止,并且使他们的应用程序运行得非常慢。的确,我曾听说应用程序运行得不是特别快,但是这(通常)是由于野蛮强制查询或“置疑的”数据库实现导致的结果。
可伸缩性: MSDE 数据库限制在 2GB。如果您需要比这更多的数据,又该如何呢?这是否意味着您必须升级目标系统以使用 SQL Server Standard Edition,而这可能比期望使用它的系统花费更多?另外,我所听到的最多的抱怨就是人们存储二进制大对象 (BLOB)(例如数据库中的文档或图片)时涉及的问题。一旦它们将 BLOB 替换为一个到 BLOB 文件的路径,它们的数据库就缩小到非常合理的大小了。
工具: SQL Server 的 MSDE 版本是“部署”配置。同样,它并不包括管理服务器或它所管理的数据库所需要的任何工具。我通常会推荐开发人员购买 49 美元的 (SRP) Developer Edition,它包括用于管理其 MSDE 数据库的整套工具。但是,由于许可限制,这些工具无法利用应用程序进行部署。这意味着开发人员必须构建他们自己的客户端工具或简单地将需要的功能构建到他们已部署的应用程序中。
管理: 无论它是如何完成的,应用程序必须要承担很多管理性责任。对于没有“SA”(系统管理员)值守的 SQL Server Express 系统而言,这一点尤为重要。这些管理责任包括管理登录帐户、权限、备份、还原和日志维护。最终用户通常不具有执行这些操作的能力并且不应该被信任来执行这些操作 — 这取决于应用程序。因为 JET 数据库需要周期性的压缩或修复,MSDE(和任意 SQL Server 数据库)需要周期性地备份(和转储)日志和数据库。当数据库没有进行集中管理时(集中管理可以更简单地管理管理性和维护任务),这个问题就变得相当重要。同样,这取决于应用程序。
Service Pack: 由于 MSDE 通常嵌入到应用程序中,用户可能不知道他们已经安装了一个 SQL Server 实例。同样,他们也没有注意到他们可能需要应用 SQL Server Service Pack 来保护他们的数据和系统以免受攻击,即使他们在 5 点钟新闻时看到它时,还在正常运转。为了防止由蠕虫和其他攻击病毒引起的某些问题,MSDE SP3(a) 禁用了网络连接,因此应用程序无法通过 Intranet(或 Internet)连接到服务器。问题在于 Service Pack 未能应用到很多系统中,因为用户不知道它是必要的,或者不知道如何应用修补程序。将 SQL Server 更新应用到 MSDE 安装这个问题仍然难以解决,因为 Microsoft 升级不是始终可以与用于部署 MSDE 应用程序和数据库的自定义安装脚本一起使用的。
连接到 SQL Server Express(获得对 SQL Server Express 的访问)
Microsoft 和我希望您使用托管代码来打破对 COM 和 OLE DB 提供程序的依赖性 — 即,SQL Server 提供程序。SqlClient .NET 数据提供程序仍然是最好的选择。如果必须使用 MDAC 和 OLE DB 从基于 COM 的应用程序连接到 SQL Server Express,您可以这么做,但是您无法通过共享的内存提供程序进行连接,并且您将需要确保启动了 SQL Browser 服务。
由于默认安全性设置是集成安全性,您将需要在连接字符串中使用 Integrated Security=SSPI,除非更改为混合模式安全性。您仍然需要在连接字符串中指定初始目录或 Database,以指向 SQL 所针对的特定数据库。当使用 SQL 分析器来监视代码所执行的操作时,我还建议您使用 Application Name 连接字符串参数来唯一地标识您的操作。
使用 AttachDBFilename 进行连接
SQL Server 团队所推荐的新方法是将关键字 AttachDBFilename 添加到连接字符串。如果一直用于 Web 应用程序,对于典型 SQL Server 客户端/服务器前端应用程序而言,这是不常用而且是极少使用的方法。对于说明 SQL Sever 实例的任意连接字符串,您必须按名称(或 IP 地址)指向服务器并提供一个实例名。此外,当使用 AttachDBFilename 关键字指向连接字符串中的文件名时,ADO.NET(或 ADO)会通知目标 SQL Server 实例,您希望将引用的文件“附加”到服务器 — 这样,在打开连接的过程中会将该数据库注册在 SQL Server Master 数据库中。
在附加数据库后,当您引用数据库时,从此时起,该服务器访问引用的文件 (.MDF) 及其附带日志文件 (.LDF)。因为此处有一个 catch 语句,请务必小心。您必须 在连接字符串中指定 Database 关键字。如果不指定,该服务器则无法确定这个新附加的数据库。代码列表 1 显示了被配置为附加并打开一个 .MDF 文件的 ADO.NET Sqlclient.SqlConnection 对象的示例。
代码列表 1. 使用 AttachDBFilename 关键字连接到 SQL Server .MDF 文件。
Try
cn = New SqlConnection("Data Source=.\SQLExpress;" _
& "Integrated Security=True;Database=Biblio;" _
& "Timeout=60;" _
& "Application Name=SQLExpress Test;" _
& "AttachDBFilename=" & strFn)
da = New SqlDataAdapter("SELECT AU_ID, Author, Year_Born from authors", cn)
ds = New DataSet
da.Fill(ds)
DataGridView1.DataSource = ds.Tables(0)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
提示 将新数据库附加到 Master 的过程比简单地打开它要花费更多的时间。确保设置连接字符串 Timeout 关键字,以考虑该增加的时间。
管理附加的 .MDF 数据库文件
尽管打开连接的过程会附加一个数据库,但是当应用程序关闭该连接时,数据库并没有分离。一旦附加,它会永久性地安装在 SQL Server 实例中。这意味着在应用程序结束后,数据库本身对任何应用程序都是可视的,且带有足够的权限。它还表示您需要负责在带有其他应用程序文件的相同目录中维护数据库文件。由于在 SQL Server 运行时,文件受到 Windows 的保护,所以在没有首先从数据库分离时,它不应该被“更新的”版本所覆盖。当然,分离并不困难。您可以从 SQLCMD 中使用以下命令,或使用 SQL Server 2005 GUI 管理工具。另一种方法是使用当使用该数据库的所有应用程序结束时自动关闭数据库文件的 AutoClose 选项。
EXEC sp_detach_db 'MyDb'
GO
请记住要将数据库文件保存在本地硬盘上,而不是保存在共享的网络服务器上。强制 SQL Server 执行通过线缆的物理 I/O(即使它支持该操作)是非常危险的,并且它确实会降低您的性能。
与 JET 数据库不同,备份 SQL Server 数据库文件(可能有若干个文件)非常简单,但是备份过程还涉及了通过 OSQL(其中一个工具)或 SMO 向 SQL Server 发送 T-SQL 命令。数据库可以在任何时间进行备份,可以带有任何数量的登录(和活动)用户。
直接连接到名为 SQL Server Express 的数据库
连接到名为 SQL Server Express 实例(或任意 SQL Server 实例)上的命名数据库的更典型方法是,简单地在实例名后写出计算机名,如代码列表 2 所示。这种方法假设作为目标的 Database 已经注册了 SQL Server Master 数据库。
代码列表 2. 使用对已注册的 SQL Server 数据库的“直接”访问。
cn = New SqlConnection("Data Source=.\SQLExpress;" _
& "Integrated Security=True;Database=Biblio;" _
& "Timeout=60;" _
& "Application Name=SQLExpress Test;" _
& "AttachDBFilename=" & strFn)
注 SQL Server Express 仍然支持连接字符串的“(local)”或“.”表示法来指代 SQL Server 的“默认”实例,但前提是只有您按照我前面所述安装了“默认”实例。我并不建议使用这种方法,因为 SQL Server Express 服务器可能不是服务器上的原始“默认”实例。
使用备用的实例名
您不必使用默认的“SQLEXPRESS”实例名来安装 SQL Server Express。我可以想象出几种情况来说明使用默认实例名并不是很好的解决方案。在这种情况下,您需要使用安装过程中的“高级配置”选项,以选择另一个实例名并在连接字符串中使用这个实例名。这种方法的问题在于,如果应用程序安装实用工具不知道安装在目标服务器上的数据库名称,您的名称可能会与现有名称发生冲突 — 正像在用户系统上安装 SQL Server 的某个其他应用程序可能会与您选择的名称发生冲突一样。这就解释了为什么 SQLEXPRESS 的公用实例名是如此重要的一项创新。
使用别名
从应用程序连接到“公用”服务器名的另一种方法是使用别名。也就是说,您可以使用 SQL 计算机管理器来为 SQL Server 实例指定一个别名(如图 5 所示)。在此例中,我创建了别名“George”,我可以将其用于我的连接字符串中。如果基本服务器发生变化(例如,当我从测试服务器更改为生产服务器时),我只要更改别名,该应用程序就会重定向到正确的服务器。
图 5. 使用计算机管理实用工具来创建实例别名。
利用 Windows 身份验证模式管理集成安全性
当您的连接字符串包含关键字 Integrated Security=SSPI 时,ADO.NET(或您所使用的数据访问接口)则使用 Windows 身份验证模式。在幕后,这种模式使用 NTLM (NT LAN Man) Windows NT 质询/响应身份验证协议来验证使用加密的帐户凭据,以便保护传输过程中的密码以防止“刺探者”以离线状态攫取您的凭据。每次打开(或重新打开)连接时,用户凭据会根据域控制器 (Active Directory) 数据库重新进行验证。Microsoft 建议对大多数应用程序使用 Windows 身份验证模式。
当然,我所编写的用于验证这段代码的测试应用程序可以正常工作(该代码显示在代码列表 1 中)。因为我是以管理员身份登录的,所以我的 Windows 帐户被授予了 SQL Server 上的系统管理员权限。这就是当使用 SQL Server Express 时,为什么不需要使用 SA 帐户或者不需要知道 SA 密码的原因所在。然而,我的确希望最终用户不被授予管理员帐户。当任何人登录到 Windows 域时,域管理员会确定授予他们的权限。该信息存储在 Active Directory 中。这些权限不会传递到 SQL Server,除非您特别地授予这些权限。这意味着(默认情况下)不会 为非管理员授予到服务器或其内容的权限,并且您将需要设置用户、组和角色以管理数据库及其内容。执行该操作的机制在一段时间以来都没有改变,在 SQL Server Books Online 中有对它们的详细说明。有关 SQL Server 安全性最佳操作的详细信息,请访问 TechNet。
|
1.
|
Windows 域帐户:系统管理员需要建立域帐户,包括登录名和(强)密码 — 用户“凭据”。该帐户(默认情况下)是“Domain Users”组的成员。管理员可以建立其他组并根据需要将用户分配到这些组。我通常建立用户的“类”,它按照用户在办公室中被分配的工作角色的类型对其进行分类。例如,我将建立“Accounting Admin1”和“Accounting Admin Lead”组,并将特定的 Windows 域帐户添加到这些组。可以分配给单个 Windows 用户多个角色。
|
|
2.
|
工作站和用户的物理安全性。如果在用户离开时,工作站保留为登录状态,或者用户允许其他人使用他们的 Windows 帐户凭据,那么您的安全性已经被洞穿。这一层通常被忽略。这就解释了为什么当用户没有实际出现时 Microsoft 使用密钥访问系统来防止对系统的访问。
|
|
3.
|
SQL Server 登录:这是在 SQL Server 上建立的帐户,用于屏蔽连接到 SQL Server 的尝试。您向该列表中添加的每个帐户,都会减弱保护数据的服务器能力,因为它允许额外的 Windows 用户获得对该服务器的访问。当使用集成安全性(我们建议这么做)时,您仍然需要在 SQL Server 上建立一个登录帐户,以允许特定用户或 Windows 域组(例如 Domain Users)对目标数据库进行访问。授予每个登录帐户对一个或多个数据库的访问权限,并且如果初始目录 (Database) 关键字没有在连接字符串中使用,则分配一个所引用的默认数据库。
|
|
4.
|
数据库用户:保护的最后一层是在数据库本身中进行管理的。在这种情况下,您需要建立一个或多个数据库用户,为这些用户授予对特定表格、视图、函数和存储过程的访问权限。如果需要,您甚至可以授予对特定列的访问权限。
|
在任何 SQL Server 数据库上管理安全性帐户的一个方法就是使用 SQLCMD。但是,除非您是数据库管理员 (DBA) 并且具有 T-SQL 的丰富经验,否则这可能有一点令人畏缩。幸运的是,您可以使用 SQL Server 2005 Management Studio(与 SQL 企业管理器等价)来创建数据库用户、组或角色。该工具没有包括在 SQL Server Express 中,因此您需要使用 Microsoft 提供的标准版或开发人员版的工具或使用第三方的一个工具。在创建这些角色后,您可以使用 SQL 工具将这些 T-SQL 命令导出到一个脚本文件。
使用混合模式的安全性
混合模式身份验证是使用 Windows 集成安全性的一个备选方法。在这种情况下,连接字符串 UID 和 PWD 关键字会根据 SQL Server 登录名和密码进行验证。由于这种技术绕过了 Windows 身份验证,它被认为是不太安全的。要使用这种安全性模式(并忽略我们的建议),您需要在安装过程中启用这种混合模式安全性。为此,当使用安装批处理文件时,您可以将 SECURITYMODE 命令参数设置为“SQL”。该选项还可用于 SQL Server Express 交互式安装程序和 SQL Server Express Manager (XM),其预览版本应该很快就可用了。