关系数据库中目录和模式有什么区别?

133

我曾经认为模式是数据库本身之前的“上层包装器”对象。 我的意思是DB.schema.<在模式下任何对象名称>

现在,目录“包装器”变得相当混乱。我们为什么需要一个目录?目录应该用于什么目的?

2个回答

257

迈克·谢里尔(Mike Sherrill 'Cat Recall')给出了一个出色的答案。我只想再举一个例子:Postgres

集群=Postgres安装

当您在计算机上安装Postgres时,该安装被称为集群。这里的“集群”并不是指多台计算机协同工作的硬件意义。在Postgres中,“集群”指的是您可以使用相同的Postgres服务器引擎运行多个不相关的数据库。

集群一词也在SQL标准中以与Postgres相同的方式定义。紧密遵循SQL标准是Postgres项目的主要目标。

SQL-92 规范说明:

一个群集是一个实现定义的目录集合。

恰好有一个群集与 SQL 会话关联。

这是一种含糊的方式来表达群集是一个数据库服务器(每个目录是一个数据库)。

群集 > 目录 > 模式 > 表 > 列 & 行

所以在 Postgres 和 SQL 标准中,我们有这个包含层次结构:

  • 一台计算机可能只有一个集群,也可能有多个。
  • 数据库服务器是一个集群
  • 一个集群拥有目录。(目录=数据库)
  • 目录有模式。(模式=表的命名空间和安全边界)
  • 模式有
  • 表有
  • 行有,由定义。
    这些值是您的应用程序和用户关心的业务数据,例如人名、发票到期日、产品价格、游戏玩家的高分。列定义了值的数据类型(文本、日期、数字等)。

Diagram showing nesting boxes representing how connecting on a port gets you to cluster (a database server) which contains one or more Catalogs (a database) each of which contains one or more Schemas (a namespace) each of which contains tables each of which has rows.

多个集群

这张图表代表了一个单独的集群。在Postgres中,您可以在一台主机计算机(或虚拟操作系统)上拥有多个集群。多个集群通常用于测试和部署新版本的Postgres(例如:9.0, 9.1, 9.2, 9.3, 9.4, 9.5)。

如果您有多个集群,请想象上面的图表被复制。

不同的端口号允许多个集群并存并同时运行。每个集群将被分配一个自己的端口号。通常的默认端口号是5432,但可以由您自己设置。每个集群都在其分配的端口上侦听传入的数据库连接。
示例场景:
例如,一家公司可能有两个不同的软件开发团队。一个团队编写用于管理仓库的软件,而另一个团队则构建用于管理销售和营销的软件。每个开发团队都有自己的数据库,毫不知情地相互独立。
但IT运营团队决定在单个计算机框(Linux、Mac或其他)上运行这两个数据库。因此,在该框上安装了Postgres。所以只有一个数据库服务器(数据库集群)。在该集群中,他们创建了两个目录,一个目录为每个开发团队命名:一个名为'warehouse',一个名为'sales'。
每个开发团队都使用许多不同目的和访问角色的表。因此,每个开发团队将它们的表组织成模式。巧合的是,两个开发团队都会跟踪会计数据,因此每个团队都有一个名为“accounting”的模式。使用相同的模式名称并不是问题,因为每个namespace都有自己的目录,所以不会发生冲突。
此外,每个团队最终都会创建一个用于会计目的的表,名为“ledger”。同样,没有命名冲突。
您可以将此示例视为层次结构...
  • 计算机(硬件盒子或虚拟化服务器)
    • Postgres 9.2 集群(安装)
      • warehouse 目录(数据库)
        • inventory 模式
          • […一些表]
        • accounting 模式
          • ledger
          • […一些其他表]
      • sales 目录(数据库)
        • selling 模式
          • […一些表]
        • accounting 模式(与上述模式巧合同名)
          • ledger 表(与上述表巧合同名)
          • […一些其他表]
    • Postgres 9.3 集群
      • […其他模式和表]

