Sql Server來龍去脈系列 必須知道的權限控制基礎篇


    題外話:最近看到各種吐槽.NET怎么落寞、.NET怎么不行了、.NET工資低的帖子。我也吐槽一句:一個程序猿的自身價值不是由他選擇了哪一門技術來決定,而是由他自身能創造出什么價值來決定。

    在進入本篇內容之前,這里有幾個問題:

    1.一般程序猿都知道怎樣創建、修改、登錄賬號,但知不知道登陸賬號存儲在哪個表或者視圖?

    2.數據庫中其實存在登錄賬號和用戶兩個概念,你能解釋清楚這兩個概念嗎?

    3.對於一個登錄賬號,我們可以為他設置哪些權限?

    4.你清不清楚數據庫信息存儲在哪些表或試圖?

    5.我們可以給登錄賬號設置權限,但清不清楚具體有哪兩種權限?

   

    如果你回答不上,那接下來的內容有必要知道。如果都能很清楚的回答出來,接下來的內容你可以直接忽略。

    前一段時間寫了Sql Server來龍去脈系列的前四篇,包括數據庫的框架和配置、查詢過程跟蹤、數據庫庫和文件。說實話, 當時寫的時候自己都是一知半解,有些內容了解得不是很清楚。近來我一直沒有更新系列的后續內容,而是把時間用來寫一個小的數據庫權限管理系統,為得就是把前面寫的系列隨筆涉及到的知識鞏固下。系統的主界面如下圖:

clipboard

    界面上的導航菜單也就是這篇隨筆的主要內容,包括登陸賬號、數據庫、權限控制。權限控制包括了服務權限和數據庫權限。需要說明的是:界面上的說的用戶實際是登陸賬號,而數據庫用戶和賬號是有區別的。

    像登錄賬號、數據庫以及權限等系統元數據一般是不允許直接操作的,那么我們怎樣讀取以及怎樣修改更新這些元數據?Sql Server為開發人員提供了系統視圖、存儲過程、DDL(數據定義語言)用來讀取以及更改系統元數據。DDL全稱是Data Definition Laguage,它的語法包括我們經常用到的CREATE、ALTER、DROP等。開發人員在MSDN上也能找到對應的在線說明。下面分別給出幫助鏈接:

    1.系統視圖:https://msdn.microsoft.com/zh-cn/library/ms177862(v=sql.120).aspx,查看元數據一般都是通過目錄視圖查找。

    2.存儲過程:https://msdn.microsoft.com/zh-cn/library/ms187961(v=sql.120).aspx

    3.DDL:https://msdn.microsoft.com/zh-cn/library/ff848799(v=sql.120).aspx

    接下來我們分別介紹前面說的登錄賬號管理、數據庫管理以及權限管理。

登錄賬號管理

賬號查詢

    管理維護Sql Server數據庫,一般都是使用Sql Server Management Studio。當我們成功鏈接數據庫實例后,可通過Security/Logins管理登錄賬號。如下圖:

clipboard[1]

    這里有個疑問:這些賬號信息是從哪里查出來的?之前我們介紹了系統元數據可通過系統視圖查詢。登錄賬號的目錄視圖是sys.syslogins,我們可通過下面的查詢語句查詢登錄賬號信息:

select * from sys.syslogins, 字段說明:https://msdn.microsoft.com/zh-cn/library/ms178593(v=sql.120).aspx

    執行結果如下:

clipboard[2]

    返回的結果包括了name、dbname、password、language,這幾個字段是經常涉及到的,每行數據不止上面這些字段,還包括服務權限字段,如下:

clipboard[3]

    至於這些字段有什么用,后面介紹權限時再說明。在我自己寫的數據管理系統中就是通過從sys.syslogins查詢數據。系統界面如下:

clipboard[4]

創建賬號

    知道數據怎么查詢后,我們繼續看怎樣創建登錄賬號,下圖就是創建登錄賬號的界面:

clipboard[5]

    界面包括了登錄名、密碼、默認數據庫、默認語言,登陸名和密碼操作者自己輸入,但默認數據庫和默認語言只能選擇數據庫存在的。所有我們必須得知道怎樣查詢數據庫表和語言表,這里就提出了 另外兩個目錄視圖sys.databases、sys.syslanguages。通過名字也能知道這兩個表分別存儲的是數據庫和語言的元數據。執行下面語句查詢數據庫中存在哪些數據庫:

