包含的数据库有缺点吗?


33

SQL Server 2012引入了“包含”数据库的概念,其中数据库所需的所有内容(包括大部分内容)都包含在数据库本身中。在服务器之间移动数据库时,这提供了很大的优势。那么,我想知道在设计新数据库时这是否应该作为我的默认策略。

MSDN列出了所包含数据库的几个缺点,最大的缺点是缺少对更改跟踪和复制的支持。还有其他吗?如果我不打算使用这些功能,是否有任何理由不使用包含的数据库?

Answers:


33

包含数据库的主要目的是使数据库移植到新服务器时更加容易,而无需花费很多精力。考虑到这一点,我将处理一些潜在的问题,这些问题将使迁移变得更加困难-大部分围绕这样一个事实,即所包含的数据库仅部分包含在SQL Server 2012中(实际上并没有强制执行)。


连接字符串

到包含数据库的连接字符串必须在连接字符串中显式指定数据库。您不再可以依赖登录名的默认数据库来建立连接;如果您未指定数据库,则SQL Server不会逐步浏览所有包含的数据库,并尝试查找您的凭据可能匹配的任何数据库。


跨数据库查询

即使您在同一服务器上的两个不同的包含数据库中使用相同的密码创建了相同的用户,您的应用程序也将无法执行跨数据库查询。用户名和密码可以相同,但不是同一用户。原因是什么?如果您在托管服务器上包含数据库,则不应阻止您与碰巧正在使用同一托管服务器的其他人拥有相同的包含用户。当全封闭到达(可能在SQL Server 2012之后的版本 永远),无论如何绝对禁止跨数据库查询。我强烈建议您不要使用与包含的数据库用户相同的名称创建服务器级别的登录名,并尽量避免在包含的数据库中创建相同的包含的用户名。如果您需要运行命中多个包含的数据库的查询,请使用具有适当特权的服务器级登录名进行操作(您可能会认为这是sysadmin,但是对于只读查询,这是CONNECT ANY DATABASESELECT ALL USER SECURABLES)。


同义字

大多数3和4部分名称易于识别,并显示在DMV中。但是,如果您创建一个指向3或4部分名称的同义词,则这些名称不会显示在DMV中。因此,如果大量使用同义词,则可能会错过一些外部依赖关系,这可能会在将数据库迁移到其他服务器时引起问题。我对此问题有所抱怨,但是由于“设计使然”关闭,因此无法迁移到新的反馈系统中。请注意,DMV还将丢失通过动态SQL构造的3部分和4部分名称。


密码政策

如果在没有适当密码策略的系统上创建了包含的数据库用户,则可能会发现很难在没有适当密码策略的其他系统上创建同一用户。这是因为CREATE USER语法不支持绕过密码策略。我提交了一个有关此问题的错误,该错误仍处于打开状态(并且在Connect退出后,它也没有幸免于此)。对于我来说,很奇怪的是,在已设置密码策略的系统上,您可以创建一个服务器级别的登录名,该登录名可以轻松绕过该策略,但是您不能创建一个这样做的数据库用户,即使该用户是固有用户较少的安全风险。


校对

由于我们不再能够依赖tempdb的排序规则,因此您可能需要更改当前使用显式排序规则的任何代码,或者DATABASE_DEFAULT改为使用它们CATALOG_DEFAULT。有关某些潜在问题,请参见此BOL文章


智能感知

如果您以包含的用户身份连接到包含的数据库,SSMS将不会完全支持IntelliSense。您将获得语法错误的基本下划线,但没有自动完成列表或工具提示以及所有有趣的东西。我提交了一个有关此问题的错误,但该错误仍未解决 -还有一个无法通过此操作幸免。


SQL Server数据工具

如果您打算使用SSDT进行数据库开发,则当前不完全支持所包含的数据库。这实际上只是意味着,如果您使用某些破坏收容的功能或语法,则构建项目不会失败,因为SSDT当前不知道什么是收容,以及什么可能破坏收容。


修改数据库

当运行一个ALTER DATABASE自包含数据库的上下文中的命令,rRather比ALTER DATABASE foo你需要使用ALTER DATABASE CURRENT-这是这样,如果数据库被移动,重命名等,这些命令不需要知道他们的外部环境或任何参考。


其他一些

