[聚合文章] SQL Server 安全篇——数据层面安全性(1)——架构

SQL Server 2018-01-24 13 阅读

在安全性主体层级之下,SQL Server 为保护数据提供了一组丰富的功能。本章将介绍架构、所有权链接和继承。本文集中介绍架构(Schema)。

正文:

如果学过编程语言特别是JAVA、C#等的话,应该听过命名空间(namespace)这个术语。是一个逻辑的容器,schema把数据库对象包在里面。并且在对象和它们的拥有者之间提供一个抽象层,每个数据库中的对象必须由一个数据库用户拥有。

从SQL Server 2005开始,一个用户拥有一个架构,而可能有10个表属于这个架构,那么这个用户就隐形地拥有这10个表。

这种抽象简化了更改数据库对象的所有权工作,在上面那个例子中,如果要把10个表的所有权改成另外一个用户,那么过去需要改最少10次,现在只需要直接把架构修改即可。

合理地使用架构同样可以简化权限管理,因为你只需要把安全主体的权限授予到一个架构上而不是单独的对象上面。比如,如果有5个sales相关的表:  SalesOrdersHeader ,  SalesOrderDetails ,  SalesPerson ,  Stores , 和Customers ,如果把这5个表都加入一个Sales的架构中,那么只需要对架构Sales进行授权增删改查到一个数据库角色(比如包括了所有销售团队的数据库用户)。而且授权给架构不仅仅对表有效,还对属于这个架构的视图、存储过程、函数有效。还可以对架构中的这些可执行对象授权EXECUTE。

现在来看看演示数据库AdventureWorks2017中的 SalesOrderHeader , SalesOrderDetail ,  SalesPerson ,  Employee , 和Person  表,如下图:

数据库关系图中已经替代了各表的主键和外键信息,但是注意表名后面的括号,这些就是架构,5个表分别属于Sales、HumanResources和Person架构。那么架构用来干嘛的?下面来演示一下,创建一个架构T,然后授权给用户George,并对这个架构的Select权限:

USE [master]
GO
CREATE LOGIN [George] WITH PASSWORD=N'xxxx', DEFAULT_DATABASE=[AdventureWorks2016], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
GO
USE [AdventureWorks2016]
GO
CREATE USER [George] FOR LOGIN [George]
GO
USE [AdventureWorks2016]
GO
ALTER ROLE [db_owner] ADD MEMBER [George]
GO
USE AdventureWorks2016 
GO 
CREATE SCHEMA T ; 
GO 
GRANT SELECT ON SCHEMA::T TO George ; 
GO
接下来,创建一个表,注意这里不带明显的架构名,那么就会自动把表的架构赋给dbo架构,然后我们把这个表的架构从dbo改成T:
USE AdventureWorks2016
GO
--如无指定,则默认为dbo
CREATE TABLE TestSchema
(
ID int
)
GO
--把表的架构传输给T,个人记忆方法(仅供参考),可以从后面读起:dbo.TestSchema Transfer (to) T
ALTER SCHEMA T TRANSFER dbo.TestSchema
GO
架构修改前后如图:

从贴图可见已经修改成功,需要说明的是,从最佳实践来看,不管是否db_owner角色成员,都应该使用[架构名].[表名]甚至[服务器].[库名]. [架构名].[表名]这种方式来访问,理由主要有两个:

1. 由于表名可能一样但是架构名不一样,如果不带架构名,可能访问报错,即使不报错,可能容易造成误操作。

2. 从性能来看,由于优化器也要区别表名是属于什么架构的,这部分必然带来开销。

另外,当你尝试删除架构时,会出现下图错误,因为还有表属于这个架构,可以使用下面的脚本把表的架构传输回去给dbo这个必定存在的架构中,然后就可以删除架构T:

USE AdventureWorks2016
GO
ALTER SCHEMA dbo TRANSFER T.TestSchema
GO

DROP SCHEMA T
GO

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。