3.6. Наследование #
Наследование — это концепция, взятая из объектно-ориентированных баз данных. Она открывает множество интересных возможностей при проектировании баз данных.
Давайте создадим две таблицы: cities
(города) и capitals
(столицы штатов). Естественно, столицы штатов также являются городами, поэтому нам нужно явным образом добавлять их в результат, когда мы хотим просмотреть все города. Если вы проявите смекалку, вы можете предложить, например, такое решение:
CREATE TABLE capitals ( name text, population real, elevation int, -- (высота в футах) state char(2) ); CREATE TABLE non_capitals ( name text, population real, elevation int -- (высота в футах) ); 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 -- (высота в футах) ); CREATE TABLE capitals ( state char(2) UNIQUE NOT NULL ) INHERITS (cities);
В данном случае строка таблицы capitals
наследует все столбцы (name
, population
и elevation
) от родительской таблицы cities
. Столбец 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
. Многие операторы, которые мы уже обсудили — SELECT
, UPDATE
и DELETE
— поддерживают указание ONLY
.
Примечание
Хотя наследование часто бывает полезно, оно не интегрировано с ограничениями уникальности и внешними ключами, что ограничивает его применимость. Подробнее это описывается в Разделе 5.10.