How to understand Principals in SQL Server?

tete picture tete · Nov 9, 2012 · Viewed 14.8k times · Source

This sounds stupid but I find it really confusing: in MSDN the definition is the entity that can request SQL Server resources. And basically there are three types of principals: Windows-level principals, SQL Server-level principals and Database-level principals. So far it's fine. Only that it gives me an impression that the identifier of one principal should be different than others, no matter what type this principle is.(If all principals of these three types could be arranged in one table, they would have unique identifiers)

The confusing part comes from these three queries below:

1)

Select name,principal_id from sys.database_principals 

(Note: I run it on one database)

2)

Select name,principal_id from sys.server_principals

Now I know the first one returns database user principals while the second one returns server user principals (correct me if I am wrong). But why one row from the first query can have the same principal_id as one from the second query? For example, one row from the database principals would be:

name:INFORMATION_SCHEMA, principal_id: 3

while one row from the second query is

name:sysadmin, principal_id: 3

What are these two principal_id? As I mentioned, I thought the identifiers of two principals would be different, even if one is a DB user and the other is server user(and from the name I assume principal_id is the identifier).

Well, if the principal_id is not unique for all principals, but only unique at each query's range(the principal_id from the first query are only identifiers for database users, so it can happen to be the same as one from server users), I then have a third query and don't understand what does it mean:

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

If the two principal_id are only unique within their ranges, what does it mean to make an inner join on both principal_id ? An inner join means this column is jointly unique, right?

There must be something very elementary that I misunderstand. Thanks for any help on that!

Answer

Damien_The_Unbeliever picture Damien_The_Unbeliever · Nov 9, 2012

There is no correspondence between principal_ids on sys.database_principals and sys.server_principals. On the first, it's only documented to be unique within the database. On the second, they're unique across the server. And there's no documented relationship between these columns in the same views.

In fact, low numbered principal_ids are highly likely to be assigned in both views, and the principals that they relate to are unrelated.

So the query showing a join between the two views using principal_id is wrong.