select name, database_id, owner_sid, create_date from sys.databases,字段說明:https://msdn.microsoft.com/zh-cn/library/ms178534(v=sql.120).aspx

    結果如下:

clipboard[6]

    結果中包含owner_sid字段,這個字段就是存儲的登錄賬號的系統ID,一般是哪個登錄賬號創建的數據庫,這個數據庫就屬於這個創建它的登陸賬號。執行下面語句:

select db.name, db.database_id, lg.name, db.create_date from sys.databases db inner join sys.syslogins lg on db.owner_sid = lg.sid

    結果如下:

clipboard[7]

    通過結果一目了然的看出每個數據庫的所屬者。記得在初始化系統數據庫腳本時,一般都會判斷數據庫是否存在。現在我們知道可以通過sys.databases視圖查看數據庫信息,那么我們也通過以下語句判斷一個數據庫是否存在:

if exists (select * from sys.databases where name = '數據庫名') 
    drop database [數據庫名]

    sys.syslanguages的數據比較簡單,這里就不再說明。可通過https://msdn.microsoft.com/zh-cn/library/ms190303(v=sql.120).aspx查看字段解釋。現在再回到之前的創建界面,數據庫和語言我們都能提供出來了,登錄名和密碼也輸入了。但怎么把數據插入到數據庫?這里就提到前面說的數據定義語言DDL,用CREATE LOGIN關鍵字創建登錄賬號。先看下在系統中我拼湊的SQL語句:

string sql = string.Format("CREATE LOGIN [{3}] WITH PASSWORD = N'{0}', DEFAULT_DATABASE =[{1}], DEFAULT_LANGUAGE =[{2}]" , login.Password, login.DbName, login.Laguage, login.Name);

   語句很簡單,PASSWORD設置密碼,DEFAULT_DATABASE設置默認數據庫,DEFAULT_LANGUAGE設置默認語言。當然創建登錄賬號的參數肯定不止這些,我們可通過https://msdn.microsoft.com/zh-cn/library/ms189751(v=sql.120).aspx查看創建登錄賬號所有的參數。

修改賬號

   現在已經知道怎樣創建登錄賬號了,但有些時候我們需要修改登錄賬號的某些信息,例如密碼、默認數據庫。修改登錄賬號使用DDL語言的ALTER LOGIN關鍵字。修改語句和創建語句極其相似,只是把CREAT關鍵字改成了ALTER。看看下面的系統修改登錄賬號代碼:

string sql = string.Format("ALTER LOGIN {0} WITH PASSWORD = N'{1}', DEFAULT_DATABASE =[{2}],DEFAULT_LANGUAGE =[{3}]", name, login.Password, login.DbName, login.Laguage)
//參考:https://msdn.microsoft.com/zh-cn/library/ms189828(v=sql.120).aspx

刪除賬號

    最后還剩下刪除操作,我們知道刪除表的語句一般是 DROP TABLE [表名],而刪除登陸賬號也相似,執行:

DROP LOGIN [登錄名], https://msdn.microsoft.com/zh-cn/library/ms188012(v=sql.120).aspx

    知道了上面這些內容,我們就可以很容易理解怎樣增刪改查登錄賬號了。但一個登錄賬號不是單獨的存在數據庫中,它還關聯了服務權限、數據庫權限等。

數據庫管理

查詢數據庫

    數據庫同樣也涉及到增刪改查,首先看看怎樣查詢數據庫。在上一節我們知道數據庫可以從sys.databases目錄視圖中查看,先看看權限系統的數據庫查詢界面,如下圖所示:

clipboard[8]

    通過列表我們能看到數據庫名稱、數據庫所有者、創建時間以及文件路徑。然后我們執行語句:

select * from sys.databases

    執行結果如下:

clipboard[9]

    分析查詢結果,我們單從sys.databases視圖中是看不到數據庫擁有者的名字以及數據庫文件路徑。但上一節我們講了登錄賬號,我們知道它也有一個sid,所有可以通過sys.databases中的owner_sid和sys.logins關聯。但數據庫文件從哪里查詢?這里又提出了另外一個目錄視圖sys.master_files,它包含了數據庫文件的信息。先執行下面語句:

select * from sys.master_files,https://msdn.microsoft.com/zh-cn/library/ms186782(v=sql.120).aspx

    執行結果如下:

