許多開發人員在初接觸 SQL Server 時,常會混淆「登入名」與「使用者名」的概念。早期習慣使用 sa 登入直接管理所有資源,雖然方便,卻埋下安全隱患。網路上的教學文章雖多,但往往缺乏實作驗證,導致觀念不清。本文結合大量資料查閱與親自實驗,系統整理兩者的關係與運作機制,希望能幫助大家建立正確的安全架構觀念。
登入名是 SQL Server 執行個體層級的主體,儲存於 master 資料庫的 syslogins 系統表中。它的唯一功能是允許連線進入伺服器,本身不具備存取任何使用者資料庫物件的權限。常見的類型包含 SQL Server 驗證登入(如 sa)與 Windows 整合驗證登入。
使用者名存在於各個使用者資料庫內(儲存於 sysusers 或新版的 sys.database_principals),是登入名在該資料庫中的映射投影。透過對使用者授權(如加入 db_datareader 角色),間接賦予對應登入名存取該資料庫物件的權限。一個登入名可以在多個資料庫中映射為不同名稱的使用者,但每個資料庫中同一登入名只能對應一個使用者。
SQL Server 將此對應關係稱為「映射」。當使用登入名連線後,欲存取某資料庫時,引擎會自動檢查該資料庫中是否存在與該登入名關聯的使用者:
guest 使用者(若已啟用)存取,否則拒絕存取。這就像大樓與房間的關係:登入名是「大樓鑰匙」,讓你進入大樓(伺服器);使用者名是「房間鑰匙」,決定你能進入哪些房間(資料庫)以及在房間內能做什麼事。連接字串中的 User ID 參數指的也是登入名而非資料庫使用者名。
dbo (Database Owner) 是每個資料庫預設擁有者使用者。以 sa 登入或 Windows 系統管理員群組成員登入時,在資料庫中會被映射為 dbo 使用者。值得注意的是,dbo 使用者名固定為 dbo,不會隨登入名改變。例如建立登入 me 並在資料庫建立同名使用者 me,則該登入建立的物件擁有者為 me(如 me.Table1),而非 dbo。
每個資料庫都內建 public 角色,所有使用者自動隸屬且無法移除。它是權限繼承的基準基礎。
特殊使用者帳戶,當登入名無對應使用者時啟用。預設在 master、msdb、tempdb 啟用,使用者資料庫預設停用。啟用時需謹慎評估安全風險。
SQL Server 採用「擁有者.物件」的四部分命名法(類似 Oracle Schema),避免同名物件衝突。若使用者 me 需存取 you 建立的 TestTable,需滿足兩條件:
me 擁有 db_owner 角色權限(或至少具備該物件的權限)。SELECT * FROM you.TestTable。dbo 身為管理員,可無條件存取所有使用者的物件。若省略擁有者名稱,SQL Server 會依序嘗試:目前使用者同名物件 → dbo 同名物件。
login_ibrahim,僅能看見系統資料庫。Database Creator 伺服器角色,使其能建立資料庫。test,系統自動建立 dbo(映射至 login_ibrahim)與 guest 使用者。因 sysadmin 固定角色成員自動映射為 dbo,此時 test 資料庫的 dbo 同時對應 login_ibrahim 與 sa 兩個登入。login_ibrahim2(無伺服器角色),指定可存取 test 資料庫,系統自動建立同名使用者 login_ibrahim2。login_ibrahim2 登入嘗試建表失敗(無權限)。login_ibrahim(即 dbo)授予 login_ibrahim2 使用者 db_ddladmin 角色。login_ibrahim2 登入,成功建立資料表 T_ibrahim 並寫入資料。釐清「登入名負責進站、使用者名負責進廳、角色負責授權」的三層架構,是建立 SQL Server 安全體系的基石。實務上應遵循最小權限原則:建立專用登入、對應專用資料庫使用者、授予最精確的角色或物件權限,避免濫用 sa 或 db_owner,方能兼顧安全與維運彈性。