Sql Server前因後果系列 必須知道的權限控制基礎篇

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

    在進入本篇內容以前,這裏有幾個問題:git

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

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

    3.對於一個登陸帳號,咱們能夠爲他設置哪些權限?服務器

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

    5.咱們能夠給登陸帳號設置權限,但清不清楚具體有哪兩種權限?框架

   

    若是你回答不上,那接下來的內容有必要知道。若是都能很清楚的回答出來,接下來的內容你能夠直接忽略。spa

    前一段時間寫了Sql Server前因後果系列的前四篇,包括數據庫的框架和配置、查詢過程跟蹤、數據庫庫和文件。說實話, 當時寫的時候本身都是隻知其一;不知其二,有些內容瞭解得不是很清楚。近來我一直沒有更新系列的後續內容,而是把時間用來寫一個小的數據庫權限管理系統,爲得就是把前面寫的系列隨筆涉及到的知識鞏固下。系統的主界面以下圖:日誌

clipboard

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

    像登陸帳號、數據庫以及權限等系統元數據通常是不容許直接操做的,那麼咱們怎樣讀取以及怎樣修改更新這些元數據?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

 

 

    若是本篇內容對你們有幫助,請關注博主。若是以爲很差,也歡迎拍磚。大家的反饋就是博主的動力!下篇內容,敬請期待!

相關文章
相關標籤/搜索