65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL 11 (代号 Denali) 入门 - 第四部分 (CTP 1 中的独立数据库)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (11投票s)

2011 年 5 月 20 日

CPOL

11分钟阅读

viewsIcon

28543

本文将介绍 Sql 11 (代号: Denali) CTP 1 中提供的独立数据库的基础知识。

SQL 11 (代号 Denali) 入门 - 第四部分 (CTP 1 中的独立数据库)

目录

  1. 引言
  2. 背景
  3. 当前(非独立)数据库的问题
  4. 什么是独立数据库?
  5. 我们应该知道的一些术语
  6. 创建独立数据库的四步方法
  7. 将非独立数据库转换为独立数据库
  8. 备份独立数据库
  9. 还原独立数据库
  10. 关于独立数据库的一些补充事实
  11. 参考文献
  12. 结论

引言

微软在技术领域最热门、最令人惊叹的开发之一于 2010 年 11 月 8 日发布了 SQL Server 2011 (代号 Denali) 的社区技术预览版 1 (CTP 1)。CTP1 提供 32 位和 64 位版本。不出所料,Denali 为 SQL Server 用户(无论是开发人员、管理员还是商业智能 (BI) 专业人士)带来了一些新功能。 第一部分 介绍了 SSMS 中的功能和增强。 第二部分 侧重于 T-SQL 角度的新开发和增强功能。 第三部分 考察了 SSIS 方面的增强。在本系列中,我们将探讨 独立数据库功能 。我们将在后续系列中探讨 Denali CTP-I 的其他功能。

背景

在过去几年里,微软为开发人员带来了许多新技术。随着 SQL Server 2005 (代号 Yukon) 的问世,SQL Server 的术语发生了巨大变化,而在随后的 SQL Server 2008 (代号 Katmai) 和 SQL Server 2011 (代号 Denali) 等版本中,通过引入新功能、增强功能和改进,保持了同样的步伐。本文将深入介绍独立数据库,它是什么,它的用途以及更多相关内容。

当前(非独立)数据库的问题

在描述什么是独立数据库之前,让我们先看看它产生的原因。

当前数据库的一些问题列出如下:

  • 数据库迁移或部署过程中信息丢失
  • 当我们把数据库从一个 SQL Server 实例迁移到另一个实例时,像登录名、作业代理信息等信息无法一起迁移。这是因为这些信息是应用程序特定的,因此驻留在 SQL Server 实例内部。在新 SQL Server 实例上重新创建此类任务是一个耗时且容易出错的过程。

  • 应用程序开发偏离应用程序部署
  • 在服务器上部署应用程序时可能会遇到障碍,因为环境不匹配的可能性很高,例如,可能没有创建新登录名的权限,“xp_cmdshell”等命令行工具可能被禁用,应用程序使用的数据库排序规则在部署后可能与服务器排序规则最初确定的不同。

  • 应用程序管理中的安全问题
  • 由于登录名和作业代理信息可以在整个数据库实例中获得,因此管理和维护单个数据库变得困难,从而允许用户授予整个实例的权限,这会授予对其他数据库的不必要访问,从而导致安全漏洞。

什么是独立数据库?

顾名思义,它是一种自给自足的数据库,即它包含设置数据库所需的所有数据库设置和元数据信息。它独立于实例或服务器,没有外部依赖性,并且具有用户身份验证的自给自足机制。由于它独立于数据库实例,因此可以确保在将数据库部署到不同服务器时,数据库排序规则不会成为问题。

独立数据库在其内部保留所有必需的信息和对象,如表、函数、约束、架构、类型等。它还存储应用程序中的所有应用程序级对象,如登录名、持久化错误消息、应用程序级代理作业、系统设置、链接服务器信息等。

拥有此类数据库的好处是,它们可以轻松地迁移到另一台服务器,并且由于它们没有任何外部依赖性,因此我们可以立即开始工作,而无需任何额外的配置。

我们应该知道的一些术语

创建独立数据库的四步方法

此时,我认为我们已经对什么是独立数据库、为什么会出现它有了一些理论概念。现在是时候动手实践了。下面是创建独立数据库的四步方法。

步骤 1:在 SQL Server 实例级别启用“独立数据库身份验证”属性。

步骤 2:创建一个数据库,并将其 CONTAINMENT 属性设置为 Partial。

步骤 3:在新建的独立数据库中创建一个独立用户。

