PostgreSQL Schema管理基础

Postgresql schema是什么、为什么它们很重要以及如何使用schema(模式)使您的数据库实现更加健壮和可维护?本文将介绍 Postgresql 中schema的基础知识,并通过一些基本示例向您展示如何创建它们。未来的文章将深入探讨如何保护和使用实际应用程序schema的示例。
首先,为了消除潜在的术语混淆,让我们了解一下,在 Postgresql 世界中,“schema”一词可能不幸地被过度使用了。在关系数据库管理系统 (RDBMS) 的更广泛背景下,“schema”一词可能被理解为指数据库的整体逻辑或物理设计,即构成数据库定义的所有表、列、视图和其他对象的定义。在这种广义背景下,schema 可以通过实体关系(ER)图或用于实例化应用数据库的DDL语句脚本来表达。
“什么是命名空间?” 通常,命名空间是一种通过名称,组织和识别信息的相当灵活的方式。例如,想象两个相邻的家庭,Smith家有Alice和Bob,Jones家有Bob和Cathy(参见图1)。如果我们只使用名字,当谈论Bob时可能会弄不清楚指的是哪一个人。但通过添加姓氏Smith或Jones,我们可以唯一地确定我们指的是哪一个人

在这里插入图片描述

命名空间通常组织成嵌套的层次结构。这允许将大量信息高效地分类到非常细粒度的结构中,例如互联网域名系统。在顶层,“.com”、“.net”、“.org”、“.edu”等定义了广泛的命名空间,在这些空间内注册了特定实体的名称,例如“severalnines.com”和“postgresql.org”被唯一定义。但在每一个这些顶层域名之下,还有许多常见的子域名,例如“www”、“mail”和“ftp”等,这些子域名单独来看是重复的,但在各自的命名空间内是唯一的。
PostgreSQL 中的 schema 具有组织和识别的作用,但与前面的第二个例子不同,PostgreSQL 的 schema 不能嵌套在层次结构中。虽然一个数据库可以包含许多 schema,但它们只有一个层次结构,因此在一个数据库中,schema 名称必须是唯一的。此外,每个数据库必须至少包含一个 schema。每当新数据库被创建时,都会创建一个名为 “public” 的默认 schema。一个 schema 的内容包括所有其他数据库对象,如表、视图、存储过程、触发器等。为了形象化,请参考图2,它展示了类似俄罗斯套娃的嵌套结构,显示了 schema 在 PostgreSQL 数据库结构中的位置。
在这里插入图片描述
除了简单地将数据库对象组织成逻辑组以便更易管理之外,schemas 还具有避免名称冲突的实际用途。一种操作范式是为每个数据库用户定义一个 schema,以提供一定程度的隔离,使用户可以在各自的空间中定义自己的表和视图而不相互干扰。另一种方法是将第三方工具或数据库扩展安装在单独的 schema 中,以便将所有相关组件逻辑地集中在一起。本系列的后续文章将详细介绍一种新的稳健应用设计方法,使用 schemas 作为间接手段,限制数据库物理设计的暴露,而是呈现一个用户界面,解决合成键并促进系统需求演变中的长期维护和配置管理。
在数据库中创建schema的最简单命令是

CREATE SCHEMA hollywood;

此命令需要数据库中的create权限,新创建的 schema “hollywood” 将由调用该命令的用户拥有。更复杂的调用可能包括指定不同所有者的可选元素,甚至可以在一个命令中包含创建schema 内数据库对象的 DDL 语句!
一般格式是:

CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]

“username” 是 schema 的所有者,“schema_element” 可以是某些 DDL 命令之一(具体参考 PostgreSQL 文档)。使用 AUTHORIZATION 选项需要超级用户权限。
例如,要在一个命令中创建一个名为 “hollywood” 的 schema,并在其中包含一个名为 “films” 的表和一个名为 “winners” 的视图,可以这样做:

CREATE SCHEMA hollywood
    CREATE TABLE films (title text, release date, awards text[])
    CREATE VIEW winners AS
        SELECT title, release FROM films WHERE awards IS NOT NULL;

随后可以直接创建额外的数据库对象,例如,将使用以下命令将附加表添加到schema中:

CREATE TABLE hollywood.actors (name text, dob date, gender text);

