ALTER TABLE
ALTER TABLE — изменить определение таблицы
Синтаксис
ALTER TABLE [ IF EXISTS ] [ ONLY ]имя[ * ]действие[, ... ] ALTER TABLE [ IF EXISTS ] [ ONLY ]имя[ * ] RENAME [ COLUMN ]имя_столбцаTOновое_имя_столбцаALTER TABLE [ IF EXISTS ] [ ONLY ]имя[ * ] RENAME CONSTRAINTимя_ограниченияTOимя_нового_ограниченияALTER TABLE [ IF EXISTS ]имяRENAME TOновое_имяALTER TABLE [ IF EXISTS ]имяSET SCHEMAновая_схемаALTER TABLE ALL IN TABLESPACEимя[ OWNED BYимя_роли[, ... ] ] SET TABLESPACEновое_табл_пространство[ NOWAIT ] Гдедействиеможет быть следующим: ADD [ COLUMN ]имя_столбцатип_данных[ COLLATEправило_сортировки] [ограничение_столбца[ ... ] ] DROP [ COLUMN ] [ IF EXISTS ]имя_столбца[ RESTRICT | CASCADE ] ALTER [ COLUMN ]имя_столбца[ SET DATA ] TYPEтип_данных[ COLLATEправило_сортировки] [ USINGвыражение] ALTER [ COLUMN ]имя_столбцаSET DEFAULTвыражениеALTER [ COLUMN ]имя_столбцаDROP DEFAULT ALTER [ COLUMN ]имя_столбца{ SET | DROP } NOT NULL ALTER [ COLUMN ]имя_столбцаSET STATISTICSintegerALTER [ COLUMN ]имя_столбцаSET (атрибут=значение[, ... ] ) ALTER [ COLUMN ]имя_столбцаRESET (атрибут[, ... ] ) ALTER [ COLUMN ]имя_столбцаSET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } ADDограничение_таблицы[ NOT VALID ] ADDограничение_таблицы_по_индексуALTER CONSTRAINTимя_ограничения[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] VALIDATE CONSTRAINTимя_ограниченияDROP CONSTRAINT [ IF EXISTS ]имя_ограничения[ RESTRICT | CASCADE ] DISABLE TRIGGER [имя_триггера| ALL | USER ] ENABLE TRIGGER [имя_триггера| ALL | USER ] ENABLE REPLICA TRIGGERимя_триггераENABLE ALWAYS TRIGGERимя_триггераDISABLE RULEимя_правила_перезаписиENABLE RULEимя_правила_перезаписиENABLE REPLICA RULEимя_правила_перезаписиENABLE ALWAYS RULEимя_правила_перезаписиDISABLE ROW LEVEL SECURITY ENABLE ROW LEVEL SECURITY FORCE ROW LEVEL SECURITY NO FORCE ROW LEVEL SECURITY CLUSTER ONимя_индексаSET WITHOUT CLUSTER SET WITH OIDS SET WITHOUT OIDS SET TABLESPACEновое_табл_пространствоSET { LOGGED | UNLOGGED } SET (параметр_хранения=значение[, ... ] ) RESET (параметр_хранения[, ... ] ) INHERITтаблица_родительNO INHERITтаблица_родительOFимя_типаNOT OF OWNER TO {новый_владелец| CURRENT_USER | SESSION_USER } REPLICA IDENTITY { DEFAULT | USING INDEXимя_индекса| FULL | NOTHING } иограничение_таблицы_по_индексу: [ CONSTRAINTимя_ограничения] { UNIQUE | PRIMARY KEY } USING INDEXимя_индекса[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
Описание
ALTER TABLE меняет определение существующей таблицы. Несколько её разновидностей описаны ниже. Заметьте, что для разных разновидностей могут требоваться разные уровни блокировок. Если явно не отмечено другое, требуется блокировка ACCESS EXCLUSIVE. При перечислении нескольких подкоманд будет запрашиваться самая сильная блокировка из требуемых ими.
ADD COLUMNЭта форма добавляет в таблицу новый столбец, с тем же синтаксисом, что и CREATE TABLE.
DROP COLUMN [ IF EXISTS ]Эта форма удаляет столбец из таблицы. При этом автоматически будут удалены индексы и ограничения таблицы, связанные с этим столбцом. Если от этого столбца зависят какие-либо объекты вне этой таблицы, например, внешние ключи или представления, удалить и их можно, добавив указание
CASCADE. Если в команде указаноIF EXISTSи этот столбец не существует, это не считается ошибкой, вместо этого просто выдаётся замечание.SET DATA TYPEЭта форма меняет тип столбца таблицы. Индексы и простые табличные ограничения, включающие этот столбец, будут автоматически преобразованы для использования нового типа столбца, для чего будет заново разобрано определяющее их выражение. Необязательное предложение
COLLATEзадаёт правило сортировки для нового столбца; если оно опущено, выбирается правило сортировки по умолчанию для нового типа. Необязательное предложениеUSINGопределяет, как новое значение столбца будет получено из старого; если оно отсутствует, выполняется приведение типа по умолчанию, как обычное присваивание значения старого типа новому. ПредложениеUSINGстановится обязательным, если неявное приведение или присваивание с приведением старого типа к новому не определено.SET/DROP DEFAULTЭти формы задают или удаляют значение по умолчанию для столбцов. Значения по умолчанию применяются только при последующих командах
INSERTилиUPDATE; их изменения не отражаются в строках, уже существующих в таблице.SET/DROP NOT NULLЭти формы определяют, будет ли столбец принимать значения NULL или нет. Задать
SET NOT NULLможно, только если столбец не содержит значений NULL.SET STATISTICSЭта форма задаёт ориентир сбора статистики по столбцу для последующих операций ANALYZE. Диапазон допустимых значений ориентира: 0..10000; при -1 применяется системное значение по умолчанию (default_statistics_target). За дополнительными сведениями об использовании статистики планировщиком запросов Postgres Pro обратитесь к Разделу 14.2.
SET STATISTICSзапрашивает блокировкуSHARE UPDATE EXCLUSIVE.SET (атрибут=значение[, ... ] )RESET (атрибут[, ... ] )Эта форма устанавливает или сбрасывает параметры атрибутов. В настоящее время единственными параметрами атрибутов являются
n_distinctиn_distinct_inherited, которые переопределяют оценку кол-ва_различных_значений, производимую последующими операциями ANALYZE. Атрибутn_distinctвлияет на расчёт статистики по самой таблице, аn_distinct_inherited— на статистику по таблице и её потомкам. Если заданное значение положительно,ANALYZEбудет считать, что столбец содержит именно это количество различных значений не NULL. Если заданное значение отрицательно (оно должно быть больше или равно -1),ANALYZEбудет считать, что количество различных значений не NULL в столбце линейно зависит от размера таблицы; точное число будет получено умножением примерного размера таблицы на абсолютное значение параметра. Например, при -1 будет предполагаться, что различны все значения в столбце, а при -0,5 — что в среднем каждое значение повторяется дважды. Это может быть полезно, когда размер таблицы меняется со временем, так как умножение на число строк в таблице производится только во время планирования запроса. С 0 количество различных значений оценивается как обычно. За дополнительными сведениями об использовании статистики планировщиком запросов Postgres Pro обратитесь к Разделу 14.2.Для изменения параметров атрибутов запрашивается блокировка
SHARE UPDATE EXCLUSIVE.-
SET STORAGE Эта форма устанавливает режим хранения столбца. Она определяет, хранятся ли данные внутри таблицы или в отдельной таблице TOAST, а также, сжимаются ли они. Режим
PLAINдолжен применяться для значений фиксированной длины, таких какinteger; это вариант хранения внутри, без сжатия. РежимMAINприменяется для хранения внутри, но сжатых данных,EXTERNAL— для внешнего хранения несжатых данных, аEXTENDED— для внешнего хранения сжатых данных.EXTENDEDиспользуется по умолчанию для большинства типов данных, поддерживающих хранилище неPLAIN. ПрименениеEXTERNALпозволяет ускорить операции с подстроками на очень больших значенияхtextиbytea, за счёт проигрыша в объёме хранилища. Заметьте, что предложениеSET STORAGEсамо по себе не меняет ничего в таблице, оно только задаёт стратегию, которая будет реализована при будущих изменениях в таблице. За дополнительными сведениями обратитесь к Разделу 63.2.ADDограничение_таблицы[ NOT VALID ]Эта форма добавляет в таблицу новое ограничение, с тем же синтаксисом, что и CREATE TABLE, и дополнительным указанием
NOT VALID, которое в настоящее время разрешено только для ограничений внешнего ключа и ограничений-проверок. Если ограничение помечено какNOT VALID, потенциально длительная начальная проверка того, что ему удовлетворяют все строки, пропускается. Тем не менее это ограничение будет действовать при последующих добавлениях или изменениях данных (то есть эти операции не будут выполнены, если новая строка нарушит условие ограничения-проверки, либо при наличии внешнего ключа в главной таблице не найдётся соответствующая строка). Но база данных не будет считать, что ограничение выполняется для всех строк таблицы, пока оно не будет проверено с применением указанияVALIDATE CONSTRAINT.ADDограничение_таблицы_по_индексуЭта форма добавляет в таблицу новое ограничение
PRIMARY KEYилиUNIQUEна базе существующего уникального индекса. В это ограничение будут включены все столбцы данного индекса.Индекс не может быть частичным и включать столбцы-выражения. Кроме того, это должен быть индекс-B-дерево с порядком сортировки по умолчанию. С такими ограничениями добавляемые индексы не будут ничем отличаться от индексов, создаваемых обычными командами
ADD PRIMARY KEYиADD UNIQUE.В случае с указанием
PRIMARY KEY, если столбцы индекса ещё не помеченыNOT NULL, данная команда попытается выполнитьALTER COLUMN SET NOT NULLдля каждого столбца. При этом потребуется произвести полное сканирование таблицы, чтобы убедиться, что столбец(ы) не содержит NULL. Во всех остальных случаях это быстрая операция.Если задано имя ограничения, индекс будет переименован и получит заданное имя. В противном случае именем ограничения станет имя индекса.
После выполнения этой команды индекс становится «принадлежащим» ограничению, так же, как если бы он был создан обычной командой
ADD PRIMARY KEYилиADD UNIQUE. Это значит, в частности, что при удалении ограничения индекс будет удалён вместе с ним.Примечание
Добавление ограничения на базе существующего индекса бывает полезно в ситуациях, когда новое ограничение требуется добавить, не блокируя изменения в таблице на долгое время. Для этого можно создать индекс командой
CREATE INDEX CONCURRENTLY, а затем задействовать его как полноценное ограничение, используя эту запись. См. следующий пример.ALTER CONSTRAINTЭта форма меняет атрибуты созданного ранее ограничения. В настоящее время изменять можно только ограничения внешнего ключа.
VALIDATE CONSTRAINTЭта форма проверяет ограничение внешнего ключа или ограничение-проверку, созданное ранее с указанием
NOT VALID, сканируя всю таблицу с целью убедиться, что ограничению удовлетворяют все строки. Если ограничение уже помечено как верное, ничего не происходит.Проверка больших таблиц может быть довольно длительной. Смысл отделения проверки от собственно создания ограничения состоит в том, что это позволяет отложить проверку на время меньшей активности или провести дополнительную работу с существующими ошибками и при этом не допустить новых. Заметьте также, что во время осуществления проверки сама по себе она не препятствует выполнению обычных команд записи в таблицу.
При проверке запрашивается только блокировка
SHARE UPDATE EXCLUSIVEцелевой таблицы. Для ограничений внешнего ключа требуется также блокировкаROW SHAREв таблице, на которую ссылается ограничение.DROP CONSTRAINT [ IF EXISTS ]Эта форма удаляет указанное ограничение таблицы. Если указано
IF EXISTSи заданное ограничение не существует, это не считается ошибкой. В этом случае выдаётся только замечание.DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGERЭти формы настраивают срабатывание триггера(ов), принадлежащего таблице. Отключённый триггер сохраняется в системе, но не выполняется, когда происходит вызывающее его событие. Для отложенных триггеров состояние включения проверяется при возникновении события, а не когда фактически вызывается функция триггера. Эта команда может отключить или включить один триггер по имени, либо все триггеры таблицы, либо только пользовательские триггеры (исключая сгенерированные внутрисистемные триггеры ограничений, например, триггеры, реализующие ограничения внешнего ключа или отложенные ограничения уникальности или исключений). Для отключения или включения сгенерированных внутрисистемных триггеров ограничений требуются права суперпользователя; отключать их следует с осторожностью, так как очевидно, что невозможно гарантировать целостность ограничений, если триггеры не работают. На механизм срабатывания триггеров также влияет конфигурационная переменная session_replication_role. Включённые без дополнительных указаний триггеры будут срабатывать, когда роль репликации — «origin» (по умолчанию) или «local». Триггеры, включённые указанием
ENABLE REPLICA, будут срабатывать, только если текущий режим сеанса — «replica», а после указанияENABLE ALWAYSтриггеры срабатывают вне зависимости от текущего режима репликации.Эта команда запрашивает блокировку
SHARE ROW EXCLUSIVE.DISABLE/ENABLE [ REPLICA | ALWAYS ] RULEЭти формы настраивают срабатывание правил перезаписи, относящихся к таблице. Отключённое правило сохраняется в системе, но не применяется во время переписывания запроса. По сути эти операции подобны операциям включения/отключения триггеров. Однако это не распространяется на правила
ON SELECT— они применяются всегда, чтобы представления продолжали работать, даже в сеансах, исполняющих не основную роль репликации.DISABLE/ENABLE ROW LEVEL SECURITYЭти формы управляют применением относящихся к таблице политик защиты строк. Если защита включается, но политики для таблицы не определены, применяется политика запрета доступа по умолчанию. Заметьте, что политики могут быть определены для таблицы, даже если защита на уровне строк отключена — в этом случае политики НЕ применяются и их ограничения игнорируются. См. также CREATE POLICY.
NO FORCE/FORCE ROW LEVEL SECURITYЭти формы управляют применением относящихся к таблице политик защиты строк, когда пользователь является её владельцем. Если это поведение включается, политики защиты на уровне строк будут действовать и на владельца таблицы. Если оно отключено (по умолчанию), защита на уровне строк не будет действовать на пользователя, являющегося владельцем таблицы. См. также CREATE POLICY.
CLUSTER ONЭта форма выбирает индекс по умолчанию для последующих операций CLUSTER. Собственно кластеризация таблицы при этом не выполняется.
Для изменения параметров кластеризации запрашивается блокировка
SHARE UPDATE EXCLUSIVE.SET WITHOUT CLUSTERЭта форма удаляет последнее заданное указание индекса для CLUSTER. Её действие отразится на будущих операциях кластеризации, для которых не будет задан индекс.
Для изменения параметров кластеризации запрашивается блокировка
SHARE UPDATE EXCLUSIVE.SET WITH OIDSЭта форма добавляет в таблицу системный столбец
oid(см. Раздел 5.4). Если в таблице уже есть такой столбец, она не делает ничего.Заметьте, что это не равнозначно команде
ADD COLUMN oid oid(эта команда добавит не системный, а обычный столбец с подходящим именемoid).SET WITHOUT OIDSЭта форма удаляет из таблицы системный столбец
oid. Это в точности равнозначноDROP COLUMN oid RESTRICT, за исключением того, что в случае отсутствия столбцаoidошибки не будет.SET TABLESPACEЭта форма меняет табличное пространство таблицы на заданное и перемещает файлы данных, связанные с таблицей, в новое пространство. Индексы таблицы, если они имеются, не перемещаются; однако их можно переместить отдельно дополнительными командами
SET TABLESPACE. ФормаALL IN TABLESPACEпозволяет перенести в другое табличное пространство все таблицы текущей базы данных, при этом она сначала блокирует все таблицы, а затем переносит каждую из них. Эта форма также поддерживает указаниеOWNED BY, с которым перемещаются только таблицы указанного владельца. Если указан параметрNOWAIT, команда завершится ошибкой, если не сможет получить все требуемые блокировки немедленно. Заметьте, что системные каталоги эта форма не перемещает; если требуется переместить их, следует использоватьALTER DATABASEили явные вызовыALTER TABLE. Отношенияinformation_schemaне считаются частью системных каталогов и подлежат перемещению. См. также CREATE TABLESPACE.SET { LOGGED | UNLOGGED }Эта форма меняет характеристику журналирования таблицы, делает таблицу журналируемой/нежурналируемой, соответственно (см.
UNLOGGED). К временной таблице она неприменима.SET (параметр_хранения=значение[, ... ] )Эта форма меняет один или несколько параметров хранения таблицы. Подробнее допустимые параметры описаны в Параметры хранения. Заметьте, что эта команда не меняет содержимое таблицы немедленно; в зависимости от параметра может потребоваться перезаписать таблицы, чтобы получить желаемый эффект. Это можно сделать с помощью команд VACUUM FULL, CLUSTER или одной из форм
ALTER TABLE, принудительно перезаписывающих таблицу.Примечание
Хотя
CREATE TABLEпозволяет указатьOIDSв синтаксисеWITH (,параметр_хранения)ALTER TABLEне воспринимаетOIDSкак параметр хранения. Поэтому для изменения характеристики OID следует применять формыSET WITH OIDSиSET WITHOUT OIDS.RESET (параметр_хранения[, ... ] )Эта форма сбрасывает один или несколько параметров хранения к значениям по умолчанию. Как и с
SET, для полного обновления таблицы может потребоваться перезаписать таблицу.INHERITтаблица_родительЭта форма назначает целевую таблицу потомком заданной родительской таблицы. Впоследствии запросы к родительской таблице будут включать записи и целевой таблицы. Чтобы таблица могла стать потомком, она должна содержать те же столбцы, что и родительская (хотя она может включать и дополнительные столбцы). Столбцы должны иметь одинаковые типы данных и, если в родительской таблице какие-то из них имеют ограничение
NOT NULL, они должны иметь ограничениеNOT NULLи в таблице-потомке.Также в таблице-потомке должны присутствовать все ограничения
CHECKродительской таблицы, за исключением ненаследуемых (то есть созданных командойALTER TABLE ... ADD CONSTRAINT ... NO INHERIT), которые игнорируются; при этом все соответствующие ограничения в таблице-потомке не должны быть ненаследуемыми. В настоящее время ограниченияUNIQUE,PRIMARY KEYиFOREIGN KEYне учитываются, но в будущем это может измениться.NO INHERITтаблица_родительЭта форма удаляет целевую таблицу из списка потомков указанной родительской таблицы. Результаты запросов к родительской таблице после этого не будут включать записи, взятые из целевой таблицы.
OFимя_типаЭта форма связывает таблицу с составным типом, как если бы она была сформирована командой
CREATE TABLE OF. При этом список имён и типов столбцов должен точно соответствовать тому, что образует составной тип; отличие возможно в системном столбцеoid. Кроме того, таблица не должна быть потомком какой-либо другой таблицы. Эти ограничения гарантируют, что командаCREATE TABLE OFпозволит создать таблицу с таким же определением.NOT OFЭта форма разрывает связь типизированной таблицы с её типом.
OWNERЭта форма меняет владельца таблицы, последовательности, представления, материализованного представления или сторонней таблицы на заданного пользователя.
REPLICA IDENTITYЭта форма меняет информацию, записываемую в журнал предзаписи для идентификации изменяемых или удаляемых строк. Данный параметр действует только при использовании логической репликации. В режиме
DEFAULT(по умолчанию для не системных таблиц) записывается старые значения столбцов первичного ключа, если он есть. В режимеUSING INDEXзаписываются старые значения столбцов, составляющих заданный индекс, который должен быть уникальным, не частичным, не отложенным и включать только столбцы, помеченныеNOT NULL. В режимеFULLзаписываются старые значения всех столбцов в строке, а в режимеNOTHING(по умолчанию для системных таблиц) никакая информация о старой строке не записывается. Во всех случаях старые значения записываются в журнал, только если как минимум в одном столбце из тех, что должны быть записаны, произошли изменения в новой строке.RENAMEФормы
RENAMEменяют имя таблицы (или индекса, последовательности, представления, материализованного представления или сторонней таблицы), имя отдельного столбца таблицы или имя ограничения таблицы. На хранимые данные это не влияет.SET SCHEMAЭта форма перемещает таблицу в другую схему. Вместе с таблицей перемещаются связанные с ней индексы и ограничения, а также последовательности, принадлежащие столбцам таблицы.
Все виды ALTER TABLE, действующие на одну таблицу, кроме RENAME и SET SCHEMA, можно объединить в список множественных изменений и применить вместе. Например, можно добавить несколько столбцов и/или изменить тип столбцов в одной команде. Это особенно полезно для больших таблиц, так как вся таблица обрабатывается за один проход.
Выполнить ALTER TABLE может только владелец соответствующей таблицы. Чтобы сменить схему или табличное пространство таблицы, необходимо также иметь право CREATE в новой схеме или табличном пространстве. Чтобы сделать таблицу потомком другой таблицы, нужно быть владельцем и родительской таблицы. Чтобы сменить владельца, необходимо быть непосредственным или опосредованным членом новой роли-владельца, а эта роль должна иметь право CREATE в схеме таблицы. (С такими ограничениями при смене владельца не происходит ничего такого, что нельзя было бы сделать, имея право удалить и вновь создать таблицу. Однако суперпользователь может сменить владельца таблицы в любом случае.) Чтобы добавить столбец, сменить тип столбца или применить предложение OF, необходимо также иметь право USAGE для соответствующего типа данных.
Параметры
IF EXISTSНе считать ошибкой, если таблица не существует. В этом случае будет выдано замечание.
имяИмя (возможно, дополненное схемой) существующей таблицы, подлежащей изменению. Если перед именем таблицы указано
ONLY, изменяется только заданная таблица. БезONLYизменяется и заданная таблица, и все её потомки (если таковые есть). После имени таблицы можно также добавить необязательное указание*, чтобы явно обозначить, что изменению подлежат все дочерние таблицы.имя_столбцаИмя нового или существующего столбца.
новое_имя_столбцаНовое имя существующего столбца.
новое_имяНовое имя таблицы.
тип_данныхТип данных нового столбца или новый тип данных существующего столбца.
ограничение_таблицыНовое ограничение таблицы.
имя_ограниченияИмя нового или существующего ограничения.
CASCADEАвтоматически удалять объекты, зависящие от удаляемого столбца или ограничения (например, представления, содержащие этот столбец).
RESTRICTОтказать в удалении столбца или ограничения, если существуют зависящие от них объекты. Это поведение по умолчанию.
имя_триггераИмя включаемого или отключаемого триггера.
ALLОтключить или включить все триггеры, принадлежащие таблице. (Для этого требуются права суперпользователя, если в числе этих триггеров оказываются сгенерированные внутрисистемные триггеры исключений, например те, что реализуют ограничения внешнего ключа или отложенные ограничения уникальности и исключений.)
USERОтключить или включить все триггеры, принадлежащие таблице, за исключением сгенерированных внутрисистемных триггеров исключений, например, тех, что реализуют ограничения внешнего ключа или отложенные ограничения уникальности и исключений.
имя_индексаИмя существующего индекса.
параметр_храненияИмя параметра хранения таблицы
значениеНовое значение параметра хранения таблицы. Это может быть число или строка, в зависимости от параметра.
таблица_родительРодительская таблица, с которой будет установлена или разорвана связь данной таблицы.
новый_владелецИмя пользователя, назначаемого новым владельцем таблицы.
новое_табл_пространствоИмя табличного пространства, в которое будет перемещена таблица.
новая_схемаИмя схемы, в которую будет перемещена таблица.
Замечания
Ключевое слово COLUMN не несёт смысловой нагрузки и может быть опущено.
Когда столбец добавляется с помощью ADD COLUMN, во всех существующих в таблице строках этот столбец инициализируется значением по умолчанию (или NULL, если предложение DEFAULT для столбца отсутствует). Если предложение DEFAULT отсутствует, это сводится только к изменению метаданных, непосредственного изменения данных таблицы не происходит; добавленные значения NULL выводятся при чтении.
Добавление столбца с предложением DEFAULT или изменение типа существующего столбца влечёт за собой перезапись всей таблицы и её индексов. Но возможно исключение при смене типа существующего столбца: если предложение USING не меняет содержимое столбца и старый тип двоично приводится к новому или является неограниченным доменом поверх нового типа, перезапись таблицы не требуется; хотя все индексы с затронутыми столбцами всё же требуется перестроить. При добавлении или удалении системного столбца oid также необходима перезапись всей таблицы. Перестроение больших таблиц и/или их индексов может быть весьма длительной процедурой, которая при этом временно требует вдвое больше места на диске.
Добавление ограничений CHECK или NOT NULL влечёт за собой необходимость просканировать таблицу, чтобы проверить, что все существующие строки удовлетворяют ограничению, но перезаписывать таблицу при этом не требуется.
Возможность объединения множества изменений в одну команду ALTER TABLE полезна в основном тем, что позволяет совместить сканирования и перезаписи таблицы, требуемые этим операциям, и выполнить их за один проход.
Форма DROP COLUMN не удаляет столбец физически, а просто делает его невидимым для операций SQL. При последующих операциях добавления или изменения в этот столбец будет записываться значение NULL. Таким образом, удаление столбца выполняется быстро, но при этом размер таблицы на диске не уменьшается, так как пространство, занимаемое удалённым столбцом, не высвобождается. Это пространство будет освобождено со временем, по мере изменения существующих строк. (При удалении системного столбца oid это поведение не наблюдается, так как немедленно выполняется перезапись таблицы.)
Чтобы принудительно высвободить пространство, занимаемое столбцом, который был удалён, можно выполнить одну из форм ALTER TABLE, производящих перезапись всей таблицы. В результате все строки будут воссозданы так, что в удалённом столбце будет содержаться NULL.
Перезаписывающие формы ALTER TABLE небезопасны с точки зрения MVCC. После перезаписи таблица будет выглядеть пустой для параллельных транзакций, если они работают со снимком, полученным до момента перезаписи. За подробностями обратитесь к Разделу 13.5.
В указании USING предложения SET DATA TYPE на самом деле можно записать выражение со старыми значениями строки; то есть, оно может ссылаться как на преобразуемые столбцы, так и на другие. Это позволяет записывать в SET DATA TYPE очень общие преобразования данных. Ввиду такой гибкости, выражение USING не применяется к значению по умолчанию данного столбца (если таковое есть); результат может быть не константным выражением, что требуется для значения по умолчанию. Это означает, что в случае отсутствия явного приведения или присваивания старого типа новому, SET DATA TYPE может не справиться с преобразованием значения по умолчанию, несмотря на то, что применяется предложение USING. В этих случаях нужно удалить значение по умолчанию с помощью DROP DEFAULT, выполнить ALTER TYPE, а затем с помощью SET DEFAULT задать новое подходящее значение по умолчанию. Подобные соображения применимы и в отношении индексов и ограничений с этим столбцом.
Если у таблицы есть дочерние таблицы, добавлять, переименовывать или менять тип столбца, либо переименовывать наследуемое ограничение в родительской таблице, не делая того же самого во всех дочерних таблицах, нельзя. То есть, команда ALTER TABLE ONLY выполнена не будет. Это гарантирует, что дочерние таблицы всегда будут содержать те же столбцы, что и родительская.
Рекурсивная операция DROP COLUMN удалит столбец из дочерней таблицы, только если этот столбец не наследуется от каких-то других родителей и не была определён в дочерней таблице независимо. Нерекурсивная операция DROP COLUMN (т. е., ALTER TABLE ONLY ... DROP COLUMN) никогда не удаляет унаследованные столбцы, но вместо этого помечает их как независимо определённые, а не наследуемые.
Действия TRIGGER, CLUSTER, OWNER и TABLESPACE никогда не распространяются рекурсивно на дочерние таблицы; то есть, они всегда выполняются так, как будто указано ONLY. Операция добавления ограничения выполняется рекурсивно только для ограничений CHECK, не помеченных как NO INHERIT.
Какие-либо изменения таблиц системного каталога не допускаются.
За более подробным описанием допустимых параметров обратитесь к CREATE TABLE. Дополнительно о наследовании можно узнать в Главе 5.
Примеры
Добавление в таблицу столбца типа varchar:
ALTER TABLE distributors ADD COLUMN address varchar(30);
Удаление столбца из таблицы:
ALTER TABLE distributors DROP COLUMN address RESTRICT;
Изменение типов двух существующих столбцов в одной операции:
ALTER TABLE distributors
ALTER COLUMN address TYPE varchar(80),
ALTER COLUMN name TYPE varchar(100);Смена типа целочисленного столбца, содержащего время в стиле Unix, на тип timestamp with time zone с применением предложения USING:
ALTER TABLE foo
ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';То же самое, но в случае, когда у столбца есть значение по умолчанию, не приводимое автоматически к новому типу данных:
ALTER TABLE foo
ALTER COLUMN foo_timestamp DROP DEFAULT,
ALTER COLUMN foo_timestamp TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
ALTER COLUMN foo_timestamp SET DEFAULT now();Переименование существующего столбца:
ALTER TABLE distributors RENAME COLUMN address TO city;
Переименование существующей таблицы:
ALTER TABLE distributors RENAME TO suppliers;
Переименование существующего ограничения:
ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
Добавление в столбец ограничения NOT NULL:
ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
Удаление ограничения NOT NULL из столбца:
ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
Добавление ограничения-проверки в таблицу и все её потомки:
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
Добавление ограничения-проверки только в таблицу, но не в её потомки:
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;
(Данное ограничение-проверка не будет наследоваться и будущими потомками тоже.)
Удаление ограничения-проверки из таблицы и из всех её потомков:
ALTER TABLE distributors DROP CONSTRAINT zipchk;
Удаление ограничения-проверки только из самой таблицы:
ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
(Ограничение-проверка остаётся во всех дочерних таблицах.)
Добавление в таблицу ограничения внешнего ключа:
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address);
Добавление в таблицу ограничения внешнего ключа с наименьшим влиянием на работу других:
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) NOT VALID; ALTER TABLE distributors VALIDATE CONSTRAINT distfk;
Добавление в таблицу ограничения уникальности (по нескольким столбцам):
ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
Добавление в таблицу первичного ключа с автоматическим именем (учтите, что в таблице может быть только один первичный ключ):
ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
Перемещение таблицы в другое табличное пространство:
ALTER TABLE distributors SET TABLESPACE fasttablespace;
Перемещение таблицы в другую схему:
ALTER TABLE myschema.distributors SET SCHEMA yourschema;
Пересоздание ограничения первичного ключа без блокировки изменений в процессе перестроения индекса:
CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;Совместимость
Формы ADD (без USING INDEX), DROP, SET DEFAULT и SET DATA TYPE (без USING) соответствуют стандарту SQL. Другие формы являются расширениями стандарта SQL, реализованными в Postgres Pro. Кроме того, расширением является возможность указать в одной команде ALTER TABLE несколько операций изменения.
ALTER TABLE DROP COLUMN позволяет удалить единственный столбец таблицы и оставить таблицу без столбцов. Это является расширением стандарта SQL, который не допускает существование таблиц с нулём столбцов.