3.5. Наследование

Наследование - это концепт из объектно-ориентированных СУБД. Оно открывает новые интересные возможности разработки баз данных.

Создайте две таблицы: Таблицу cities (города) и таблицу capitals (столицы). Фактически, столицы - это тоже города, так что вы можете захотеть получить какой-либо способ просматривать неявно и столицы, когда вы смотрите список всех городов. Если вы действительно сообразительны вы можете реализовать например такую схему:

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

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

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

Это хорошо работает, когда вы создаете запросы для просмотра, но это безобразно, когда вам нужно обновить в нескольких записях, например, поле name.

Лучшим решением является:

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

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

В данном случае, строки в таблице capitals наследуют все колонки (name, population и altitude) от родительской таблицы cities. Тип колонки name это text - один из родных типов PostgreSQL для символьных строк переменной длины. Столицы штатов имеют дополнительную колонку state, которая показывает штат. В 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)

Здесь ONLY перед cities означает, что запрос должен быть запущен только для таблицы cities, а не для таблиц ниже cities в иерархии наследования. Многие из тех команд, которые мы рассмотрели -- SELECT, UPDATE и DELETE -- поддерживают нотацию ONLY.