您可能不应该使用的某些东西,但是仍然在不支持或不建议使用的东西列表中提及,并且不应该在包含的数据库中使用:

  • 编号程序
  • 临时程序
  • 绑定对象中的排序规则更改
  • 更改数据捕获
  • 变更追踪
  • 复制

综上所述,这些不一定是使用包含数据库的不利条件,它们只是您应该意识到的问题,并未在正式文档中明确披露。

您还需要确保,如果要迁移一个包含的数据库,或者它是可用性组的一部分,或者正在被镜像,则所有潜在的目标服务器的sp_configure选项都contained database authentication设置为1。

您可能会发现这个博客帖子是有用的,以及这一次,即使他们预先日期RTM。


你知道为什么不允许临时程序吗?
乔恩·塞格尔

2
@JonSeigel仍然允许它们处于部分容纳状态,但是它们违反了容纳状态(这意味着无法验证过程访问的实体,因为它的元数据和定义存储在其他位置),因此不建议这样做。从 msdn.microsoft.com/zh-cn/library/ff929071.aspx#Limitations当前允许使用临时存储过程。由于临时存储过程违反了包含性,因此预期将来所包含数据库的版本将不支持它们。
亚伦·伯特兰

9

对于那些有兴趣获取有关包含的数据库的更多详细信息的人,我可以建议他们阅读本文http://www.sqlshack.com/contained-databases-in-sql-server/

本文指出了使用包含的数据库的主要优点/缺点。

缺点

部分包含的数据库不能使用复制,更改数据捕获,更改跟踪,架构绑定对象等功能,这些功能依赖于具有归类更改的内置功能。

好处

另一方面,如前所述,使用包含的数据库有一些好处,例如:

  • 将数据库从一台服务器移至另一台服务器非常容易,
    因为不会出现孤立的用户问题
  • 元数据存储在包含的数据库中,因此更容易携带
  • 对于包含的数据库用户,可能同时具有SQL Server和Windows身份验证

本文还有助于:

  • 创建一个新的包含的数据库(通过在SQL Server的“选项”页面中将容纳类型设置为“部分”,然后使用T-SQL查询来创建数据库)
  • 使用SQL Server Management Studio连接到包含的数据库(需要在连接参数中指定包含的数据库名称)
  • 将现有数据库转换为包含的数据库
  • 在一个包含的数据库上工作并列出所有包含该用户类型的登录名

4

一个缺点是包含的数据库用户不能像登录名那样被迫更改自己的密码(MUST_CHANGE)。用户无法管理自己的密码,除非您授予他们更改用户权限,并告诉他们如何使用SQL语句更改密码。他们很难通过用户界面来管理它,或者至少我不知道如何。

另外需要注意的是,我在“ PIVOT”和“ UNPIVOT”子句中发现了意外的和未记录的元数据用法,我认为它应该仅在系统目录(sys.tables / sys.columns / etc)中。如msdn中所述

在一个包含的数据库中,目录排序规则Latin1_General_100_CI_AS_WS_KS_SC。对于SQL Server所有实例上所有包含的数据库,此排序规则都相同,并且无法更改。

但是他们没有提到“ PIVOT”和“ UNPIVOT”子句也将系统目录用作执行机制。因此在迁移过程中,在使用“ PIVOT”和“ UNPIVOT”子句附近的任何地方都会产生归类冲突错误。这里是一些复制:

/*step1 create a table belongs to a contained database and populate some data*/
create  table dbo.test1 (col1 varchar(100),col2 varchar(100))
insert  dbo.test1 values('a','x')
insert  dbo.test1 values('b','y')
insert  dbo.test1 values('c','z')

/*step2 lets see its collation you will see it is correctly as same as its (contained) database */
select name,collation_name from sys.columns where object_name(object_id) = 'test1'

/*step3 reproduce an unpivoted column*/
select * into dbo.test2
from (select * from dbo.test1) a unpivot (val for col in (col1,col2)) a


/*step4 lets check its collation you will see the column specified at "FOR" clause is created as Latin1_General_100_CI_AS_KS_WS_SC */
select name,collation_name from sys.columns where object_name(object_id) = 'test2'

/*step5 make use of the unpivoted table without awareness will cause an error*/
select val + ' = ' + col from dbo.test2 

/*step6 clean up*/
drop table dbo.test1
drop table dbo.test2

您还可以看到有关所包含数据库的文章大多不完整。因此决定使用它需要非常好的即兴性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.