1. 程式人生 > >SQL Server 安全篇——資料層面安全性(1)——架構

SQL Server 安全篇——資料層面安全性(1)——架構

在安全性主體層級之下,SQL Server 為保護資料提供了一組豐富的功能。本章將介紹架構、所有權連結和繼承。本文集中介紹架構(Schema)。

正文:

如果學過程式語言特別是JAVA、C#等的話,應該聽過名稱空間(namespace)這個術語。是一個邏輯的容器,schema把資料庫物件包在裡面。並且在物件和它們的擁有者之間提供一個抽象層,每個資料庫中的物件必須由一個數據庫使用者擁有。 從SQL Server 2005開始,一個使用者擁有一個架構,而可能有10個表屬於這個架構,那麼這個使用者就隱形地擁有這10個表。 這種抽象簡化了更改資料庫物件的所有權工作,在上面那個例子中,如果要把10個表的所有權改成另外一個使用者,那麼過去需要改最少10次,現在只需要直接把架構修改即可。 合理地使用架構同樣可以簡化許可權管理,因為你只需要把安全主體的許可權授予到一個架構上而不是單獨的物件上面。比如,如果有5個sales相關的表:  SalesOrdersHeader ,  SalesOrderDetails ,  SalesPerson ,  Stores , 和Customers ,如果把這5個表都加入一個Sales的架構中,那麼只需要對架構Sales進行授權增刪改查到一個數據庫角色(比如包括了所有銷售團隊的資料庫使用者)。而且授權給架構不僅僅對錶有效,還對屬於這個架構的檢視、儲存過程、函式有效。還可以對架構中的這些可執行物件授權EXECUTE。 現在來看看演示資料庫AdventureWorks2017中的 SalesOrderHeader , SalesOrderDetail ,  SalesPerson ,  Employee , 和Person  表,如下圖:
資料庫關係圖中已經替代了各表的主鍵和外來鍵資訊,但是注意表名後面的括號,這些就是架構,5個表分別屬於Sales、HumanResources和Person架構。那麼架構用來幹嘛的?下面來演示一下,建立一個架構T,然後授權給使用者George,並對這個架構的Select許可權:
USE [master]
GO
CREATE LOGIN [George] WITH PASSWORD=N'xxxx', DEFAULT_DATABASE=[AdventureWorks2016], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
GO
USE [AdventureWorks2016]
GO
CREATE USER [George] FOR LOGIN [George]
GO
USE [AdventureWorks2016]
GO
ALTER ROLE [db_owner] ADD MEMBER [George]
GO
USE AdventureWorks2016 
GO 
CREATE SCHEMA T ; 
GO 
GRANT SELECT ON SCHEMA::T TO George ; 
GO 
 接下來,建立一個表,注意這裡不帶明顯的架構名,那麼就會自動把表的架構賦給dbo架構,然後我們把這個表的架構從dbo改成T:
USE AdventureWorks2016
GO
--如無指定,則預設為dbo
CREATE TABLE TestSchema
(
ID int
)
GO
--把表的架構傳輸給T,個人記憶方法(僅供參考),可以從後面讀起:dbo.TestSchema Transfer (to) T
ALTER SCHEMA T TRANSFER dbo.TestSchema
GO
架構修改前後如圖: 從貼圖可見已經修改成功,需要說明的是,從最佳實踐來看,不管是否db_owner角色成員,都應該使用[架構名].[表名]甚至[伺服器].[庫名].[架構名].[表名]這種方式來訪問,理由主要有兩個: 1. 由於表名可能一樣但是架構名不一樣,如果不帶架構名,可能訪問報錯,即使不報錯,可能容易造成誤操作。 2. 從效能來看,由於優化器也要區別表名是屬於什麼架構的,這部分必然帶來開銷。 另外,當你嘗試刪除架構時,會出現下圖錯誤,因為還有表屬於這個架構,可以使用下面的指令碼把表的架構傳輸回去給dbo這個必定存在的架構中,然後就可以刪除架構T:
USE AdventureWorks2016
GO
ALTER SCHEMA dbo TRANSFER T.TestSchema
GO

DROP SCHEMA T
GO