步骤 4:使用存在于独立数据库中的用户登录到独立数据库。

我们将在下面的段落中逐一介绍每个步骤。

  • 步骤 1:在 SQL Server 实例级别启用“独立数据库身份验证”属性
  • 1.登录到 SQL Server Management Studio of SQL Server 2011 (代号 Denali),从对象资源管理器中,右键单击服务器实例,然后单击“属性”。

    1.jpg

    2.访问“高级”选项卡,然后将“包含”组部分下的“启用独立数据库”属性设置为 TRUE。

    2.jpg

    可以使用以下 T-SQL 脚本实现相同的功能:

    --Enabled Advanced options
    sp_configure 'show advanced', 1;
    RECONFIGURE WITH OVERRIDE;
    go
    --Enabled Database Containment
    sp_configure 'contained database authentication', 1;
    RECONFIGURE WITH OVERRIDE;
    go
    
  • 步骤 2:创建一个数据库,并将其 CONTAINMENT 属性设置为 Partial
  • 1.创建一个名为 “TestContainedDB” 的新数据库。

    2.右键单击“TestContainedDB”,然后单击“属性”。

    3.jpg

    3.访问“选项”选项卡,然后将“包含”类型选择为“Partial”。

    4.jpg

    可以使用以下 T-SQL 脚本实现相同的功能:

    USE [master]
    GO
    
    CREATE DATABASE [TestContainedDB]
     CONTAINMENT = PARTIAL
     ON  PRIMARY 
    ( NAME = N'TestContainedDB', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.NILADRIDENALI\MSSQL\DATA\TestContainedDB.mdf' , SIZE = 4096KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
     LOG ON 
    ( NAME = N'TestContainedDB_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.NILADRIDENALI\MSSQL\DATA\TestContainedDB_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
    GO
    
    ALTER DATABASE [TestContainedDB] SET COMPATIBILITY_LEVEL = 110
    GO
    
    IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
    begin
    EXEC [TestContainedDB].[dbo].[sp_fulltext_database] @action = 'enable'
    end
    GO
    
    ALTER DATABASE [TestContainedDB] SET ANSI_NULL_DEFAULT OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET ANSI_NULLS OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET ANSI_PADDING OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET ANSI_WARNINGS OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET ARITHABORT OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET AUTO_CLOSE OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET AUTO_CREATE_STATISTICS ON 
    GO
    
    ALTER DATABASE [TestContainedDB] SET AUTO_SHRINK OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET AUTO_UPDATE_STATISTICS ON 
    GO
    
    ALTER DATABASE [TestContainedDB] SET CURSOR_CLOSE_ON_COMMIT OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET CURSOR_DEFAULT  GLOBAL 
    GO
    
    ALTER DATABASE [TestContainedDB] SET CONCAT_NULL_YIELDS_NULL OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET NUMERIC_ROUNDABORT OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET QUOTED_IDENTIFIER OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET RECURSIVE_TRIGGERS OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET  DISABLE_BROKER 
    GO
    
    ALTER DATABASE [TestContainedDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET DATE_CORRELATION_OPTIMIZATION OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET TRUSTWORTHY OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET ALLOW_SNAPSHOT_ISOLATION OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET PARAMETERIZATION SIMPLE 
    GO
    
    ALTER DATABASE [TestContainedDB] SET READ_COMMITTED_SNAPSHOT OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET HONOR_BROKER_PRIORITY OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET  READ_WRITE 
    GO
    
    ALTER DATABASE [TestContainedDB] SET RECOVERY FULL 
    GO
    
    ALTER DATABASE [TestContainedDB] SET  MULTI_USER 
    GO
    
    ALTER DATABASE [TestContainedDB] SET PAGE_VERIFY CHECKSUM  
    GO
    
    ALTER DATABASE [TestContainedDB] SET DB_CHAINING OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET DEFAULT_FULLTEXT_LANGUAGE = 1033 
    GO
    
    ALTER DATABASE [TestContainedDB] SET DEFAULT_LANGUAGE = 1033 
    GO
    
    ALTER DATABASE [TestContainedDB] SET NESTED_TRIGGERS = ON 
    GO
    
    ALTER DATABASE [TestContainedDB] SET TRANSFORM_NOISE_WORDS = OFF 
    GO
    
    ALTER DATABASE [TestContainedDB] SET TWO_DIGIT_YEAR_CUTOFF = 2049 
    GO
    
  • 步骤 3:在新建的独立数据库中创建一个独立用户
  • 1.访问“TestContainedDB”的“安全性”节点下的“用户”节点。

    2.右键单击“用户”节点,然后单击“新建用户”。

    5.jpg

    3.创建任何用户名和密码。此处 用户名是:TestUser,密码是:testuser

    6.jpg

    4.从“成员身份”选项卡中选中“db_owner”复选框。

    7.jpg

    可以使用以下 T-SQL 脚本实现相同的功能:

    USE [TestContainedDB]
    GO
    CREATE USER [TestUser] 
    WITH PASSWORD='testuser', 
    DEFAULT_SCHEMA=[dbo]
    GO
    

    完成后,我们可以看到我们的用户已创建。

    8.jpg

  • 步骤 4:使用存在于独立数据库中的用户登录到独立数据库
  • 完成第三步后,我们将退出 SSMS。再次登录 SSMS,然后执行以下步骤:

    1.在登录名和密码框中,输入为“TestContainedDB”创建的用户的登录名和密码,即用户名“TestUser”,密码“testuser”。

    9.jpg

    2.接下来,单击“选项”按钮,然后访问“连接属性”。

    10.jpg

    3.在“连接到数据库”框中,输入独立数据库的名称,在本例中为“TestContainedDB”。

    11.jpg

    4.现在单击“连接”按钮,我们就进入了我们的独立环境。

    12.jpg

将非独立数据库转换为独立数据库

在本节中,我们将介绍如何将非独立数据库转换为独立数据库。

初始设置

通过执行以下脚本创建一个名为“NonContainedDB”的数据库。

USE [master]
GO

CREATE DATABASE [NonContainedDB]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'NonContainedDB', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.NILADRIDENALI\MSSQL\DATA\NonContainedDB.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'NonContainedDB_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.NILADRIDENALI\MSSQL\DATA\NonContainedDB_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

ALTER DATABASE [NonContainedDB] SET COMPATIBILITY_LEVEL = 110
GO

IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [NonContainedDB].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO

ALTER DATABASE [NonContainedDB] SET ANSI_NULL_DEFAULT OFF 
GO

ALTER DATABASE [NonContainedDB] SET ANSI_NULLS OFF 
GO

ALTER DATABASE [NonContainedDB] SET ANSI_PADDING OFF 
GO

ALTER DATABASE [NonContainedDB] SET ANSI_WARNINGS OFF 
GO

ALTER DATABASE [NonContainedDB] SET ARITHABORT OFF 
GO

ALTER DATABASE [NonContainedDB] SET AUTO_CLOSE OFF 
GO

ALTER DATABASE [NonContainedDB] SET AUTO_CREATE_STATISTICS ON 
GO

ALTER DATABASE [NonContainedDB] SET AUTO_SHRINK OFF 
GO

ALTER DATABASE [NonContainedDB] SET AUTO_UPDATE_STATISTICS ON 
GO

ALTER DATABASE [NonContainedDB] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO

ALTER DATABASE [NonContainedDB] SET CURSOR_DEFAULT  GLOBAL 
GO

ALTER DATABASE [NonContainedDB] SET CONCAT_NULL_YIELDS_NULL OFF 
GO

ALTER DATABASE [NonContainedDB] SET NUMERIC_ROUNDABORT OFF 
GO

ALTER DATABASE [NonContainedDB] SET QUOTED_IDENTIFIER OFF 
GO

ALTER DATABASE [NonContainedDB] SET RECURSIVE_TRIGGERS OFF 
GO

ALTER DATABASE [NonContainedDB] SET  DISABLE_BROKER 
GO

ALTER DATABASE [NonContainedDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO

ALTER DATABASE [NonContainedDB] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO

ALTER DATABASE [NonContainedDB] SET TRUSTWORTHY OFF 
GO

ALTER DATABASE [NonContainedDB] SET ALLOW_SNAPSHOT_ISOLATION OFF 
GO

ALTER DATABASE [NonContainedDB] SET PARAMETERIZATION SIMPLE 
GO

ALTER DATABASE [NonContainedDB] SET READ_COMMITTED_SNAPSHOT OFF 
GO

ALTER DATABASE [NonContainedDB] SET HONOR_BROKER_PRIORITY OFF 
GO

ALTER DATABASE [NonContainedDB] SET  READ_WRITE 
GO

ALTER DATABASE [NonContainedDB] SET RECOVERY FULL 
GO

ALTER DATABASE [NonContainedDB] SET  MULTI_USER 
GO

ALTER DATABASE [NonContainedDB] SET PAGE_VERIFY CHECKSUM  
GO

ALTER DATABASE [NonContainedDB] SET DB_CHAINING OFF 
GO

接下来,通过执行以下脚本添加一个名为“tbl_Players”的表。

-- Drop the table if it exists
IF EXISTS (SELECT * FROM sys.objects WHERE name = N'tbl_Players' AND type = 'U')
    DROP TABLE tbl_Players
GO
SET ANSI_NULLS ON
GO
--Create the table
CREATE TABLE tbl_Players (
	PlayerID INT IDENTITY,
	PlayerName VARCHAR(15),
	BelongsTo VARCHAR(15),
	MatchPlayed INT,
	RunsMade INT,
	WicketsTaken INT,
	FeePerMatch NUMERIC(16,2)
)

--Insert the records
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('A. Won','India',10,440,10, 1000000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('A. Cricket','India',10,50,17, 400000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('B. Dhanman','India',10,650,0,3600000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('C. Barsat','India',10,950,0,5000000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('A. Mirza','India',2,3,38, 3600000)

INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('M. Karol','US',15,44,4, 2000000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('Z. Hamsa','US',3,580,0, 400)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('K. Loly','US',6,500,12,800000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('S. Summer','US',87,50,8,1230000)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('J.June','US',12,510,9, 4988000)

INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('A.Namaki','Australia',1,4,180, 999999)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('Z. Samaki','Australia',2,6,147, 888888)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('MS. Kaki','Australia',40,66,0,1234)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('S. Boon','Australia',170,888,10,890)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('DC. Shane','Australia',28,39,338, 4444499)

INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('S. Noami','Singapore',165,484,45, 5678)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('Z. Biswas','Singapore',73,51,50, 22222)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('K. Dolly','Singapore',65,59,1,99999)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('S. Winter','Singapore',7,50,8,12)
INSERT INTO tbl_Players(PlayerName, BelongsTo, MatchPlayed,RunsMade,WicketsTaken,FeePerMatch) VALUES('J.August','Singapore',9,99,98, 890)

另外,通过执行以下脚本向数据库添加一个存储过程。

If Exists (Select * from sys.objects where name = 'usp_SelectRecordsByPlayerName' and type = 'P')
    Drop Procedure usp_SelectRecordsByPlayerName
Go
-- Create the  stored procedure
Create Procedure [dbo].[usp_SelectRecordsByPlayerName]
( @PlayerID int )
As
Begin
	Select 
		PlayerID
		,PlayerName
		, BelongsTo
		, MatchPlayed
		,RunsMade
		,WicketsTaken
		,FeePerMatch
	From
	tbl_Players
	Where PlayerId = @PlayerID
End

这意味着,现在我们有一个名为“NonContainedDB”的数据库,其中包含两个数据库对象:一个表“tbl_Players”和一个存储过程“usp_SelectRecordsByPlayerName”。目前,此数据库是非独立的。我们的目标是使其成为独立数据库。

步骤 1

作为第一步,我们将创建一个新的服务器级登录名,并为该登录名在“NonContainedDB”中创建一个用户。让我们在 master 数据库上执行以下脚本:

--Create a login on the server
CREATE LOGIN NonContainedUser
WITH PASSWORD = 'somepassword@123'

--Create a "non-contained" users for the login on the server
USE NonContainedDB
GO
CREATE USER NonContainedUser FOR LOGIN NonContainedUser
GO

第二步

现在,让我们识别“NonContainedDB”数据库的非独立数据库对象。为此,让我们执行以下脚本:

USE NonContainedDB
GO

SELECT 
	class_desc
	,feature_name
	,feature_type_name 
FROM sys.dm_db_uncontained_entities

输出如下:

13.jpg

我们可以忽略 ROUTE。因此,有两个非独立数据库对象,如图所示。

要识别数据库中的非独立用户,我们可以执行以下脚本:

USE NonContainedDB
GO
SELECT dp.name 
FROM sys.database_principals dp 
JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.authentication_type = 1
  AND sp.is_disabled = 0 

它将给出以下结果:

14.jpg

步骤 3

右键单击“NonContainedDB”,然后单击“属性”。访问“选项”选项卡,并将“包含”类型选择为“Partial”。

或者,我们也可以通过执行以下 T-SQL 脚本来实现相同的功能:

USE master
GO
ALTER DATABASE NonContainedDB SET CONTAINMENT=PARTIAL;
GO

之后,执行以下脚本:

USE NonContainedDB
GO
EXEC sp_migrate_user_to_contained @username = N'NonContainedUser', 
                                  @rename = N'keep_name', 
                                  @disable_login = N'disable_login'

sp_migrate_user_to_contained 存储过程是必需的,以便包含与 SQL Server 登录名关联的用户。它会将 SQL Server 登录名转换为带密码的用户。

现在,让我们再次运行相同的查询来识别数据库中的非独立用户:

USE NonContainedDB
GO
SELECT dp.name 
FROM sys.database_principals dp 
JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.authentication_type = 1
  AND sp.is_disabled = 0 

结果如下:

15.jpg

因此,我们可以看出,“NonContainedUser”不再出现。这意味着它已被更改为独立用户。同时,服务器级别的登录名已被禁用。

步骤 4

让我们退出 SSMS。再次登录 SSMS。在登录名和密码框中,输入为“TestContainedDB”创建的用户的登录名和密码,即用户名“NonContainedUser”,密码“somepassword@123”。接下来,单击“选项”按钮,然后访问“连接属性”。在“连接到数据库”框中,输入独立数据库的名称,在本例中为“NonContainedDB”。现在单击“连接”按钮,我们就进入了我们的独立环境。

16.jpg

备份独立数据库

我们可以像备份非独立数据库一样备份独立数据库。我们可以通过以下方式进行:

a) 无 T-SQL 脚本

1.通过 SSMS 登录到 SQL Server 2011 (“Denali”)。

2.在对象资源管理器中,导航到“TestContainedDB”。

3.右键单击,转到“任务”->“备份”。

17.jpg

b) 使用 T-SQL 脚本

我们还可以通过执行以下脚本来备份数据库:

BACKUP DATABASE TestContainedDB
TO DISK='<File Path>\ TestContainedDB.bak'

还原独立数据库

与备份一样,我们可以通过以下方式还原数据库:

a) 无 T-SQL 脚本

1.通过 SSMS 登录到 SQL Server 2011 (“Denali”)。

2.在对象资源管理器中,导航到“数据库”节点。

3.右键单击,然后转到“还原数据库”。

18.jpg

b) 使用 T-SQL 脚本

RESTORE DATABASE TestContainedDB
FROM DISK='<File Path>\TestContainedDB.bak'

但是,在运行脚本时,我们可能会遇到以下错误:

消息 12824,级别 16,状态 1,行 1
“独立数据库身份验证”的 sp_configure 值必须设置为 1 才能还原独立数据库。您可能需要使用 RECONFIGURE 来设置 value_in_use。
消息 3013,级别 16,状态 1,行 1
RESTORE DATABASE 正在异常终止。

从消息中可以清楚地看出,我们需要在 SQL Server 实例级别启用“独立数据库身份验证”属性,该属性默认关闭。执行以下脚本可解决此问题:

--Enabled Advanced options
sp_configure 'show advanced', 1;
RECONFIGURE WITH OVERRIDE;
go
--Enabled Database Containment
sp_configure 'contained database authentication', 1;
RECONFIGURE WITH OVERRIDE;
go

关于独立数据库的一些补充事实

  • 独立数据库支持的身份验证模式
  • a) SQL Server 身份验证

    基于 Windows 的身份验证

  • CREATE/ALTER DATABASE 语句的更改
  • 对于独立数据库,CREATE / ALTER DATABASE 语句的工作方式不同。该语句

    	Alter Database <Database Name>
    

    对于独立数据库不再有效。相反,添加了一个名为 CURRENT 的新选项,它确保如果我们移动数据库到新实例或更改数据库名称,该命令仍然有效。

    因此,该语句

    	ALTER DATABASE CURRENT
    

    适用于独立数据库。而

    	Alter Database <Database Name>
    

    适用于非独立数据库。

参考文献

理解独立数据库

结论

在本文中,我们了解了什么是独立数据库,它为什么会出现,它如何解决了非独立数据库带来的问题,我们如何创建独立数据库,以及如何将非独立数据库转换为独立数据库等。希望本文能够为您开始使用独立数据库提供必要的思路。我们将在后续文章中探讨 Denali CTP 1 的更多功能。

感谢阅读。

© . All rights reserved.