zoukankan      html  css  js  c++  java
  • 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 FilesMicrosoft SQL ServerMSSQL11.MSSQLSERVERMSSQLDATAHeaviDb.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

        如果本篇内容对大家有帮助,请关注博主。如果觉得不好,也欢迎拍砖。你们的反馈就是博主的动力!下篇内容,敬请期待!

  • 相关阅读:
    streamsets 集成 cratedb 测试
    streamsets k8s 部署试用
    streamsets rest api 转换 graphql
    StreamSets sdc rpc 测试
    StreamSets 相关文章
    StreamSets 多线程 Pipelines
    StreamSets SDC RPC Pipelines说明
    StreamSets 管理 SDC Edge上的pipeline
    StreamSets 部署 Pipelines 到 SDC Edge
    StreamSets 设计Edge pipeline
  • 原文地址:https://www.cnblogs.com/w-wanglei/p/5084532.html
Copyright © 2011-2022 走看看