3.5. 继承

继承是面向对象的数据库的概念.它开启了数据库设计新的可能性大门.

让我们创建两个表∶一个表 cities 和一个表 capitals.自然,首府(capital)也可以是 城市(cities),因此在列出所有城市时你想要某种方法隐含地显示首府. 如果你已经很高明了,那么你可能会创造类似下面这样的大纲∶

CREATE TABLE capitals (
    name            text,
    population      real,
    altitude        int,    -- (单位是英尺)
    state           char(2)
);

CREATE TABLE non_capitals (
    name            text,
    population      real,
    altitude        int     -- (单位是英尺)
);

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

如果只是查询,那么这个方法运转得很好,但是如果你需要更新某几行, 那这个方法就很难看了.

一种更好的方法是∶

CREATE TABLE cities (
    name            text,
    population      real,
    altitude        int     -- (单位是英尺)
);

CREATE TABLE capitals (
    state           char(2)
) INHERITS (cities);

在这个例子里,capitals 的一行 继承所有来自它的父表cities的所有字段(namepopulation,和altitude). 字段 name 的类型是 text, 是 PostgreSQL 用于变长字符串的固有类型. 州首府有一个额外的字段,州,显示所处的州.在 PostgreSQL 里,一个表可以从零个或者更多其它 表中继承过来.

比如,下面的查询找出所有海拔超过 500 英尺的城市的名字, 包括州首府∶

SELECT name, altitude
    FROM cities
    WHERE altitude > 500;

它返回:

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

另外一方面,下面的查询找出所有不是州首府并且位于 海拔大于或等于 500 英尺的城市∶

SELECT name, altitude
    FROM ONLY cities
    WHERE altitude > 500;

   name    | altitude
-----------+----------
 Las Vegas |     2174
 Mariposa  |     1953
(2 rows)

这里的 cities 前面的 ONLY 指示系统只对 cities 表运行查询,而不包括 继承级别中低于 cities 的表.许多我们已经 讨论过的命令 -- SELECT, UPDATEDELETE -- 支持这个 ONLY 表示法.