每个开发团队的软件都要连接到集群。在这样做时,他们必须指定哪个目录(数据库)是他们的。Postgres要求您连接到一个目录,但您不限于该目录。初始目录仅是默认值,在SQL语句省略目录名称时使用。

因此,如果开发团队需要访问其他团队的表,则可以这样做,如果数据库管理员已经给予他们权限。访问是通过明确命名模式进行的:目录.架构.表。因此,如果'仓库'团队需要查看其他团队的('销售'团队)分类账,则他们使用sales.accounting.ledger编写SQL语句。要访问自己的分类账,他们只需编写accounting.ledger。如果他们在同一段源代码中访问两个分类账,他们可以选择包括自己的(可选)目录名称,例如warehouse.accounting.ledgersales.accounting.ledger,以避免混淆。


顺便提一下...
你可能会听到“模式”这个词被用在更一般的意义上,意思是特定数据库表结构的整个设计。相比之下,在SQL标准中,这个词具体指的是Cluster > Catalog > Schema > Table层次结构中的特定层。
Postgres在各种地方都使用了“数据库”和“目录”这两个词,比如CREATE DATABASE命令。
并非所有的数据库系统都提供这种完整的Cluster > Catalog > Schema > Table层次结构。有些只有一个目录(数据库)。有些没有模式,只有一组表。Postgres是一个非常强大的产品。

17
为什么在pgAdmin(PostgreSQL UI)中,“Catalog”和“Schema”节点是同级节点,而不是“Schema”节点作为“Catalog”的子节点? - Nate Anderson
9
“Schema”节点是你自己的,但“Catalogs”节点不是。 “Catalogs”节点恰好有两个条目:(1) PostgreSQL (pg_catalog),系统目录,几十个存储元数据定义的“pg_”表,例如pg_indexpg_triggerpg_constraint。(2) ANSI (information_schema),由SQL标准定义为information_schema,同一系统目录的只读视图。 在pgAdmin中,“Catalogs”节点的更好名称可能是“System”或“System Tables”。 - Basil Bourque
1
并非所有的数据库系统都提供完整的聚集 > 目录 > 模式 > 表层次结构。我想知道MySQL和SQL Server是什么样子的?谢谢。 - Tim
1
@Tim 一个架构(schema)只是一个命名空间,用于将表组分离,就像文件夹在文件系统中组织文件一样(除了没有嵌套的模式)。 表将您应用程序的数据存储为按行的属性/列。 - Basil Bourque
@mFeinstein 请查看此答案的第一条评论。PgAdmin在其用户界面中使用了奇怪的术语选择。 - Basil Bourque
显示剩余6条评论

92

从关系型的角度看:

目录是保存所有各种模式(外部、概念性、内部)以及相应的映射(外部/概念性、概念性/内部)的地方,除此之外,还有其他信息。

换句话说,目录包含了有关系统自身感兴趣的各种对象的详细信息(有时称为描述符信息元数据)。

例如,优化器使用目录信息来帮助它决定如何实现用户请求,其中包括有关索引和其他物理存储结构的目录信息,以及许多其他信息。同样,安全子系统使用目录信息来授予或拒绝首次提出这样的请求的用户和安全约束的目录信息。

《数据库系统简介》(第7版),C.J. Date,第69-70页。


从SQL标准的角度看:

在SQL环境中,目录是命名为模式集合的一个组成部分。一个SQL环境包含零个或多个目录。目录包含一个或多个模式,但始终包含一个名为 INFORMATION_SCHEMA 的模式,该模式包含信息模式的视图和域。

数据库语言SQL,(DIS 9075的拟议修改文本),第45页。


从SQL的角度来看:

目录通常与数据库同义。在大多数SQL数据库管理系统中,如果您查询信息模式视图,您会发现“table_catalog”列中的值映射到数据库的名称。

如果您发现您的平台使用目录的含义比这三个定义更广泛,它可能指的是比数据库更广泛的东西——数据库集群、服务器或服务器集群。但我有点怀疑,因为您可以在平台的文档中轻松地找到这些信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接