SQL Server中包含的数据库

As we know there are two types of authentication available in SQL Server Windows authentication and SQL authentication. In Windows authentication we use Active directory authentication to connect with SQL Server which makes the most secure authentication method as it can have complexity, group policy configured at AD level applied to all domain servers while in SQL Authentication SQL users are created inside SQL and provided required permissions. The Permissions includes server wide and database wide. The logins can have certain permissions at the database level might be read or write etc.

众所周知,SQL Server Windows身份验证和SQL身份验证有两种类型的身份验证。 在Windows身份验证中,我们使用Active Directory身份验证与SQL Server连接,这是最安全的身份验证方法,因为它可能具有复杂性,在AD级别配置的组策略适用于所有域服务器,而在SQL身份验证中,SQL用户是在SQL内部创建的,并且需要权限。 权限包括服务器范围和数据库范围。 登录名可以在数据库级别具有某些权限,可以读取或写入等。

We need to understand the difference between a user and login here. A login is created at a server level while the user is created at a database level. Each having Unique SID and to work for the user, both SID should be equivalent.

我们需要了解用户和此处登录之间的区别。 在服务器级别创建登录名,而在数据库级别创建用户。 每个都有唯一的SID,并且要为用户工作,两个SID应该等效。

Usually, we have the requirement for restoring the staging or UAT databases from production or any new server. When we move or restore the database into a different environment we might come up with issues of Orphan users (where SID is not mapped for both login and user) if we have not migrated the logins with sp_help_revlogin script or by any other means, so users might have issues accessing the databases or application malfunctions. We need to fix the orphans users using system stored procedure sp_change_users_logins with appropriate parameters.

通常,我们需要从生产或任何新服务器中还原登台数据库或UAT数据库。 如果我们尚未使用sp_help_revlogin脚本或任何其他方式迁移登录名,则在将数据库移动或还原到其他环境中时,我们可能会遇到孤立用户问题(未同时为登录名和用户映射SID)。可能在访问数据库或应用程序故障时遇到问题。 我们需要使用带有适当参数的系统存储过程sp_change_users_logins修复孤儿用户。

SQL Server 2012 Onwards we have a new solution termed as contained database. Contained database is defined as a database which has the database user without logins. It includes all settings related to databases along with its metadata, thus system will be having no dependency with SQL server login. Users can easily connect to a contained database without having to go through the log in at DB engine.

从SQL Server 2012开始,我们有了一个称为包含数据库的新解决方案。 包含的数据库定义为数据库用户没有登录名的数据库。 它包括与数据库有关的所有设置及其元数据,因此系统将不依赖于SQL Server登录。 用户可以轻松地连接到包含的数据库,而无需通过DB引擎登录。

Contained database feature provides two containment modes:

包含数据库功能提供两种包含模式:

  • None – By default each database has its mode set as NONE. This means there is no contained database feature being used.

    无-默认情况下,每个数据库的模式均设置为NONE。 这意味着没有使用任何包含的数据库功能。
  • Partial – With partially contained databases, we can define boundaries between databases and the server, so the metadata will exist inside the databases. It makes SQL Server databases more portable and less dependent on underlying hosts.

    部分-使用部分包含的数据库,我们可以定义数据库和服务器之间的边界,因此元数据将存在于数据库内部。 它使SQL Server数据库具有更高的可移植性,并减少了对基础主机的依赖。

Contained databases feature is available at instance level and it is not enabled by default.

包含数据库功能在实例级别可用,默认情况下未启用。

To enable it, right click on server ➜ properties, go to Advanced, and enable the Enabled Contained Databases option

要启用它,请右键单击服务器➜属性,转到“高级”,然后启用“已启用包含的数据库”选项

SQL Server中包含的数据库_第1张图片

Alternatively, we can use a sp_configure system stored procedure to enable contained databases on the instance, as per below query:

或者,我们可以使用sp_configure系统存储过程在实例上启用包含的数据库,如以下查询所示:

 
EXEC sp_configure 'show advanced', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'contained database authentication', 1
GO
RECONFIGURE
GO
 

创建一个新的包含的数据库 ( Creating a new contained database )

If we want to create a new database as a contained database, we have to make containment type as Partial in the Options page.

如果要创建一个新数据库作为包含数据库,则必须在“选项”页面中将包含类型设置为“部分”。

SQL Server中包含的数据库_第2张图片

If we script out the create database, we can find out the query to create it using t-SQL as below:

如果我们编写创建数据库的脚本,则可以使用t-SQL查找查询以创建它,如下所示:

 
CREATE DATABASE [TestContainedDB]
 CONTAINMENT = PARTIAL
 ON  PRIMARY 
( NAME = N'TestContainedDB', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\TestContainedDB.mdf' ,
 SIZE = 5120KB , FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'TestContainedDB_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\TestContainedDB_log.ldf' , 
SIZE = 2048KB , FILEGROWTH = 10%)
GO
 

Once the database is created, we can verify it using the sys.databases

创建数据库后,我们可以使用sys.databases进行验证

 
select containment,name from sys.databases where name='TestContainedDB'
 

If the containment is not enabled in the databases, it will return 0, else 1, so in our case it should return 1 for TestContainedDB as shown:

如果在数据库中未启用包含,它将返回0,否则返回1,因此在我们的情况下,它应为TestContainedDB返回1,如下所示:

SQL Server中包含的数据库_第3张图片

Once the contained database is created, we need to create a new database user.

创建包含的数据库后,我们需要创建一个新的数据库用户。

For this, we need to expand contained databases and go to security -> Create new database user and create new user type as SQL user with password, provide default schema, appropriate permissions required, as shown below:

