数据库中User和Schema的关系

假如咱们想了解数据库中的User和Schema到底是什么关系,首先必须了解一下数据库中User和Schema究竟是什么概念。 数据库

  在SQL Server2000中,因为架构的缘由,User和Schema总有一层隐含的关系,让咱们不多意识到其实User和Schema是两种彻底不一样的概念,不过在SQL Server2005中这种架构被打破了,User和Schema也被分开了。 架构

  首先我来作一个比喻,什么是Database,什么是Schema,什么是Table,什么是列,什么是行,什么是User?咱们能够能够把Database看做是一个大仓库,仓库分了不少不少的房间,Schema就是其中的房间,一个Schema表明一个房间,Table能够看做是每一个Schema中的床,Table(床)就被放入每一个房间中,不能放置在房间以外,那岂不是晚上睡觉无家可归了J。,而后床上能够放置不少物品,就比如Table上能够放置不少列和行同样,数据库中存储数据的基本单元是Table,现实中每一个仓库放置物品的基本单位就是床, User就是每一个Schema的主人,(因此Schema包含的是Object,而不是User),其实User是对应与数据库的(即User是每一个对应数据库的主人),既然有操做数据库(仓库)的权利,就确定有操做数据库中每一个Schema(房间)的权利,就是说每一个数据库映射的User有每一个Schema(房间)的钥匙,换句话说,若是他是某个仓库的主人,那么这个仓库的使用权和仓库中的全部东西都是他的(包括房间),他有彻底的操做权,能够扔掉不用的东西从每一个房间,也能够放置一些有用的东西到某一个房间,呵呵,和现实也太类似了吧。我还能够给User分配具体的权限,也就是他到某一个房间能作些什么,是只能看(Read-Only),仍是能够像主人同样有全部的控制权(R/W),这个就要看这个User所对应的角色Role了,至于分配权限的问题,我留在之后单独的blog中详述。比喻到这里,相信你们都清楚了吧。 对象

  在SQL Server2000中,假如咱们在某一个数据库中建立了用户Bosco,按么此时后台也为咱们默认地建立了默认Schema 【Bosco】。Schema的名字和User的名字相同,这也是咱们分不清楚用户和Schema的缘由。 blog

  在SQL Server2005中,为了向后兼容,当你用sp_adduser 存储过程建立一个用户的时候,SQL Server2005同时也建立了一个和用户名相同的Schema,然而这个存储过程是为了向后兼容才保留的,咱们应该逐渐熟悉用新的DDL语言Create User和Create Schema来操做数据库。在SQL Server2005中,当咱们用Create User建立数据库用户时,咱们能够为该用户指定一个已经存在的Schema做为默认Schema,若是咱们不指定,则该用户所默认的Schema即为dbo Schema,dbo 房间(Schema)比如一个大的公共房间,在当前登陆用户没有默认Schema的前提下,若是你在大仓库中进行一些操做,好比Create Tabe,若是没有指定特定的房间(Schema),那么你的物品就只好放进公共的dbo房间(Schema)了。可是若是当前登陆用户有默认的Schema,那么所作的一切操做都是在默认Schema上进行(好比当前登陆用户为login1,该用户的默认Schema为login1,那么所作的全部操做都是在这个login1默认Schema上进行的。实验已经证实的确如此)。估计此时你会有一点晕,为何呢?我刚才说dbo是一个Schema,可是你能够在数据库中查看到,dbo同时也是一个user,晕了吧,呵呵。 table

  在SQL Server2005中建立一个数据库的时候,会有一些Schema包括进去,被包括进去的Schema有:dbo,INFORMATION_SCHEMA, guest,sys等等(还有一些角色Schema,不提了,有晕了)。 登录

  我在上文中已经提到了,在SQL Server2005中当用存储过程sp_adduser建立一个user时,同时SQL Server2005也为咱们建立了一个默认的和用户名相同的Schema,这个时候问题出来了,当咱们create table A时,若是没有特定的Schema作前缀,这个A表建立在了哪一个Schema上,即进入了哪一个房间?答案是: 后台

  1.若是当前操做数据库的用户(能够用Select current_user查出来)有默认的Schema(在建立用户的时候指定了),那么表A被建立在了默认的Schema上。 select

  2.若是当前操做数据库的用户没有默认的Schema(即在建立User的时候默认为空),可是有一个和用户名同名的Schema,那么表A照样被建立在了dbo Schema上,即便有一个和用户名同名的Schema存在,因为它不是该用户默认的Schema,因此建立表的时候是不会考虑的,看成通常的Schema来处理,别看名字相同,但是没有任何关系哦。 权限

  3.若是在建立表A的时候指定了特定的Schema作前缀,则表A被建立在了指定的 Schema上(有权限吗?) 数据

  如今问题又出来了,在当前操做数据库的用户(用select current_user能够查看到,再次强调)没有默认Schema的前提下,当咱们用Create table A语句时,A表会去寻找dbo Schema,并试图建立在dbo Schema上,可是若是建立A表的用户只有对dbo Schema的只读权限,而没有写的权限呢?这个时候A表既不是创建不成功,这个就是我之后会说起到的Login,User, Role和Schema四者之间的关系。在这里,为了不混淆和提升操做数据库的速度(在少许数据范围内,对咱们肉眼来讲几乎看不到差别),咱们最好每次在操做数据库对象的时候都显式地指定特定的Schema最为前缀。

  如今若是登陆的用户为Sue,该用户有一个默认Schema也为Sue,那么若是如今有一条查询语句为Select * from mytable, 那么搜寻每一个房间(Schema)的顺序是怎样的呢?顺序以下:

  1. 首先搜寻sys.mytable (Sys Schema)

  2. 而后搜寻Sue.mytable (Default Schema)

  3. 最后搜寻 dbo.mytable (Dbo Schema)

  执行的顺序你们既然清楚了,那么之后在查询数据库表中的数据时,最好指定特定的Schema前缀,这样子,数据库就不用去扫描Sys Schema了,固然能够提升查询的速度了。

  另外须要提示一下的是,每一个数据库在建立后,有4个Schema是必须的(删都删不掉),这4个Schema为:dbo,guest,sys和INFORMATION_SCHEMA,其他的Schema均可以删除。