2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

3.6. 继承 #

继承是面向对象数据库中的一个概念。它为数据库设计开辟了有趣的新的可能性。

让我们创建两个表: cities 表和 capitals 表。自然,首都是城市,所以当您列出所有城市时,您希望有一种方法可以隐式地显示首府。如果您足够聪明,也许可以想出这样的方案:

CREATE TABLE capitals (
  name       text,
  population real,
  elevation  int,    -- (in ft)
  state      char(2)
);

CREATE TABLE non_capitals (
  name       text,
  population real,
  elevation  int     -- (in ft)
);

CREATE VIEW cities AS
  SELECT name, population, elevation FROM capitals
    UNION
  SELECT name, population, elevation FROM non_capitals;

就查询而言,这工作得还可以,但当您需要更新多行时,它会变得很糟糕,仅举一例。

一个更好的解决方案是这样的:

CREATE TABLE cities (
  name       text,
  population real,
  elevation  int     -- (in ft)
);

CREATE TABLE capitals (
  state      char(2) UNIQUE NOT NULL
) INHERITS (cities);

在这种情况下,capitals 表中的一行会从其 父表 cities 继承所有列(namepopulationelevation)。name 列的类型是 text,这是 PostgreSQL 原生的可变长度字符串类型。capitals 表有一个额外的列 state,用于显示其州缩写。在 PostgreSQL 中,一个表可以继承自零个或多个其他表。

例如,以下查询找到所有海拔超过 500 英尺的城市(包括州首府)的名称:

SELECT name, elevation
  FROM cities
  WHERE elevation > 500;

结果返回:

   name    | elevation
-----------+-----------
 Las Vegas |      2174
 Mariposa  |      1953
 Madison   |       845
(3 rows)

另一方面,以下查询找到所有不是州首府且海拔超过 500 英尺的城市:

SELECT name, elevation
    FROM ONLY cities
    WHERE elevation > 500;
   name    | elevation
-----------+-----------
 Las Vegas |      2174
 Mariposa  |      1953
(2 rows)

这里的 ONLY 放在 cities 前面,表示查询应该只针对 cities 表运行,而不是 cities 在继承层次结构中的子表。我们已经讨论过的许多命令(如 SELECTUPDATEDELETE)都支持这种 ONLY 表示法。

注意

尽管继承非常有用,但它尚未与唯一约束或外键集成,这限制了它的实用性。有关更多详细信息,请参阅 第 5.11 节

提交更正

如果您在文档中发现任何不正确、与您在使用特定功能时的经验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。