为此,我们需要扩展包含的数据库,然后转到安全性->创建新的数据库用户,并使用密码以SQL用户身份创建新的用户类型,提供默认模式和所需的适当权限,如下所示:

SQL Server中包含的数据库_第4张图片

SQL Server中包含的数据库_第5张图片

The script below can be used to create the user by t-sql

以下脚本可用于通过t-sql创建用户

 
USE [TestContainedDB]
GO
CREATE USER [TestUser] WITH PASSWORD=N'test', DEFAULT_SCHEMA=[dbo]
Go
 

So here we need not to create the Login before creating the user, we will directly create the user with appropriate password tagged.

因此,这里我们无需在创建用户之前创建登录名,我们将直接创建带有适当密码标记的用户。

Note: we cannot create the user in a normal database, which is not contained. If tried, we will get the below error

注意:我们无法在不包含的普通数据库中创建用户。 如果尝试过,我们将得到以下错误

Msg 33233, Level 16, State 1, Line 1 You can only create a user with a password in a contained database.

消息33233,级别16,状态1,行1您只能在包含的数据库中使用密码创建用户。

如何使用SQL Server Management Studio连接到包含的数据库 ( How to connect to the contained DB using SQL Server Management Studio )

Normally, to connect with SQL database instance we used to provide instance name, authentication method (windows\SQL) and, if SQL, username and password.

通常,为了连接SQL数据库实例,我们通常提供实例名称,身份验证方法(windows \ SQL),如果提供SQL,则提供用户名和密码。

But to connect contained database we also need to specify contained DB name in the connection parameter.

但是,要连接包含的数据库,我们还需要在连接参数中指定包含的数据库名称。

If we try to connect contained database with contained user and password without specifying database name, we will get the error as:

如果我们尝试在不指定数据库名称的情况下使用所包含的用户名和密码来连接所包含的数据库,则会出现以下错误:

SQL Server中包含的数据库_第6张图片

SQL Server中包含的数据库_第7张图片

So, in the connection properties we need to specify contained database name as shown below:

因此,在连接属性中,我们需要指定包含的数据库名称,如下所示:

SQL Server中包含的数据库_第8张图片

Once connected through SQL Server Management Studio, we can see the database user has access to:

通过SQL Server Management Studio连接后,我们可以看到数据库用户有权访问:

SQL Server中包含的数据库_第9张图片

将现有数据库转换为包含的数据库 ( Converting existing database to the contained database )

If want to convert existing database into contained database, run the command below:

如果要将现有数据库转换为包含的数据库,请运行以下命令:

 
ALTER DATABASE [Database_name] SET CONTAINMENT = PARTIAL WITH NO_WAIT
GO
 

After converting the database we need to take care of the existing logins as well. For this, we need to move the users or migrate the users using the system procedure. We need to use sp_migrate_users_to_contained with below parameters.

转换数据库后,我们还需要注意现有的登录信息。 为此,我们需要使用系统过程移动用户或迁移用户。 我们需要使用带有以下参数的sp_migrate_users_to_contained。

  • @username = SQL Server authenticated user.

    @username = SQL Server认证的用户。
  • @rename = If login and username differ, this tells whether to keep the user name or take the login name.

    @rename =如果登录名和用户名不同,则表明是保留用户名还是采用登录名。
  • @disablelogin = This parameter will disable to server login in the master database, if we want to

    @disablelogin =如果我们想要此参数将禁用主数据库中的服务器登录

Suppose we have the user as TestMovecontained, so query for moving the user will be:

假设我们的用户名为TestMovecontained,因此移动用户的查询将为:

 
sp_migrate_user_to_contained
    @username = 'TestMovecontained',  --Userame to be specified here
    @rename = N'keep_name',
    @disablelogin = N'do_not_disable_login' ;
GO
 

在一个包含的数据库上工作 ( Working on a contained database )

As a contained user is created at database level, we cannot do any activity we require instance permissions like backup \ restore.

由于包含用户是在数据库级别创建的,因此我们无法执行我们需要实例权限的任何活动,例如backup \ restore。

As visible below, we are not getting option of backup \ Restore database here but we can take the database Offline.

如下所示,我们这里没有备份\ Restore database选项,但是我们可以使数据库脱机。

SQL Server中包含的数据库_第10张图片

列出包含用户类型的登录名 ( Listing out logins that are of contained user type )

We can use the system view sys.database_principals view in the database to see which users are listed as contained users using the below query

我们可以使用数据库查询中的系统视图sys.database_principals视图查看哪些用户被列为包含的用户

 
SELECT name,type_desc,authentication_type_desc
FROM sys.database_principals WHERE authentication_type =2
 

SQL Server中包含的数据库_第11张图片

使用包含的数据库的好处 ( Benefits of using contained databases )

  1. It is quite easy to move the database from one server to another, as we will not have orphaned user issues

    将数据库从一台服务器移动到另一台服务器非常容易,因为我们不会遇到孤立的用户问题
  2. Metadata is stored on contained databases so it is easier and more portable.

    元数据存储在包含的数据库中,因此更容易携带。
  3. We can have both SQL Server and Windows authentication for contained DB users.

    对于包含的数据库用户,我们可以同时具有SQL Server和Windows身份验证。

缺点 ( Disadvantages )

Partially contained databases cannot use features like replication, change data capture, change tracking, schema-bound objects that depend on built-in functions with collation changes.

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

翻译自: https://www.sqlshack.com/contained-databases-in-sql-server/

你可能感兴趣的:(数据库,python,linux,java,mysql)