Наследование таблиц в PostgreSQL

Если у вас стоит задача создать таблицу на основе другой таблицы, так, чтобы она включала в себя все столбцы родительской, то делается это при помощи наследования.
Допустим, у нас есть таблица insects и мы хотим сделать таблицу bees на ее основе.

CREATE TABLE insects (
id serial
name text,
size float
);

CREATE TABLE bees (
can_collect_honey smallint
) INHERITS (insects);

В этом случае столбцы name и size будут присутствовать и в bees. Кроме того, в bees будет присутствовать дополнительный столбец can_collect_honey.
Если мы сделаем Insert в одну из этих таблиц, то добавляемая строка появится только в той таблицу, в которую мы ее добавляем.
Если сделать Select из таблицы Insects, то в выборку попадут удовлетворяющие критериям записи из ОБОИХ таблиц.
Если мы хотим выбирать из строк только родительской таблицы, нужно использовать ключевое слово ONLY:

SELECT *
FROM ONLY insects

Любые связки с другими таблицами (Reference), первичные ключи (Primary Key), ограничения на уникальность (Unique) и другие ограничения (Constraints), существующие для родительской таблицы, не наследуются потомком. Для него нужно создавать свои ключи и ограничения. Отсюда следует, что, например, если мы хотим видеть поле id уникальным, то оно будет таковым только в пределах родительской таблицы.

Если мы хотим, чтобы при добавлении в родительскую таблицу при определенных критериях данные попадали вместо этого в дочернюю таблицу, то это можно сделать либо с помощью триггеров (Trigger), либо с помощью правил (Rule).

Одна таблица может наследовать сразу нескольким, также и у одного родителя может быть много потомков (с помощью пустой родительской таблицы и потомков можно создавать т.н. партиции (Partition), например, чтобы разнести большие массивы данных по какому-то параметру по разным таблицам для более быстрого доступа и т.п. — в этом случае в каждой партиционной таблицу надо поставить проверку (Check) на те данные, которые туда пишутся).

Если внешняя таблица ссылается (Reference) на родительскую таблицу, то строки, входящие в дочерние таблицы, игнорируются.

Особое внимание надо уделить также полям типа Serial и последовательностям (Sequence) для них. Если, как в нашем примере, дочерняя таблица просто наследует Serial поле родительской (id в нашем случае), то они делят последовательность. И, скажем, добавив строку в родительскую таблицу, а потом в дочернюю, и снова в родительскую, имеем три записи, две из которых — с id= 1 и 3 — относятся к родительской, а с id=2 — к дочерней. Если мы просто определим поле id в дочерней таблицу тоже, то для нее автоматически создастся новая последовательность, так, что записи в родительской и дочерней таблицах станут иметь дубликаты по id. Однако, вы можете вручную указать другую последовательность для столбца id (скорее всего, с другими, не пересекающимися с родительской последовательностью, стартовым и конечным номерами). В этом случае при записи в каждую из таблиц номера будут браться из соответствующей «своей» последовательности.

Подробнее по теме:

1 комментарий

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.