SQL SERVER 2005中的Schema详解
以往 SQL Server 内的对象命名是“服务器.数据库.用户名.对象”,但新版的对象命名改为“服务器.数据库.Schema.对象”。这让你规划数据库对象命名时更有弹性。
架构是形成单个命名空间的数据库实体的集合。命名空间是一个集合,其中每个元素的名称都是唯一的。
虽然 SQL Server 2000 包含 CREATE SCHEMA 语句,但实际上并不会像上面所定义的那样创建架构。在 SQL Server 2000 中,数据库用户和架构是隐式连接在一起的。每个数据库用户都是与该用户同名的架构的所有者。对象的所有者在功能上与包含它的架构所有者相同。因而,SQL Server 2000 中的完全限定名称的“架构”也是数据库中的用户。因此,从 SQL Server 2000 数据库中删除用户之前,管理员需要删除该用户所拥有的所有对象或更改这些对象的所有者。以包含此对象的 SQL Server 2000 数据库为例:
accounting.ap.george.reconciliation
此对象的所有者为用户“george”。如果管理员需要删除用户“george”,则必须先删除此对象或更改此对象的所有者。在后一种情况下,可以按如下方式将其重命名:
accounting.ap.sandra.reconciliation
转让对象的所有权也会更改其完全限定名称。引用 accounting.ap.george.reconciliation 的任何代码必须经过更新以反映对名称所做的更改。
在 SQL Server 2005 中,架构独立于创建它们的数据库用户而存在。可以在不更改架构名称的情况下转让架构的所有权。并且可以在架构中创建具有用户友好名称的对象,明确指示对象的功能。例如,除了 accounting.ap.sandra.reconciliation 外,您还可以创建名为 accounting.ap.invoice.reconciliation 的架构。因为“invoice”不是用户,所以从数据库中删除用户后,无需更改此名称。这就简化了数据库管理员和开发人员的工作。
用户架构分离的好处
将架构与数据库用户分离对管理员和开发人员而言有下列好处:
多个用户可以通过角色成员身份或 Windows 组成员身份拥有一个架构。这扩展了允许角色和组拥有对象的用户熟悉的功能。
极大地简化了删除数据库用户的操作。
删除数据库用户不需要重命名该用户架构所包含的对象。因而,在删除创建架构所含对象的用户后,不再需要修改和测试显式引用这些对象的应用程序。
多个用户可以共享一个默认架构以进行统一名称解析。
开发人员通过共享默认架构可以将共享对象存储在为特定应用程序专门创建的架构中,而不是 DBO 架构中。
可以用比早期版本中的粒度更大的粒度管理架构和架构包含的对象的权限。
完全限定的对象名称现在包含四部分:server.database.schema.object。
用户与架构(schema)分开,让数据库内各对象不再绑在某个用户账号上,可以解决之前版本“用户离开公司"问题,也就是在拥有该对象的用户离开公司,或离开该职务时,不必要大费周章地更改该用户所有的对象属于新的用户所有。另外,也可让 DBA 在安装某个套装软件时,设置该套装软件所用的数据库对象都属于某个特定的架构,容易区别。也就是说,在单一数据库内,不同部门或目的的对象,可以通过架构区分不同的对象命名原则与权限。
默认架构
SQL Server 2005 还引入了“默认架构”的概念,用于解析未使用其完全限定名称引用的对象的名称。在 SQL Server 2000 中,首先检查的是调用数据库用户所拥有的架构,然后是 DBO 拥有的架构。在 SQL Server 2005 中,每个用户都有一个默认架构,用于指定服务器在解析对象的名称时将要搜索的第一个架构。可以使用 CREATE USER 和 ALTER USER 的 DEFAULT_SCHEMA 选项设置和更改默认架构。如果未定义 DEFAULT_SCHEMA,则数据库用户将把 DBO 作为其默认架构。
SQL Server 2005 Database Engine 管理着可以通过权限进行保护的实体的分层集合。这些实体称为“安全对象”。在安全对象中,最突出的是服务器和数据库,但可以在更细的级别上设置离散权限。SQL Server 通过验证主体是否已获得适当的权限来控制主体对安全对象执行的操作。
附:
图一 安全对象与架构关系
图二 数据库引擎权限层次结构之间的关系图
然后引用一个兄弟的文章具体的了解下:
SQL 学习笔记之DISTINCT和GROUP BY||CREATE SCHEMA
------------------------------------2009年3月3日6点30分28秒
-----------------------------------------------
create database StuSQL --创建数据库 ---study SQL 学习SQL笔记
on(name='StuSQL',
filename='H:\StuSQL\StuSQL.mdf',
size=10mb,
maxsize=100mb,
filegrowth=5mb)
log on(name='StuSQLLog',
filename='H:\StuSQL\StuSQL.log',
size=10mb,
maxsize=50mb,
filegrowth=5mb);
---------------------------------
use StuSQL;
------------------------------------2009年3月3日6点33分28秒
--------------------研究相关distinct group by order by和having---------------------------
-----1.0-----解决雷兄的问题---
create table image
(
id int ,
names char(10),
url char(10),
primary key(id,url)
);
insert into image
values( 1,'自拍','1.jpg');
insert into image
values( 2,'动漫','2.jpg');
insert into image
values( 3,'test','3.jpg');
insert into image
values( 4,'test','4.jpg');
insert into image
values( 5,'test','2.jpg');
insert into image
values( 2,'动漫','1.jpg');
select * from image;
select id,min(names) from image group by id;---语句1
select id,min(url) from image group by id;---语句2
/*
后记:
雷兄的问题可以描述为 :select id, 随便一个rul, from image; (id 不能重复,url随便)
额,这个数据库嘛,你跟他说随便,他听不懂,这就是与人的区别了。所以呢就得加点限制,让其不能随便
所以上面就用了个min ;同样,你用max也行,然后用group by 分组后就可以保证id不重复了。
既然如此,哪就可以用另外一种方法实现了:
select id,url
from image img1
where url=(
select min(url)--同样可以用max
from image img2
where img1.id=img2.id
); --语句3 --对应语句2
-----这样同样可以保证返回的id的唯一性,因为primary key(id,url) 同一个id它的url定不同
如果是
select id,names
from image img1
where names=(
select min(names)
from image img2
where img1.id=img2.id
); ---语句4 --对应语句1
则不行了。因为 同一个id它的names可以相同
------------------------------
最后总结:语句3用的是相关子查询 与语句2相比明显效率不如
*/
---为了好看,改写该语句1为:
select id as 名册ID,min(names) as 相册名 from image group by id;
-----------总结:
-----1.1-----having 一定要跟group by 一起用,但group by 不一定要有having
-----1.2-----group by 后面的列可以有多个 但对于要查询的列一定要都包含在聚合函数或group by 自字句中
--------举例:语句1中 要查询的列有id和names 其中id包含在 group by 字句中了,而names 包含在了聚合函数min中了 语法无误 对于语句2一样
select id,url from image group by id;---语句3 要查询的id包含在了group by 字句中了,但url不包含在....语法错误
select id from image group by id,url;---语句4 要查询的id包含在了group by 字句中 语法正确
-----1.3-----group by 执行原理之自我理解:以语句1为例:分析如下
/*首先DBMS从DB中读取一条一条记录 并按id对数据进行分组,相当与把id相同的都放在一起组成一张小表,
然后在从这张小表中去依次查询要查询的记录。理解这个了,就不难理解语句3为什么有语法错误了,因为DBMS对DB中表数据
按id进行分组后,每张小表的id都相同但对每张小表其url可能不相同,数据库怎么知道你需要得到那条记录,
它没那么智能化,数据库查询都是很严格的,除非有数据库支持不规范查询,或者向html等语言哪样,有错误也可以照样跑
其实这在数据库中是不允许的,数据查询都要求是得到准确的数据,一个查询要是返回的记录可能不同的话,这数据不都乱套了
废话少说,接着进行后面的学习。
*/
-----2.0-----关于distinct的疑惑
select distinct id,url from image; ---为什么不能消掉重复的id
--用distinct关键字只能过滤查询字段中所有记录相同的(记录集相同),而如果要指定一个字段却没有效果,
--另外distinct关键字会排序,效率很低。
--要不做个试验
insert into image
values( 1,'自拍','2.jpg');
select *from image; --发现这个试验不知该怎么做哦 关于distinct 会排序 呵呵 听说而已 怎么验证以后再研究了?????
--上面的语句相当于 把id和url两个字段看成一个整体,只有当他们两个字段完全相同才视其为重复记录。
select id,distinct url from image;----语法错误 ,distinct必须放在开头
-----3.0-----另一种方法---思路比较特别---网上看到的
/*
假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集
select identity(int,1,1) as autoID, * into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name
select * from #Tmp where autoID in(select autoID from #tmp2)
*/---关键看下里面的思维方式就可以了
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
1.鄙人对SQL的create schema一直未理解透彻:
create schema到底起何作用,有何意义,在实践中又当如何来用,用在何时,何处?
2.鄙人对SQL中的外模式、模式、内模式的理解总是感觉不是很明朗,最后总结感觉主要还是这几个名词比较抽象的缘故,简单点想也就那么回事。
create schema 模式名 authorization 用户名;
schema 就是架构的意思(课本上称之为模式) 比如我们SQL里建表后,在对象资源管理器中可以看到表前面都有个dbo.,选中表,在右边的窗口的
摘要里有描述,这个dbo指的就是架构,也就是上面所谓的模式名。
dbo 就是一个创建好的架构,也就是所有者的意思。一个数据库下面可以有多的所有者,每个所有者创建自己各自的表表名可以相同,只是前面的schema不同而已
///////////////////////////////////////////////////////
成功执行了create schema stu authorization huxb
那么 huxb 就是数据库中的一个用户
stu 就是一个架构名
创建表的时候可以
create table stu.表名(ID int)
访问的时候
select * from stu.表名
/////////////////////////////////////////////////////