clipboard[10]

    從查詢結果可以看出,每個數據庫基本上包含兩行數據。其中,type字段分別為ROWS、LOG,表示數據和日志文件。結果字段中還有一個file_id,它關聯了另外一張數據庫文件視圖sys.database_files。sys.database_files存儲了數據庫文件的詳細信息,包括文件類型、文件大小、文件最大值、文件增長值。執行下面語句:

select * from sys.database_files,視圖說明:https://msdn.microsoft.com/zh-cn/library/ms174397(v=sql.120).aspx

    查詢結果如下:

clipboard[11]

    這里有個問題:為什么查詢結果只返回了兩條數據?這是因為我當前選擇的數據是master,sys.database_files只返回當前數據庫的文件信息。現在數據庫信息都知道了.另外,還有一個兼容數據庫視圖sys.sysdatabases(視圖說明:https://msdn.microsoft.com/zh-cn/library/ms179900(v=sql.120).aspx)。它和sys.databases差不多,但能查詢出文件的物理路徑。sys.sysdatabases是sql server 2000中的系統視圖,現在已經不建議使用了。以上幾個數據庫的關聯關系如下:

clipboard[12]

    視圖表已經有了,可直接通過多表關聯查詢出權限管理展示的結果。關聯的查詢語句如下:

select db.name as Name, db.database_id as DbId, db.create_date as CrTime, db.owner_sid as OwnerId, lg.name as OwnerName, mf.physical_name  as FileName    
 from sys.databases db    
left join sys.syslogins lg on db.owner_sid = lg.sid    
left join sys.master_files mf on db.database_id = mf.database_id and mf.type = 0

    執行結果如下:

clipboard[13]

創建數據庫

    作為一個開發人員,肯定會經常涉及到創建數據庫。那么怎樣創建數據庫以及創建數據庫需要哪些參數?通過創建登錄賬號(CREATE LOGINS )語句,我們 可以推理創建數據庫也是使用數據定義語句CREATE DATABASE來創建數據。我們先看看權限管理數據庫的查詢界面:

clipboard[14]

    上圖包含了數據庫名稱、數據庫所有者、初始化大小、增長方式、以及文件的最大值。當然,還必須有數據庫文件信息,我直接在后台把文件路徑寫死了,和系統數據庫同目錄。數據庫名稱由我們自己定義,數據庫所有者可通過sys.syslogins查詢選擇,初始值大小由我們自己設置,增長方式包括按照固定值大小或者按照百分比增長、文件最大值包括無限制或者設置最大值、數據庫文件路徑配置為磁盤路徑。

    參數已經了解,接下來分析具體的創建語句,我們可以從msdn上查看到完整的數據庫創建語句:

Create a database
CREATE DATABASE database_name 
[ CONTAINMENT = { NONE | PARTIAL } ]
[ ON 
      [ PRIMARY ] <filespec> [ ,...n ] 
      [ , <filegroup> [ ,...n ] ] 
      [ LOG ON <filespec> [ ,...n ] ] 
] 
[ COLLATE collation_name ]
[ WITH  <option> [,...n ] ]
[;]

<option> ::=
{
      FILESTREAM ( <filestream_option> [,...n ] )
    | DEFAULT_FULLTEXT_LANGUAGE = { lcid | language_name | language_alias }
    | DEFAULT_LANGUAGE = { lcid | language_name | language_alias }
    | NESTED_TRIGGERS = { OFF | ON }
    | TRANSFORM_NOISE_WORDS = { OFF | ON}
    | TWO_DIGIT_YEAR_CUTOFF = <two_digit_year_cutoff> 
    | DB_CHAINING { OFF | ON }
    | TRUSTWORTHY { OFF | ON }
}

<filestream_option> ::=
{
      NON_TRANSACTED_ACCESS = { OFF | READ_ONLY | FULL }
    | DIRECTORY_NAME = 'directory_name' 
}

<filespec> ::= 
{
(
    NAME = logical_file_name ,
    FILENAME = { 'os_file_name' | 'filestream_path' } 
    [ , SIZE = size [ KB | MB | GB | TB ] ] 
    [ , MAXSIZE = { max_size [ KB | MB | GB | TB ] | UNLIMITED } ] 
    [ , FILEGROWTH = growth_increment [ KB | MB | GB | TB | % ] ]
)
}

<filegroup> ::= 
{
FILEGROUP filegroup name [ [ CONTAINS FILESTREAM ] [ DEFAULT ] | CONTAINS MEMORY_OPTIMIZED_DATA ]
    <filespec> [ ,...n ]
}

<service_broker_option> ::=
{
    ENABLE_BROKER
  | NEW_BROKER
  | ERROR_BROKER_CONVERSATIONS
}

    具體參數請參考:https://msdn.microsoft.com/zh-cn/library/ms176061(v=sql.120).aspx

    現在我們通過權限管理系統創建數據庫,在創建界面輸入數據庫參數,如下圖所示:

clipboard[15]

    點擊“創建”按鈕后, 服務器自動生成數據庫創建SQL語句 ,如下:

USE master;
CREATE DATABASE HeaviDb 
ON(
Name = HeaviDb,
FILENAME = 'D:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\HeaviDb.mdf',
SIZE = 10,
FILEGROWTH = 2MB,
MAXSIZE = 500)

    在創建數據庫時,我們一般要把當前數據庫切換到master數據庫。上面的語句只指定了FILENAME,而沒有指定log的FILENAME,這種情況SQL SERVER會自動在FILENAME同目錄下為我們自動創建HeaviDb_log.ldf文件。SIZE設置為10,這里沒有單位,默認單位為MB,也可以顯示指定KB、MB、GB、TB后綴,例如SIZE = 10MB或者SIZE = 10GB。FILEGROWTH設置為2MB,即數據庫按照2MB自增長,另外我們也可以按照百分比增長,例如FILEGROWTH = 10%。MAXSIZE設置為500,默認單位也是MB。如果我們不限制數據庫文件大小,可直接用UNLIMITED代替MAXSIZE = 500。執行以上SQL語句,我們就能在數據庫中查看到該數據庫了。

修改數據庫

    這一節討論怎樣修改數據庫,但這里會涉及到比較核心的知識點。在權限管理系統中,選中數據庫列表某一列,點擊“修改”按鈕,彈出修改數據庫界面。但這里有一個問題,在數據庫列表中只包含了 數據庫名稱、文件以及數據庫所有者信息。而我們修改界面展示了數據庫初始大小以及自增長值。這些信息在列表中是沒有的。但通過數據庫查詢我們知道這些信息保存在sys.master_files中。執行查詢語句:

select 
mf.database_id as DbId, mf.name as Name, 
mf.size as InitSize, mf.max_size as MaxSize, mf.growth as Growth, mf.is_percent_growth as IsPercentGrowth 
from sys.master_files mf where mf.type = 0

    查詢結果如下:

clipboard[16]

    查詢的數據結果我們不能直接使用,數據庫大小InitSize、數據庫最大值MaxSize、自增長值Growth這些數據不能直接展示在界面,那這些數據到底是什么意思呢?先看看msdn對這幾個字段的描述:

size int 當前文件大小(以 8 KB 為單位的頁數)。 對於數據庫快照來說,size 表示該快照可以一直用於文件的最大空間。
max_size int

最大文件大小(以 8 KB 為單位的頁數):

0 = 不允許增長。

-1 = 文件將一直增長到磁盤充滿為止。

268435456 = 日志文件將增長到最大大小 2 TB。

growth int

0 = 文件大小固定,不會增長。

>0 = 文件將自動增長。

如果 is_percent_growth = 0,則以若干個 8 KB 頁為增量遞增,舍入為 64 KB

如果 is_percent_growth = 1,增量將用整數百分比表示。

is_percent_growth bit

1 = 文件的增長以百分比表示。

0 = 以頁數為單位表示絕對增長大小。

    分析幾個字段:

    1.size:沒有直接存儲文件大小,而是存儲文件的總頁數,每一頁大小為8KB。以MB為size單位,size的實際值則應該為:(size * 8 /1024)MB;

    2. max_size:有三種值,一是等於-1,二是等於0,另一種是大於0 。等於-1表示UNLIMITED(沒有限制)。等於0表示不允許增長。大於0時和size相似,以MB為max_size單位,max_size實際值則應該為:(max_size * 8 /1024)MB;

    3.is_percent_growth:值等於0或者1,等於1表示按百分比自增長。等於0表示按固定值增長;

    4.growth:等於0表示固定大小,不會自增增長。大於0時依賴於is_percent_growth的值。如果is_percent_growth=0,growth按固定數字自增長。以MB為單位,growth實際值為(growth * 8 /1024)MB。如果is_percent_growth=1,則growth的實際值為growth%;

    以上字段了解清楚后,我們的數據庫文件參數就能顯示出來了。例如,修改剛才創建的HeaviDb數據庫,彈出修改界面如下:

clipboard[17]

   修改初始值為20,增長方式為pecent並且值為10,文件最大值沒有限制。這里需要說明幾點:

    1.修改的初始值不能小於當前數據庫文件的實際大小;

    2.如果文件最大值限制為固定值,那么這個固定值不能小於當前數據庫大小以及修改后的數據庫大小(初始值);

    修改參數后界面如下:

clipboard[18]

    點擊“保存”按鈕,后台生成的SQL語句如下:

USE master;
ALTER DATABASE HeaviDb 
MODIFY FILE (Name = HeaviDb,SIZE = 20,FILEGROWTH = 20,MAXSIZE = UNLIMITED)

    修改數據庫使用DDL的ALTER DATABASE語句,修改文件使用MODIFY FILE語句。完整的數據庫修改SQL請查看:

https://msdn.microsoft.com/zh-cn/library/ms174269(v=sql.120).aspx

刪除數據庫

    數據庫的刪除語句比較簡單,SQL與語句如下:

USE master;
DROP DATABASE HeaviDb

    刪除數據庫必須知道:系統數據庫是不能刪除的;不能刪除正在使用的數據庫。

總結

    本篇隨筆主要介紹了登錄賬號的查詢、創建、修改、刪除,以及數據庫的查詢、創建、修改、刪除所涉及的系統視圖以及DDL語句。通過這篇內容我們能夠比較清楚的了解登錄賬號以及數據庫在SQL SERVER中的存儲元數據結構。本篇的內容都是一些基礎知識,但同時也是比較重要的基礎知識。下一篇將會詳細分析數據庫中登錄賬號和數據庫的權限設置

附錄

sys.syslogins

每個登錄帳戶在表中對應一行 https://msdn.microsoft.com/zh-cn/library/ms178593(v=sql.120).aspx
sys.databases 為 SQL Server 實例中的每個數據庫都包含一行 https://msdn.microsoft.com/zh-cn/library/ms178534(v=sql.120).aspx
sys.syslanguages 對於 SQL Server 實例中的每種語言都包含一行 https://msdn.microsoft.com/zh-cn/library/ms190303(v=sql.120).aspx
sys.master_files 每個存儲在 master 數據庫中的數據庫文件各占一行。 這是一個系統范圍視圖 https://msdn.microsoft.com/zh-cn/library/ms186782(v=sql.120).aspx
sys.database_files 每個存儲在數據庫本身中的數據庫文件在表中占用一行。 https://msdn.microsoft.com/zh-cn/library/ms174397(v=sql.120).aspx
sys.sysdatabases Microsoft SQL Server 實例中的每個數據庫在該表中各對應一行 https://msdn.microsoft.com/zh-cn/library/ms179900(v=sql.120).aspx
CREATE LOGIN 為 數據庫引擎 和 SQL Server 創建Azure SQL Database登錄名 https://msdn.microsoft.com/zh-cn/library/ms189751(v=sql.120).aspx
ALTER LOGIN ALTER LOGIN https://msdn.microsoft.com/zh-cn/library/ms189828(v=sql.120).aspx
DROP LOGIN 刪除 SQL Server 登錄帳戶 https://msdn.microsoft.com/zh-cn/library/ms188012(v=sql.120).aspx
CREATE DATABASE 建一個新數據庫及存儲該數據庫、數據庫快照的文件,或從先前創建的數據庫的已分離文件中附加數據庫 https://msdn.microsoft.com/zh-cn/library/ms176061(v=sql.120).aspx
ALTER DATABASE 修改一個數據庫或與該數據庫關聯的文件和文件組 https://msdn.microsoft.com/zh-cn/library/ms174269(v=sql.120).aspx
DROP DATABASE 從 SQL Server 實例中刪除一個或多個用戶數據庫或數據庫快照 https://msdn.microsoft.com/zh-cn/library/ms178613(v=sql.120).aspx

 

 

    如果本篇內容對大家有幫助,請關注博主。如果覺得不好,也歡迎拍磚。你們的反饋就是博主的動力!下篇內容,敬請期待!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM