如何理解SQL Server中的Principals?

8
这听起来很蠢,但我觉得它真的很令人困惑:在MSDN中,“principal”的定义是可以请求SQL Server资源的实体。基本上有三种类型的principal:Windows级别的principal、SQL Server级别的principal和数据库级别的principal。到此为止还好。只是这让我有一个印象,即一个principal的标识符应该与其他principal不同,无论这个principal是哪种类型。(如果这三种类型的所有principal都可以排列在一个表中,则它们将具有唯一的标识符)

令人困惑的部分来自下面这三个查询:

1)

Select name,principal_id from sys.database_principals 

(注:我在一个数据库上运行它)
2)
Select name,principal_id from sys.server_principals

现在我知道第一个查询返回数据库用户主体,而第二个查询返回服务器用户主体(如果我错了请纠正)。但为什么第一个查询的一行可以与第二个查询的一行具有相同的principal_id呢?例如,来自数据库主体的一行是:

名称:INFORMATION_SCHEMA,principal_id:3

而来自第二个查询的一行是

名称:sysadmin,principal_id:3

这两个principal_id是什么?如我所说,我认为两个主体的标识符应该是不同的,即使一个是数据库用户,另一个是服务器用户(从名称中可以看出principal_id是标识符)。

那么,如果principal_id对于所有主体不是唯一的,而只在每个查询范围内是唯一的(第一个查询的principal_id仅为数据库用户的标识符,因此它可以与来自服务器用户的principal_id相同),那么我就有了第三个查询,并且不明白它是什么意思:

3)

SELECT
  SDP.PRINCIPAL_ID AS [Principal ID], 
  SDP.NAME AS [Database UserName], 
  SDP.TYPE_DESC AS [Datebase UserType],  
  SSP.NAME AS [Server LoginName], 
  SSP.TYPE_DESC AS [Server LoginType]
FROM sys.database_principals SDP 
INNER JOIN sys.server_principals SSP 
ON SDP.PRINCIPAL_ID = SSP.PRINCIPAL_ID

如果两个 principal_id 只在其范围内唯一,那么在这两个 principal_id 上进行 inner join 是什么意思?内连接意味着这一列是联合唯一的,对吗?
我可能存在一些非常基本的误解。谢谢任何关于此问题的帮助!

你从哪里获取了第三个查询? - Damien_The_Unbeliever
@Damien_The_Unbeliever 许多文章都有类似的内容。比如这个链接:http://www.sql-server-performance.com/2009/analyzing-sql-server-permissions/ - tete
你有没有看到那篇文章上的评论?指出使用principal_id进行连接是不正确的,应该使用SIDs代替。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 真糟糕,我没有仔细阅读就卡在这里了。我会继续努力...谢谢你指出来。 - tete
1个回答

10

sys.database_principalssys.server_principals上,principal_id之间没有对应关系。在第一个视图中,它仅被记录为数据库内唯一。在第二个视图中,它们在整个服务器上是唯一的。并且在相同视图中这些列之间没有记录的关系。

实际上,在这两个视图中都很可能分配较低编号的principal_id,而它们所关联的主体是不相关的。

因此,使用principal_id显示连接这两个视图的查询是错误的。


1
谢谢您的回答。我还有一个问题:我的链接中的评论说查询的目的是将服务器登录与其对应的数据库用户匹配。这实际上就是我想做的事情。然而,如果我运行修改后的查询(更改了sid上的内部连接),我无法获取我的登录名及其映射的DB用户。让我再次澄清一下我的意图:如果我运行select SYSTEM_USER,我得到我的Windows登录名,如果我选择CURRENT_USER,我得到dbo。我正在尝试找到这两者之间的映射关系。 - tete
然而,尽管我在server_principal查询中有我的登录名,但在database_principal中没有与之相同的sid。所以我失去了踪迹。我做错了什么吗?例如,我是否有权限显示所有的database_principal?我的登录名属于sysadmin服务器角色。 - tete
如果您是“sysadmin”的成员,则会出现各种奇怪的规则 - 比如说,您在每个数据库中都自动成为“dbo”,即使在“database_principals”中没有任何条目。 - Damien_The_Unbeliever
谢谢您的回答。那我将通过创建一个普通登录来进行测试。 - tete

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接