模式
一个postgresql数据库集群包含一个或多个已命名数据库。用户和用户组在整个集群返回内是共享的,但是其它数据库并不共享。任何与服务器连接的客户都只能访问那个在连接请求里声明的数据库。
注意:在集群中的用户并不一定要有访问集群内所有数据库的权限。共享用户名的意思是不能有重名用户。假定同一个集群里有两个数据库和一个stt用户,系统可以配置成只允许stt 访问其中的一个数据库。
一个数据库包含一个或多个已命名的模式,模式又包含表。模式还可以包含其他对象,包含数据类型,函数,操作符等。
同一个对象名可以在不同的模式里使用而不会导致冲突;
比如,在schema_first和schema_second两个模式中都可以包含一个表名为mytable的表。
和数据库不同,模式不是严格分离的:只要有权限,一个用户可以访问它所连接的数据库中的任意模式中的对象。
模式又很多优点值得我们使用:
1.允许多个用户使用一个数据库,而不会干扰其他用户。
2.把数据库对象组织成逻辑组,让他们更加便于管理。
3.第三方的应用可以放在不同的模式中,这样他们就不会和其他对象的名字冲突。
模式类似于操作系统层次的目录,只不过模式不能嵌套。
创建模式
要创建一个模式,使用create schema命令。给出你选择的模式名称。
案例:
create schema myschema;
当要访问模式整的对象时,写出一个受修饰的名字,这个名字包含模式名以及表名,他们之间用一个句子分开:
schema_name.table
在这里我们只讨论表。
注意:模式名适用于所有已命名对象类型,比如数据类型和函数。
更一般的语法:
database.schema.table
如果我们写了一个数据库名,那么必须和我们当前连接的数据库同名。
在模式中创建一个表,用
create table myschema.mytable(
...
);
删除一个模式
如果一个模式是空的(它里面的所有对象都已经删除),那么删除一个模式的命令如下:
drop schema myschema;
要删除一个模式以及其包含的所有对象,可以使用:
drop schema myschema cascade;
通常我们需要创建一个他人拥有的模式(因为这是一种限制用户在定义良好的模式中的活动的方法)。
案例:
create schema schemaname authorization username;
你甚至可以省略模式名字,这时模式名将和用户名同名。
以 pg_ 开头的模式名是保留给系统使用的,用户不能创建这样的名字
public模式
当我们在创建表时没有加具体的模式名称,进行省缺是,这样的表(以及其他对象)都会自动的放到一个叫做public的模式中去。
每个新创建的数据库都包含一个这样的模式。
案例:
下面两个sql是等效的。
create table products(...);
等效于下面的sql
create table public.products(...);
模式搜索路径
在搜索路径中的第一个模式叫做当前模式。除了是搜索的第一个模式外,它还是爱create table 没有声明模式名的时候,新建表的默认地址。
要显示当前的搜索路径,使用下面的命令:
show search_path;
这里第一个元素声明搜索和当前用户同名的模式。显示的是当前使用的模式test。
第二个元素指向我们已经看过的公共模式。
在省缺的配置里,任何没有修饰的访问只能引用public模式。
要设置模式的搜索路径,可以用
set search_path to myschema,public;
这样设置之后,我们就可以不使用模式修饰来访问表了;
如:
drop table mytable;
可以省掉模式名;
因为myschema是路径中的第一个元素,新对象省缺时将创建在这里。
我们也可以写成:
set search_path to myschema;
搜索路径对于数据类型名、函数名、操作符名的运作方式和表名完全相同。 数据类型和函数
名可以像表名一样加以修饰。如果需要在表达式里写一个有模式修饰的操作符,我们可以这
么写:
operator(schema.operator)
案例:
select 3 operator(pg_catalog.+) 4;
上面操作是为了避免语法歧义。
在项目实践中我们通常依赖搜索路径寻找操作符,这样就不必写这么长又复杂的语句了。
模式和权限
缺省时,用户无法访问模式中不属于他们所有的对象。为了让他们能够访问, 模式的所有者需要在模式上赋予他们 USAGE 权限。
为了让用户使用模式中的对象,我们可能需要赋予适合该对象的额外权限。
用户也可以在别人的模式里创建对象。要允许这么做,需要被赋予在该模式上的 CREATE 权限。
请注意,缺省时每个人都在 public 模式上有 CREATE 和 USAGE 权限。
这样就允许所有可以连接到指定数据库上的用户在这里创建对象。
如果你不打算这么做,可以撤销这个权限:
revoke create on schema public from PUBLIC;
其中第一个public是模式,第二个public是所有用户。
第一句里它是标识符,第二句中是个关键字,所以有不同的大小写。
系统表模式
除了 public 和用户创建的模式之外,每个数据库都包含一个 pg_catalog 模式, 它包含系统表和所有内置数据类型、函数、操作符。
pg_catalog 总是搜索路径中的一部分。如果他没有明确出现在路径中,那么它隐含地在所有路径之前搜索。这样就保证了内置名字总是可以被搜索。不过你可以明确地把pg_catlog放在搜索路径之后,如果你想使用用户自定义的名字覆盖内置的名字的话。
很多系统表名是以pg_ 开始,在命名的时候,最好避免使用pg_开头的名字来命名,防止在以后的新版本中发生冲突。
系统表将继续遵循以 pg_ 开头的传统,因此,只要你的表不是以 pg_ 开头, 就不会和无修饰的用户表名字冲突。
模式使用方法
如果没有创建任何模式,那么所有用户隐含都访问 public 模式 。这种设置建议主要用在只有一个用户或者数据库里只有几个可信用户的情形。
你可以为每个用户创建一个模式,名字和用户相同。要记得缺省的搜索路径从 $user 开始, 它会解析为用户名。因此, 如果每个用户都有一个独立的模式,那么他们缺省时访问他们自己的模式 。
要安装共享的应用(被所有人使用的表、第三方提供的额外函数等等), 我们可以把它们放到独立的模式中。只要记得给需要访问它们的用户赋予合适的权限就可以了。 然后用户就可以通过用一个模式名修饰来使用这些额外的对象,或者他们可以把额外的模式放到他们的搜索路径中。