请注意,在上面的例子中,表名以 schema 名称作为前缀。这是必需的,因为默认情况下,如果没有明确指定 schema,新创建的数据库对象会位于当前的 schema 中,我们将在接下来讨论这个问题。

回想一下上面第一个命名空间例子,我们有两个名叫 Bob 的人,我们通过加入姓氏来区分他们。但是在 Smith 和 Jones 各自的家庭中,每个家庭成员都知道 “Bob” 指的是他们家庭中的那位。所以在各自的家庭背景下,Alice 不需要称呼她的丈夫为 Bob Jones,而 Cathy 也不需要称呼她的丈夫为 Bob Smith:她们都可以直接称呼为 “Bob”。
PostgreSQL 的当前 schema 就像上面的家庭。在当前 schema 中的对象可以不加限定地引用,但引用其他 schema 中的同名对象时需要在名称前加上 schema 名称作为前缀。
当前的 schema 是由 search_path 配置参数决定的。这个参数存储了以逗号分隔的 schema 名称列表,可以使用以下命令查看:

SHOW search_path;

或设置新的值

SET search_path TO schema [, schema, ...];

列表中的第一个 schema 名称是“当前 schema”,如果没有指定 schema 名称,新对象会在该 schema 中创建。
这个以逗号分隔的 schema 名称列表还用于确定系统定位现有未限定名称对象的搜索顺序。例如,回到 Smith 和 Jones 的社区,如果一个包裹的收件人只写着“Bob”,那么送货员需要逐个拜访每家,直到找到第一个名为 “Bob” 的居民。注意,这可能不是预期的收件人。同样的逻辑适用于 PostgreSQL。系统按照 search_path 的顺序在 schema 中搜索表、视图和其他对象,然后使用第一个找到的名称匹配对象。具有 schema 限定名称的对象直接使用,而不参考 search_path。
在默认配置中,查询 search_path 配置变量会显示以下值:

SHOW search_path;
 Search_path
--------------
 "$user", public

系统将上述显示的第一个值解释为当前登录用户名,并适应之前提到的一种使用情况,即为每个用户分配一个以其用户名命名的schema,用于与其他用户分开的工作空间。如果没有创建这样的以用户命名的schema,则忽略该条目,并且“public” schema将成为创建新对象时的当前schema。

因此,回到我们之前创建“hollywood.actors”表的例子,如果我们没有使用schema名称限定表名,那么该表将在public schema中创建。如果我们预期在特定schema中创建所有对象,那么设置search_path变量可能会很方便,例如:

SET search_path TO hollywood,public;

还有一个系统信息功能,可以通过查询返回当前的schema。

select current_schema();

在拼写错误的情况下,schema的所有者可以更改名称,前提是用户也具有数据库的创建权限,并且.

ALTER SCHEMA old_name RENAME TO new_name;

最后,要从数据库中删除架构,可以使用 drop 命令

DROP SCHEMA schema_name;

如果架构包含任何对象,则 DROP 命令将失败,因此必须先删除它们,或者您可以选择使用 CASCADE 选项递归删除架构的所有内容

DROP SCHEMA schema_name CASCADE;

相关推荐

  1. KVM基础管理命令

    2024-06-12 10:10:02       13 阅读
  2. Android基础-Log管理

    2024-06-12 10:10:02       7 阅读
  3. 镜像管理基础命令

    2024-06-12 10:10:02       27 阅读
  4. Docker 基本管理

    2024-06-12 10:10:02       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-12 10:10:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-12 10:10:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-12 10:10:02       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-12 10:10:02       20 阅读

热门阅读

  1. Ubuntu 22, CURL 分块上传文件C++代码实现

    2024-06-12 10:10:02       10 阅读
  2. 利用Axios封装及泛型实现定制化HTTP请求处理

    2024-06-12 10:10:02       9 阅读
  3. idea快捷键

    2024-06-12 10:10:02       10 阅读
  4. 在CentOS上安装MySQL 5.7的详细教程

    2024-06-12 10:10:02       9 阅读
  5. 实现抖音视频滑动功能vue3+swiper

    2024-06-12 10:10:02       11 阅读
  6. Milvus 三

    2024-06-12 10:10:02       8 阅读
  7. C# —— 类型转换

    2024-06-12 10:10:02       10 阅读