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

 

 

    若是本篇内容对你们有帮助,请关注博主。若是以为很差,也欢迎拍砖。大家的反馈就是博主的动力!下篇内容,敬请期待!