5.3. Генерируемые столбцы#

5.3. Генерируемые столбцы

5.3. Генерируемые столбцы #

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

Для создания генерируемого столбца используйте предложение GENERATED ALWAYS AS в команде CREATE TABLE, например:

CREATE TABLE people (
    ...,
    height_cm numeric,
    height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED
);

Ключевое слово STORED должно быть указано для выбора хранимого типа генерируемого столбца. См. CREATE TABLE для получения более подробной информации.

Столбец, созданный автоматически, не может быть записан напрямую. В командах INSERT или UPDATE нельзя указывать значение для столбца, созданного автоматически, но можно использовать ключевое слово DEFAULT.

Рассмотрим различия между столбцом со значением по умолчанию и генерируемым столбцом. Значение по умолчанию для столбца вычисляется один раз при первой вставке строки, если другое значение не было указано; генерируемый столбец обновляется каждый раз, когда изменяется строка и не может быть переопределен. Выражение значения по умолчанию для столбца не может ссылаться на другие столбцы таблицы; а генерирующее выражение обычно ссылается на них. Выражение значения по умолчанию для столбца может использовать волатильные функции, например random() или функции, относящиеся к текущему времени; это не допускается для генерируемых столбцов.

Несколько ограничений применяются к определению генерируемых столбцов и таблиц, включающих генерируемые столбцы:

  • Генерирующее выражение может использовать только постоянные функции и не может использовать подзапросы или ссылаться на что-либо, кроме текущей строки.

  • Генерирующее выражение не может ссылаться на другой генерируемый столбец.

  • Генерирующее выражение не может ссылаться на системный столбец, за исключением столбца tableoid.

  • Столбец, созданный автоматически, не может иметь значения по умолчанию или определение идентичности.

  • Столбец, созданный автоматически, не может быть частью ключа разделения.

  • Внешние таблицы могут иметь генерируемые столбцы. См. CREATE FOREIGN TABLE для получения подробной информации.

  • Для наследования и разбиения на секции:

    • Если родительский столбец является вычисляемым столбцом, его дочерний столбец также должен быть вычисляемым столбцом; однако дочерний столбец может иметь другое генерирующее выражение. Генерирующее выражение, которое фактически применяется при вставке или обновлении строки, связано с таблицей, в которой строка физически находится. (Это отличается от поведения для значений по умолчанию столбца: для них применяется значение по умолчанию, связанное с таблицей, указанной в запросе.)

    • Если родительский столбец не является генерируемым столбцом, его дочерний столбец также не должен быть генерируемым.

    • Для унаследованных таблиц, если определение столбца дочерней таблицы задано без предложения GENERATED в CREATE TABLE ... INHERITS, то его предложение GENERATED будет автоматически скопировано из родительской таблицы. ALTER TABLE ... INHERIT будет требовать, чтобы родительские и дочерние столбцы совпадали по статусу генерирования, но не будет требовать совпадения соответствующих генерирующих выражений.

    • Аналогично для секционированных таблиц, если вы пишете определение дочернего столбца без предложения GENERATED в CREATE TABLE ... PARTITION OF, то его предложение GENERATED будет автоматически скопировано от родителя. ALTER TABLE ... ATTACH PARTITION будет требовать, чтобы родительские и дочерние столбцы совпадали по статусу генерирования, но не будет требовать совпадения соответствующих генерирующих выражений.

    • В случае множественного наследования, если один из родительских столбцов является вычисляемым столбцом, то все родительские столбцы должны быть вычисляемыми столбцами. Если у них не одинаковое генерирующее выражение, то необходимое выражение для дочернего столбца должно быть указано явно.

При использовании генерируемых столбцов следует также учитывать следующие моменты:

  • Права доступа к генерируемым столбцам отдельны от прав доступа к базовым столбцам. Таким образом, можно настроить определенную роль так, чтобы она могла прочитать генерируемый столбец, но не базовые столбцы.

  • Генерируемые столбцы, по определению, обновляются после выполнения триггеров BEFORE. Поэтому изменения, внесенные в базовые столбцы в триггере BEFORE, будут отражены в генерируемых столбцах. Но получить доступ к генерируемым столбцам в триггерах BEFORE нельзя.

  • Генерируемые столбцы пропускаются для логической репликации и не могут быть указаны в списке столбцов CREATE PUBLICATION.