Пересчет значений в сгенерированном Postgres столбце после изменения базовой функции

#sql #postgresql #sql-function #generated-columns

#sql #postgresql #sql-функция #сгенерированные столбцы

Вопрос:

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

 CREATE OR REPLACE FUNCTION extract_first_name(p_name text) RETURNS text
LANGUAGE SQL IMMUTABLE
AS $$
    SELECT split_part(p_name, ' ', 1);
$$;

CREATE TABLE customers (
    id serial,
    name text,
    first_name text GENERATED ALWAYS AS (extract_first_name(name)) STORED
);
  

Позже кто-то обнаружит, что extract_first_name функция слишком упрощена и нуждается в изменении. Затем он обновляется, но значения в first_name столбце остаются неизменными. Как нам самым простым и эффективным способом пересчитать все значения в first_name столбце, чтобы использовать последнюю версию функции без блокировки таблицы?

Ответ №1:

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

 Update customers 
   set name = name; 
  

Это при необходимости обновит каждую строку в таблице. Но поскольку Postgres использует модель MVCC, это не помешает другим пользователям выбирать во время операции.

Основное преимущество использования модели управления параллелизмом MVCC вместо блокировки заключается в том, что в MVCC блокировки, полученные для запроса (чтения) данных, не конфликтуют с блокировками, полученными для записи данных, и поэтому чтение никогда не блокирует запись, а запись никогда не блокирует чтение. PostgreSQL поддерживает эту гарантию даже при обеспечении самого строгого уровня изоляции транзакций благодаря использованию инновационного уровня изоляции сериализуемых моментальных снимков (SSI).

Однако вам нужно будет следить за взаимоблокировками, если вы продолжаете разрешать обновления во время этого процесса.

Комментарии:

1. Он также вычисляется при добавлении сгенерированного столбца.