3.6. Наследование
Наследование — это концепция, взятая из объектно-ориентированных баз данных. Она открывает множество интересных возможностей при проектировании баз данных.
Давайте создадим две таблицы: cities
(города) и capitals
(столицы штатов). Естественно, столицы штатов также являются городами, поэтому нам нужно явным образом добавлять их в результат, когда мы хотим просмотреть все города. Если вы проявите смекалку, вы можете предложить, например, такое решение:
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
наследует все столбцы (name
, population
и altitude
) от родительской таблицы cities
. Столбец name
имеет тип text
, собственный тип Postgres Pro для текстовых строк переменной длины. А в таблицу столиц добавлен дополнительный столбец state
, в котором будет указан штат. В Postgres Pro таблица может наследоваться от нуля или нескольких других таблиц.
Например, следующий запрос выведет названия всех городов, включая столицы, находящихся выше 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
.
Примечание
Хотя наследование часто бывает полезно, оно не интегрировано с ограничениями уникальности и внешними ключами, что ограничивает его применимость. Подробнее это описывается в Разделе 5.9.