SIDs and IDs
If you are writing code that interacts with the SQL Server engine, you should be aware of two numbers that are used as internal representations of principal. Every principal has an ID and a Security ID (SID). The meaning and source of these numbers depend on how the principal was created, and whether it is a server principal or a database principal.
Server-Level Identification Number
When a SQL Server login is created, it is assigned an ID and a SID. These are visible in the sys.server_principals catalog view as principal_id and SID. The ID (principal_id) identifies the login as a securable within the server. It is assigned by SQL Server when the login is created. When a login is deleted, its ID number is recycled. The SID identifies the security context of the login and is unique within the server instance. The source of the SID depends on how the login is created. If the login is created from a Windows user or group, it is given the Windows SID of the source principal; the Windows SID is unique within the domain. If the SQL Server login is created from a certificate or asymmetric key, it is assigned a SID derived from the SHA-1 hash of the public key. If the login is created as a legacy-style SQL Server login that requires a password, the server will generate a SID.
Database-Level Identification Number
When a database user is created, it is assigned an ID and a security ID (SID). These numbers are visible in the sys.database_principals catalog view as principal_id and SID. The ID identifies the user as a securable within the database. When a database user is deleted, its ID is recycled. The SID assigned to a database user is unique within the database. The source of the SID depends on how the database user is created. If the user is created from a SQL Server login, it is given the SID of the login. If the user is created from a certificate or asymmetric key, the SID is derived from the SHA-1 hash of the public key.
Maximum Number of Database Users
The maximum number of database users is determined by the size of the user ID field. The value of a user ID must be zero or a positive integer. In SQL Server 2000, the user ID is stored as a smallint consisting of 16 bits, one of which is the sign. For this reason, the maximum number of user IDs in SQL Server 2000 is 215 = 32,768. In SQL Server 2005 and later versions, the user ID is stored as an int consisting of 32 bits, one of which is the sign. These additional bits make it possible to assign 231 = 2,147,483,648 ID numbers.
Database user IDs are divided into preallocated ranges, as illustrated in the following table.
SQL Server 2000 ID |
SQL Server 2005 ID |
Allocated to |
---|---|---|
0 |
0 |
public |
1 |
1 |
dbo |
2 |
2 |
guest |
3 |
3 |
INFORMATION_SCHEMA |
4 |
4 |
SYSTEM_FUNCTION_SCHEMA |
5 - 16383 |
5 - 16383 |
Users, aliases, application roles |
16384 |
16384 |
db_owner |
16385 |
16385 |
db_accessadmin |
16386 |
16386 |
db_securityadmin |
16387 |
16387 |
db_ddladmin |
16389 |
16389 |
db_backupoperator |
16390 |
16390 |
db_datareader |
16391 |
16391 |
db_datawriter |
16392 |
16392 |
db_denydatareader |
16393 |
16393 |
db_denydatawriter |
16394 - 16399 |
16394 - 16399 |
Reserved |
16400 - 32767 |
Roles |
|
16400 - 2,147,483,647 |
Users, roles, application roles, aliases |
The user ID size is increased from smallint (16 bits) to int (32 bits). APIs that require a 16-bit user ID will return incorrect results if passed a 32-bit user ID. When migrating data and applications created for SQL Server 2000 or earlier, you should review code for references to the following deprecated interfaces.
sysusers
syscacheobjects
sysmembers
sysobjects
syspermissions
sysprocesses
sysprotects
systypes
USER_ID
These interfaces require 16-bit user IDs. They do not return correct results when used with 32-bit user IDs.