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, так как оно будет скопировано из родительского столбца.

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

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

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

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

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

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