Sql Server来龙去脉系列 必须知道的权限控制基础篇

2023年 8月 13日 76.9k 0

题外话:近看到各种吐槽.NET怎么落寞、.NET怎么不行了、.NET工资低的帖子。我也吐槽一句:一个程序猿的自身价值不是由他选择了哪一门技术来决定,而是由他自身能创造出什么价值来决定。

    在进入本篇内容之前,这里有几个问题:

    1.一般程序猿都知道怎样创建、修改、登录账号,但知不知道登陆账号存储在哪个表或者视图?

    2.数据库中其实存在登录账号和用户两个概念,你能解释清楚这两个概念吗?

    3.对于一个登录账号,我们可以为他设置哪些权限?

    4.你清不清楚数据库信息存储在哪些表或试图?

    5.我们可以给登录账号设置权限,但清不清楚具体有哪两种权限?

   

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

    前一段时间写了Sql Server来龙去脉系列的前四篇,包括数据库的框架和配置、查询过程跟踪、数据库库和文件。说实话, 当时写的时候自己都是一知半解,有些内容了解得不是很清楚。近来我一直没有更新系列的后续内容,而是把时间用来写一个小的数据库权限管理系统,为得就是把前面写的系列随笔涉及到的知识巩固下。系统的主界面如下图:

    界面上的导航菜单也就是这篇随笔的主要内容,包括登陆账号、数据库、权限控制。权限控制包括了服务权限和数据库权限。需要说明的是:界面上的说的用户实际是登陆账号,而数据库用户和账号是有区别的。

    像登录账号、数据库以及权限等系统元数据一般是不允许直接操作的,那么我们怎样读取以及怎样修改更新这些元数据?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管理登录账号。如下图:

    这里有个疑问:这些账号信息是从哪里查出来的?之前我们介绍了系统元数据可通过系统视图查询。登录账号的目录视图是sys.syslogins,我们可通过下面的查询语句查询登录账号信息:

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

    执行结果如下:

    返回的结果包括了name、dbname、password、language,这几个字段是经常涉及到的,每行数据不止上面这些字段,还包括服务权限字段,如下:

    至于这些字段有什么用,后面介绍权限时再说明。在我自己写的数据管理系统中就是通过从sys.syslogins查询数据。系统界面如下:

创建账号

    知道数据怎么查询后,我们继续看怎样创建登录账号,下图就是创建登录账号的界面:

    界面包括了登录名、密码、默认数据库、默认语言,登陆名和密码操作者自己输入,但默认数据库和默认语言只能选择数据库存在的。所有我们必须得知道怎样查询数据库表和语言表,这里就提出了 另外两个目录视图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

    结果如下:

    结果中包含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

    结果如下:

    通过结果一目了然的看出每个数据库的所属者。记得在初始化系统数据库脚本时,一般都会判断数据库是否存在。现在我们知道可以通过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目录视图中查看,先看看权限系统的数据库查询界面,如下图所示:

    通过列表我们能看到数据库名称、数据库所有者、创建时间以及文件路径。然后我们执行语句:

select * from sys.databases

    执行结果如下:

    分析查询结果,我们单从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

    执行结果如下:

    从查询结果可以看出,每个数据库基本上包含两行数据。其中,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

    查询结果如下:

    这里有个问题:为什么查询结果只返回了两条数据?这是因为我当前选择的数据是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中的系统视图,现在已经不建议使用了。以上几个数据库的关联关系如下:

    视图表已经有了,可直接通过多表关联查询出权限管理展示的结果。关联的查询语句如下:

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 =

    执行结果如下:

创建数据库

    作为一个开发人员,肯定会经常涉及到创建数据库。那么怎样创建数据库以及创建数据库需要哪些参数?通过创建登录账号(CREATE LOGINS )语句,我们 可以推理创建数据库也是使用数据定义语句CREATE DATABASE来创建数据。我们先看看权限管理数据库的查询界面:

    上图包含了数据库名称、数据库所有者、初始化大小、增长方式、以及文件的大值。当然,还必须有数据库文件信息,我直接在后台把文件路径写死了,和系统数据库同目录。数据库名称由我们自己定义,数据库所有者可通过sys.syslogins查询选择,初始值大小由我们自己设置,增长方式包括按照固定值大小或者按照百分比增长、文件大值包括无限制或者设置大值、数据库文件路径配置为磁盘路径。

    参数已经了解,接下来分析具体的创建语句,我们可以从msdn上查看到完整的数据库创建语句:

