Добавить столбец и установить значение по умолчанию в другое поле - PullRequest
1 голос
/ 26 февраля 2020

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

id  |              attrs  
----+--------------------------------------------------------------------------------------
  1 | {"type": "test_type", "m_attrs": {"left_values": "Jack", "right_values": "John"}}

Однако я хочу изменить эту таблицу и разбить столбец attrs на отдельные столбцы для type, left_values и right_values:

alter table t_name add column if not exists type text;
alter table t_name add column if not exists left_values text;
alter table t_name add column if not exists right_values text;

Каков наилучший способ сделать эти столбцы ненулевыми и установить в качестве значения по умолчанию их значение в существующем столбце attrs, ie: attrs->m_attrs->>'left_value'

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

1 Ответ

1 голос
/ 26 февраля 2020

Начиная с PostgreSQL v12, было бы лучше использовать сгенерированные столбцы :

ALTER TABLE t_name
   ADD "type" text GENERATED ALWAYS AS (attrs->>'type') STORED,
   ADD left_values text GENERATED ALWAYS AS (attrs->'m_attrs'->>'left_values') STORED,
   ADD right_values text GENERATED ALWAYS AS (attrs->'m_attrs'->>'right_values') STORED;

Это потребует переписывания таблицы, так что это займет некоторое время и пространство, но в любом случае невозможно избежать перезаписи таблицы такой операцией. Вы можете уменьшить влияние, выполнив это за один ALTER TABLE, как указано выше.

Для более старых версий баз данных вы должны сделать это в следующих шагах:

  • запустить транзакцию, чтобы следующие шаги блокируют доступ к таблице
  • добавить (обнуляемые) столбцы
  • заполнить столбцы одним UPDATE
  • повернуть столбцы NOT NULL при желании
  • создать триггер, который автоматически заполняет новые столбцы
  • зафиксировать транзакцию

Помимо обеспечения атомарности, транзакция гарантирует, что новые строки не будут добавлены до того, как триггер будет на месте.

После этого было бы неплохо VACUUM (FILL) стол (еще больше простоя), чтобы избавиться от наворотов от UPDATE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...