5 . 4 . 3 架构
2018-07-15 14:34 笑一笑十年少!!! 阅读(267) 评论(0) 编辑 收藏 举报5 . 4 . 3 架构
SQL Server 2008按 ANSI标准中的定义实现了数据库架构。SQL Server 2008中几乎每个对
象都存在于一个已定义的架构中。架构只是一种组织数据库对象并为它所包含的对象指派权限
的方法。架构本身可为任意数据库主体(包括数据库角色和应用程序角色)所有,同时包含多个
由不同用户拥冇的对象。在架构中,对象的名称不能重复。然而,如果它们存在于不同的架构
中,那么可以有相同的名称。例如,如果在服务器AughtEight上的Sales架构中创建了一个名
为 Inventory的表,这个表名称就变成AughtEight.Sales.lnventory。在 Marketing染构中可以创建 另一个名为Inventory的表,它的名称则是AughtEight.Marketing.Inventory。尽管这是可行的,
但我认为这并不是个好主意,因为这会使不熟悉该数据库的用户感到困惑,在以后也可能生成
意外的查询结果。架构真正的强大之处在于它构成了 一个安全作用域,数据库管理员可以使用
这个安全作用域来控制对架构中的所有对象的访问。第6 章对此有详细介绍。
在 SQL Server 2008中,数据库主体被赋予一个架构的所有权,而该架构又拥有表、视 图、存储过程和函数等组成对象。如果需要删除拥有某个架构的用户,那么必须首先把该
架构的所有权赋予另一个用户。最简单的解决方案就是使dbo用户拥有所有架构。dbo用 户是一个内置用户,映射至固定服务器角色sysadmin的任意成员。dbo用户总是存在,且 不能被删除,因此它是架构所有权的最理想候选人。要了解有关dbo用户、固定服务器角
色和SQL Server 2008安全性的更多信息,请参阅第6 章。
1. 架构和名称解析
由于架构只是对象容器,因此在SQL Server 2008中引用数据库对象时,设定对象引用 的上下文是很重要的。每个用户都被指派一个默认的架构。当他们登录到SQL Server并引 用数据库对象时,这个默认架构将在该对象的引用方式中发挥独特的作用。
例如,假设在AdventureWorks2008数据库中创建了一个名为FredF的用户,并把默认
架构Sales指派给他。如果FredF登录并执行SELECT* FROM CreditCard査询,由于其默 认染构是 Sales,CreditCard 表将被解析为 Adventureworks2008.Sales.CreditCard。 由于
Sales.CreditCard表存在,因此查询将返回该表的内容。
如果 FredF 执行 SELECT * FROM Person 查询,Person 表将被解析为 Adventureworks2008.
Salesperson,这是一个并不存在的表。由于SQL Server在 FredF的默认架构中找不到Person 表,它将默认去dbo架构中寻找AdventureWorks2008.dbo.Person表,同样这也不会成功。
此时,SQL Server就会返回错误“无效的对象名称”。
2. 创建架构
要创建架构,唯一需要的信息就是架构的名称。架构所有权默认属于运行创建脚本的
用户,但可以把任何有效的数据库用户指定为所有者。最简单的方法就是将dbo指定为架 构所有者,但在有些情况下,把一个锌通用户指定为所有者比较合适。CREATE SCHEMA
语句的语法和例子如下所示:
CREATE SCHEMA Schema_Name [ AUTHORIZATION owner ]
USE AdventureWorks2008 GO
CREATE SCHEMA Operations AUTHORIZATION dbo
该 CREATE SCHEMA语句之后的任何架构作用域的语句都将位于刚才创建的架构的
作用域内,如下例所示:
USE AdventureWorks2008 GO
CREATE SCHEMA Operations AUTHORIZATION dbo
CREATE TABLE DeliveryDriver (DriverlD int IDENTITY NOT NULL ,LName varchar(75) NOT NULL
, FName v a rc h a r(75) NOT NULL)
GRANT SELECT ON DeliveryDriver TO FredF
虽 然 在 CREATE TABLE语句中没有指定架构,此 脚本仍将DeliveryDriver表放入
Operations架构中。甚至GRANT SELECT语句也会成功,尽管在该语句中未指派架构,它 默认使用Operations架构,因为CREATE SCHEMA语句为批处理中的其余语句设定了该 架构的作用域。如果对脚本稍做改变,使 GRANT SELECT语句处于另一个批处理中,那
么 GRANT SELECT就会运行失败。
CREATE SCHEMA Operations AUTHORIZATION dbo CREATE TABLE DeliveryDriver (DriverlD int IDENTITY NOT NULL ,LName varchar(75) NOT NULL ,FName varchar(75) NOT NULL)
GO
GRANT SELECT ON DeliveryDriver TO FredF
Msg 15151, Level 16, State 1, Line 1 Cannot find the object 1 DeliveryDriver', because it does not exist or you do not have permission.
GO关键字将GRANT SELECT语句放在创建架构的批处理之外,这样执行上下文就
变成执行脚本的用户上下文。作为最佳实践,应该总是指定对象的架构以避免不可预料的
结果。
CREATE SCHEMA Operations AUTHORIZATION dbo CREATE TABLE Operations.DeliveryDriver (DriverlD int IDENTITY NOT NULL ,LName varchar(75) NOT NULL ,FName varchar(75) NOT NULL) GRANT SELECT ON Operations.DeliveryDriver TO FredF
记住,架构作用域解析总是起始于用户的默汄架构,如果一个被引用的对象不是作用
域限定的,解析将返回到dbo架构。
3 .架构维护
如果试图删除一个包含对象的架构,将产生如下例所示的错误:
DROP SCHEMA Operations
Msg 3729, Level 16, State 1, Line 1 Cannot drop schema 'Operations * because it is being referenced by object *DeliveryDriver*.
如果仍然需要该架构中的对象,可以使用ALTER SCHEMA语句把它转移到另一个架
构中。
ALTER SCHEMA Production TRANSFER Operations.DeliveryDriver
这个例子把表DeliveryDriver从 Operations架构转移到Production架构中。因为这是架
构中仅剩的对象,所以现在可以删除架构。但是要注意,将一个对象从一个架构移动到另
一架构会清除在该对象上设定的任何权限。
不能从数据库中删除拥有架构的对象,这就是为什么让dbo用户拥有所有架构的原因
之一。要想改变一个架构的所有权,需要改变该架构的AUTHORIZATION属性。下面的
例子将Operations架构的所有权改授予FredF:
ALTER AUTHORIZATION ON SCHEMA::Operations TO FredF