Нетривиальное использование таблиц
Наследование
В PostgreSQL поддерживается механизм создания объектно-реляционных связей, называемый наследованием. Таблица может наследовать некоторые атрибуты своих полей от одной или нескольких других таблиц, что приводит к созданию отношений типа "предок-потомок". В результате производные таблицы ("потомки") обладают теми же полями и ограничениями, что и их базовые таблицы ("предки"), а также дополняются собственными полями.
При составлении запроса к базовой таблице можно потребовать, чтобы запрос произвел выборку только из самой таблицы или же просмотрел как таблицу, так и ее производные таблицы. С другой стороны, в результаты запроса к производной таблице никогда не включаются записи из базовой таблицы.
Создание производной таблицы
Производная таблица создается командой SQL CREATE TABLE, в которую включается секция INHERITS. Секция состоит из ключевого слова INHERITS и имени базовой таблицы (или нескольких таблиц).
Часть команды CREATE TABLE, относящаяся к наследованию, выглядит так:
CREATE TABLE производная_таблица определение INHERITS (базовая_таблица [….])
В этом определении производная таблица – имя создаваемой таблицы, определение – полное определение таблицы со всеми стандартными секциями команды CREATE TABLE, а базовая _таблица – таблица, структура которой наследуется новой таблицей. Дополнительные имена базовых таблиц перечисляются через запятую.
В листинге 7.11 создается таблица distinguished_authors, определение которой состоит из единственного текстового поля award. Поскольку в команде создания таблицы указано ключевое слово INHERITS, таблица содержит четыре поля – одно собственное и три унаследованных.
Листинг 7.11. Создание производной таблицы.
booktown=# CREATE TABLE distinguished_authors (award text) booktown-# INHERITS (authors): CREATE booktown=# \d distinguished_authors Table "distinguished_authors" Attribute | Type Modifier id | integer | not null lastjiame text | firstjiame | text award text
Как видите, несмотря на то что в листинге 7.11 определено всего одно поле, таблица distinguished_authors унаследовала все поля исходной таблицы authors.
Использование производных таблиц
Связь общих полей базовой и производной таблиц не ограничивается чисто косметическими удобствами. Данные, занесенные в таблицу distinguished_authors, присутствуют и в родительской таблице authors. Впрочем, в таблице authors видны только три унаследованных поля. В запрос к базовой таблице можно включить ключевое слово ONLY, которое указывает, что данные производных таблиц исключаются из результатов запроса.
Примечание
Данные базовых таблиц никогда не включаются в результаты запросов к производным таблицам. Таким образом, ключевое слово ONLY в запросе к производной таблице действует лишь в том случае, если у производной таблицы есть собственный потомок, из-за чего она одновременно является и производной, и базовой.
В листинге 7.12 в таблицу di sti ngui shed_authors заносятся данные о новом авторе Nei I Simon с текстом Pul itzer Prize в поле award. Обратите внимание: что первые три переданных значения являются общими для обеих таблиц, базовой и производной.
Листинг 7.12. Вставка данных в производную таблицу.
booktown=# INSERT INTO distinguished_authors booktown-# VALUES (nextvaK 'authorjds'), booktown(# 'Simon'. 'Neil', 'Pulitzer Prize'); INSERT 3629421 1
Поскольку первые три поля таблицы distinguished_authors были унаследованы от таблицы authors, данные этой записи косвенно включаются в таблицу authors (хотя непосредственная вставка в таблицу authors не выполнялась). Тем не менее поле award будет присутствовать только в таблице di sti ngui shed_authors, поскольку наследование действует только в одну сторону (от родителя к потомку).