Create a databaseCREATE DATABASE database_name [ CONTAINMENT = { NONE | PARTIAL } ][ ON [ PRIMARY ] [ ,...n ] [ , [ ,...n ] ] [ LOG ON [ ,...n ] ] ] [ COLLATE collation_name ][ WITH [,...n ] ][;]

::={ FILESTREAM ( [,...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 = | DB_CHAINING { OFF | ON } | TRUSTWORTHY { OFF | ON }}

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

::= {( 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 name [ [ CONTAINS FILESTREAM ] [ DEFAULT ] | CONTAINS MEMORY_OPTIMIZED_DATA ] [ ,...n ]}

::={ ENABLE_BROKER | NEW_BROKER | ERROR_BROKER_CONVERSATIONS}

    具体参数请参考:https://msdn.microsoft.com/zh-cn/library/ms176061(v=sql.120).aspx

    现在我们通过权限管理系统创建数据库,在创建界面输入数据库参数,如下图所示:

    点击“创建”按钮后, 服务器自动生成数据库创建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 =

    查询结果如下:

    查询的数据结果我们不能直接使用,数据库大小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 = 以页数为单位表示增长大小。

相关文章

SQL数据库触发器语法详解 (sql数据库触发器语法)

2023-08-06
数据库
语法
触发器

快速简单的删除Oracle数据库字段方法 (删除oracl数据库字段)

2023-08-06
数据库
字段
删除

如何打开社工数据库bak文件 (社工数据库bak怎么打开)

2023-08-06
数据库
打开
社工

实现数据库按拼音排序的方法和技巧 (数据库按拼音排序)

2023-08-06
数据库
排序
按拼音

探究Sybase数据库的性能和功能特点 (sybase数据库怎么样)

2023-08-06
数据库
性能
探究

SQL Server 如何成功建立自己的数据库? (sql server 建立数据库)

2023-08-06
数据库
自己的
建立

如何在Oracle中查看数据库触发器? (oracle查看数据库触发器)

2023-08-06
数据库
查看
触发器

数据库表数据量千万级,对性能影响有多大? (数据库表千万级数据量多吗)

2023-08-06
数据库
级数
有多大

如何使用Oracle按时间导出表数据库? (oracle按时间导出表数据库)

2023-08-06
数据库
导出
如何使用

数据库存储:帖子长期保存,信息永不丢失 (帖子存数据库)

2023-08-06
数据库
丢失
帖子

小米六数据库:全方位数据保障和优化方案 (小米六数据库)

2023-08-05
数据库
优化
小米

简易教程:使用dbe数据库实现数据连接 (dbe数据库 数据连接)

2023-08-05
数据
数据库
连接

Oracle实现多个数据库链接的简便方法 (oracle链接多个数据库)

2023-08-05
数据库
多个
链接

数据库索引:用哪种方法建立? (数据库索引用什么建的)

2023-08-05
索引
数据库
哪种

实现高效缓存同步:Redis数据库技巧大全 (redis 数据库缓存同步)

2023-08-05
数据库
缓存
同步

如何利用数据库实现高效的模糊匹配查询? (数据库实现模糊查询)

2023-08-05
查询
数据库
模糊

数据库有哪些安装方式和位置? (数据库是装在什么上)

2023-08-05
数据库
位置
装在

Lactmed数据库:妈妈们必备的喂养指南 (lactmed 数据库)

2023-08-05
数据库
必备
喂养

数据库设计中的主属性定义及作用 (数据库主属性是什么)

2023-08-05
数据库
定义
属性

数据库分区操作不当常常造成分区不清的问题 (分区不清数据库)

2023-08-05
数据库
分区
不清

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论