Skip to content

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)

这里,ONLYcities之前表示查询应该只在cities表上运行,而不是在继承层次结构中cities下面的表上运行。我们已经讨论过的许多命令——SELECTUPDATEDELETE——支持此ONLY表示法。

注意

虽然继承通常很有用,但它尚未与唯一约束或外键集成,这限制了它的实用性。有关更多详细信息,请参见第 5.10 节