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 ] ALTER TABLE [ IF EXISTS ]имяATTACH PARTITIONимя_секции{ FOR VALUESуказание_границ_секции| DEFAULT } ALTER TABLE [ IF EXISTS ]имяDETACH PARTITIONимя_секции[ CONCURRENTLY | FINALIZE ] ALTER TABLE [ IF EXISTS ]имяSPLIT PARTITIONимя_секцииINTO (PARTITIONимя_секции1{ FOR VALUESуказание_границ_секции| DEFAULT }, PARTITIONимя_секции2{ FOR VALUESуказание_границ_секции| DEFAULT } [, ...]) ALTER TABLE [ IF EXISTS ]имяMERGE PARTITIONS (имя_секции1,имя_секции2[, ...]) INTOимя_секцииГдедействиеможет быть следующим: ADD [ COLUMN ] [ IF NOT EXISTS ]имя_столбцатип_данных[ 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 EXPRESSION AS (выражение) ALTER [ COLUMN ]имя_столбцаDROP EXPRESSION [ IF EXISTS ] ALTER [ COLUMN ]имя_столбцаADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ (параметры_последовательности) ] ALTER [ COLUMN ]имя_столбца{ SET GENERATED { ALWAYS | BY DEFAULT } | SETпараметр_последовательности| RESTART [ [ WITH ]перезапуск] } [...] ALTER [ COLUMN ]имя_столбцаDROP IDENTITY [ IF EXISTS ] ALTER [ COLUMN ]имя_столбцаSET STATISTICS {integer| DEFAULT } ALTER [ COLUMN ]имя_столбцаSET (атрибут=значение[, ... ] ) ALTER [ COLUMN ]имя_столбцаRESET (атрибут[, ... ] ) ALTER [ COLUMN ]имя_столбцаSET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ALTER [ COLUMN ]имя_столбцаSET COMPRESSIONметод_сжатия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 WITHOUT OIDS SET ACCESS METHOD {новый_метод_доступа| DEFAULT } SET TABLESPACEновое_табл_пространствоSET { LOGGED | UNLOGGED } SET (параметр_хранения[=значение] [, ... ] ) RESET (параметр_хранения[, ... ] ) INHERITтаблица_родительNO INHERITтаблица_родительOFимя_типаNOT OF OWNER TO {новый_владелец| CURRENT_ROLE | CURRENT_USER | SESSION_USER } REPLICA IDENTITY { DEFAULT | USING INDEXимя_индекса| FULL | NOTHING } иуказание_границ_секции: IN (выражение_границ_секции[, ...] ) | FROM ( {выражение_границ_секции| MINVALUE | MAXVALUE } [, ...] ) TO ( {выражение_границ_секции| MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUSчисловая_константа, REMAINDERчисловая_константа) иограничение_столбца: [ CONSTRAINTимя_ограничения] { NOT NULL | NULL | CHECK (выражение) [ NO INHERIT ] | DEFAULTвыражение_по_умолчанию| GENERATED ALWAYS AS (генерирующее_выражение) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ (параметры_последовательности) ] | UNIQUE [ NULLS [ NOT ] DISTINCT ]параметры_индекса| PRIMARY KEYпараметры_индекса| REFERENCESцелевая_таблица[ (целевой_столбец) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETEссылочное_действие] [ ON UPDATEссылочное_действие] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] иограничение_таблицы: [ CONSTRAINTимя_ограничения] { CHECK (выражение) [ NO INHERIT ] | UNIQUE [ NULLS [ NOT ] DISTINCT ] (имя_столбца[, ... ] )параметры_индекса| PRIMARY KEY (имя_столбца[, ... ] )параметры_индекса| EXCLUDE [ USINGиндексный_метод] (элемент_исключенияWITHоператор[, ... ] )параметры_индекса[ WHERE (предикат) ] | FOREIGN KEY (имя_столбца[, ... ] ) REFERENCESцелевая_таблица[ (целевой_столбец[, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETEссылочное_действие] [ ON UPDATEссылочное_действие] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] иограничение_таблицы_по_индексу: [ CONSTRAINTимя_ограничения] { UNIQUE | PRIMARY KEY } USING INDEXимя_индекса[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]параметры_индексав ограниченияхUNIQUE,PRIMARY KEYиEXCLUDE: [ INCLUDE (имя_столбца[, ... ] ) ] [ WITH (параметр_хранения[=значение] [, ... ] ) ] [ USING INDEX TABLESPACEтабл_пространство]элемент_исключенияв ограниченииEXCLUDE: {имя_столбца| (выражение) } [ COLLATEправило_сортировки] [класс_операторов[ (параметр_класса_оп=значение[, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]ссылочное_действиев ограниченииFOREIGN KEY/REFERENCES: { NO ACTION | RESTRICT | CASCADE | SET NULL [ (имя_столбца[, ... ] ) ] | SET DEFAULT [ (имя_столбца[, ... ] ) ] }
Описание
ALTER TABLE меняет определение существующей таблицы. Несколько её разновидностей описаны ниже. Заметьте, что для разных разновидностей могут требоваться разные уровни блокировок. Если явно не отмечено другое, запрашивается блокировка ACCESS EXCLUSIVE. При указании нескольких подкоманд будет запрашиваться самая сильная блокировка из требуемых ими.
ADD COLUMN [ IF NOT EXISTS ]#Эта форма добавляет в таблицу новый столбец, с тем же синтаксисом, что и
CREATE TABLE. Если указаноIF NOT EXISTSи столбец с таким именем уже существует, это не будет ошибкой.DROP COLUMN [ IF EXISTS ]#Эта форма удаляет столбец из таблицы. При этом автоматически будут удалены индексы и ограничения таблицы, связанные с этим столбцом. Также будет удалена многовариантная статистика, охватывающая удаляемый столбец, если после его удаления в статистике останутся данные только одного столбца. Если от этого столбца зависят какие либо объекты вне этой таблицы, например, внешние ключи или представления, чтобы удалить их, необходимо добавить указание
CASCADE. Если в команде указаноIF EXISTSи этот столбец не существует, это не считается ошибкой, вместо этого просто выдаётся замечание.SET DATA TYPE#Эта форма меняет тип столбца таблицы. Индексы и простые табличные ограничения, включающие этот столбец, будут автоматически преобразованы для использования нового типа столбца, для чего будет заново разобрано определяющее их выражение. Необязательное предложение
COLLATEзадаёт правило сортировки для нового столбца; если оно опущено, выбирается правило сортировки по умолчанию для нового типа. Необязательное предложениеUSINGопределяет, как новое значение столбца будет получено из старого; если оно отсутствует, выполняется приведение типа по умолчанию, как обычное присваивание значения старого типа новому. ПредложениеUSINGстановится обязательным, если неявное приведение или присваивание с приведением старого типа к новому не определено.При изменении типа столбца статистика столбца удаляется, поэтому после этой операции для таблицы рекомендуется выполнить
ANALYZE.SET/DROP DEFAULT#Эти формы задают или удаляют значение по умолчанию для столбца (удаление равносильно указанию NULL в качестве значения по умолчанию). Новые значения по умолчанию применяются только при последующих командах
INSERTилиUPDATE; их изменения не отражаются в строках, уже существующих в таблице.SET/DROP NOT NULL#Эти формы определяют, будет ли столбец принимать значения NULL или нет.
Указание
SET NOT NULLможно применить к столбцу, только если ни одна из записей таблицы не содержит в этом столбце значениеNULL. Обычно эта проверка производится в момент выполненияALTER TABLEи требует сканирования всей таблицы; однако в случае наличия ограниченийCHECK, гарантирующих отсутствиеNULL, сканирование таблицы пропускается.Если данная таблица является секцией, операцию
DROP NOT NULLнельзя выполнить для столбца, если он определён с характеристикойNOT NULLв родительской таблице. Чтобы удалить ограничениеNOT NULLиз всех секций, выполнитеDROP NOT NULLдля родительской таблицы. Даже если ограничениеNOT NULLв родительской таблице отсутствует, при желании такое ограничение может быть добавлено в отдельные секции. Другими словами, потомки могут запрещать значения NULL, даже если родитель их допускает, но не наоборот.SET EXPRESSION AS#Эта форма заменяет выражение генерируемого столбца. Существующие данные в столбцах обновляются, для всех будущих изменений будет использоваться новое генерирующее выражение.
DROP EXPRESSION [ IF EXISTS ]#Эта форма преобразует хранимый генерируемый столбец в обычный. Существующие данные в столбцах сохраняются, но будущие изменения будут вноситься не генерирующим выражением.
Если указано
DROP EXPRESSION IF EXISTSи заданный столбец не является хранимым генерируемым столбцом, это не считается ошибкой. В этом случае выдаётся только замечание.ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITYSET GENERATED { ALWAYS | BY DEFAULT }DROP IDENTITY [ IF EXISTS ]#Это формы меняют для столбца свойство идентификации или меняют характеристику генерирования для существующего столбца идентификации. За подробностями обратитесь к описанию
CREATE TABLE. Как иSET DEFAULT, эти формы влияют на поведение только последующих командINSERTиUPDATE; их действие не отражаются в строках, уже существующих в таблице.Если указано
DROP IDENTITY IF EXISTSи заданный столбец не является столбцом идентификации, это не считается ошибкой. В этом случае выдаётся только замечание.SETпараметр_последовательностиRESTART#Эти формы меняют нижележащую последовательность ранее созданного столбца идентификации. Здесь
параметр_последовательности— это параметр, поддерживаемый командойALTER SEQUENCE, напримерINCREMENT BY.SET STATISTICS#Эта форма задаёт ориентир сбора статистики по столбцу для последующих операций
ANALYZE. Значение ориентира может лежать в диапазоне от 0 до 10000. Чтобы использовался системный ориентир статистики по умолчанию, необходимо задать значениеDEFAULT(default_statistics_target). Для этого также можно задать значение -1, но теперь этот способ считается устаревшим. За дополнительными сведениями об использовании статистики планировщиком запросов 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 { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT }# Эта форма устанавливает режим хранения столбца. Она определяет, хранятся ли данные внутри таблицы или в отдельной таблице TOAST, а также, сжимаются ли они. Режим
PLAINдолжен применяться для значений фиксированной длины, таких какinteger; это вариант хранения внутри, без сжатия. РежимMAINприменяется для хранения внутри, но сжатых данных,EXTERNAL— для внешнего хранения несжатых данных, аEXTENDED— для внешнего хранения сжатых данных.EXTENDEDиспользуется по умолчанию для большинства типов данных, поддерживающих хранилище неPLAIN. ПрименениеEXTERNALпозволяет ускорить операции с подстроками на очень больших значенияхtextиbytea, за счёт проигрыша в объёме хранилища. Заметьте, что предложениеSET STORAGEсамо по себе не меняет ничего в таблице, оно только задаёт стратегию, которая будет реализована при будущих изменениях в таблице. За дополнительными сведениями обратитесь к Разделу 63.2.-
SET COMPRESSION#метод_сжатия Эта форма задаёт метод сжатия для столбца, определяющий, как будут сжиматься значения, помещаемые в этот столбец в будущем (если режим хранения вообще допускает сжатие). При изменении этого метода перезапись таблицы не производится, поэтому уже существующие в таблице данные могут оставаться сжатыми другими методами. Если таблица восстанавливается средством pg_restore, все значения перезаписываются с применением заданного метода сжатия. Если же данные вставляются из другого отношения (например, командой
INSERT ... SELECT), значения из исходной таблицы не обязательно будут распаковываться, так что ранее сжатые данные могут сохраниться с прежним методом сжатия, они не будут пережиматься методом, установленным для целевого столбца. Поддерживаемые методы сжатия:pglzиlz4. (lz4поддерживается, только если Postgres Pro был собран с ключом--with-lz4.) Кроме того,метод_сжатияможет принимать значениеdefault, с которым применяемый метод сжатия определяется текущим значением параметра default_toast_compression во время добавления данных.ADD#ограничение_таблицы[ NOT VALID ]Эта форма добавляет в таблицу новое ограничение, принимая тот же синтаксис описания ограничения, что и
CREATE TABLE, а также дополнительное указаниеNOT VALID, которое в настоящее время поддерживается только для ограничений внешнего ключа и ограничений-проверок.Обычно эта форма влечёт сканирование всей таблицы для проверки, что все существующие строки в таблице удовлетворяют новому ограничению. Но если используется указание
NOT VALID, эта потенциально длительная проверка пропускается. Тем не менее это ограничение будет действовать при последующих добавлениях или изменениях данных (то есть эти операции не будут выполнены, если новая строка нарушит условие ограничения-проверки, либо при наличии внешнего ключа в главной таблице не найдётся соответствующая строка). Но база данных не будет считать, что ограничение выполняется для всех строк таблицы, пока оно не будет проверено с применением указанияVALIDATE CONSTRAINT. Дополнительную информацию об использовании указанияNOT VALIDвы найдете ниже, в разделе Замечания.Хотя почти все разновидности
ADDтребуют блокировкуограничение_таблицыACCESS EXCLUSIVE, для указанияADD FOREIGN KEYтребуется только блокировкаSHARE ROW EXCLUSIVE. Заметьте, чтоADD FOREIGN KEYзапрашивает такую блокировку как в таблице, в которой добавляется это ограничение, так и в таблице, на которую это ограничение ссылается.С ограничениями уникальности и первичного ключа, добавляемыми в секционированные таблицы, связаны дополнительные требования; см. описание
CREATE TABLE. Кроме того, в настоящее время ограничения внешнего ключа для секционированных таблиц не могут объявляться как непроверенные (NOT VALID).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 UNIQUE INDEX CONCURRENTLY, а затем преобразовать его в ограничение, используя эту запись. См. следующий пример.ALTER CONSTRAINT#Эта форма меняет атрибуты созданного ранее ограничения. В настоящее время изменять можно только ограничения внешнего ключа.
VALIDATE CONSTRAINT#Эта форма проверяет ограничение внешнего ключа или ограничение-проверку, созданное ранее с указанием
NOT VALID, сканируя всю таблицу с целью убедиться, что ограничению удовлетворяют все строки. Если ограничение уже помечено как проверенное, ничего не происходит. (В чём польза этой команды, вы можете узнать в разделе Замечания.)Эта команда запрашивает блокировку
SHARE UPDATE EXCLUSIVE.DROP CONSTRAINT [ IF EXISTS ]#Эта форма удаляет указанное ограничение таблицы, вместе с нижележащим индексом, если таковой имеется. Если указано
IF EXISTSи заданное ограничение не существует, это не считается ошибкой. В этом случае выдаётся только замечание.DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER#Эти формы настраивают срабатывание триггера(ов), принадлежащего таблице. Отключённый триггер сохраняется в системе, но не выполняется, когда происходит вызывающее его событие. (Для отложенных триггеров состояние включения проверяется при возникновении события, а не когда фактически вызывается функция триггера.) Эта команда может отключить или включить один триггер по имени, либо все триггеры таблицы, либо только пользовательские триггеры (кроме сгенерированных внутрисистемных триггеров ограничений, например, триггеров, реализующих ограничения внешнего ключа или отложенные ограничения уникальности и ограничения-исключения). Для отключения или включения сгенерированных внутрисистемных триггеров ограничений требуются права суперпользователя; отключать их следует с осторожностью, так как очевидно, что невозможно гарантировать целостность ограничений, если триггеры не работают.
На механизм срабатывания триггеров также влияет конфигурационная переменная session_replication_role. Включённые без дополнительных указаний (по умолчанию) триггеры будут срабатывать, когда роль репликации — «origin» (по умолчанию) или «local». Триггеры, включённые указанием
ENABLE REPLICA, будут срабатывать, только если текущий режим сеанса — «replica», а триггеры, включённые указаниемENABLE ALWAYS, будут срабатывать независимо от текущего режима репликации.Эффект этого механизма состоит в том, что в конфигурации по умолчанию триггеры не срабатывают в репликах. Это полезно, потому что если триггер используется в исходной базе для распределения данных по таблицам, система репликации будет реплицировать и распределённые таким образом данные, поэтому триггер не должен срабатывать в реплике второй раз, так как иначе будет иметь место дублирование. Однако если триггер используется для других целей, например, выдаёт уведомления, может иметь смысл установить для него свойство
ENABLE ALWAYS, чтобы он также срабатывал в репликах.Когда эта команда применяется к секционированной таблице, состояния соответствующих «клонированных» триггеров в секциях также изменяются, если не указано
ONLY.Эта команда запрашивает блокировку
SHARE ROW EXCLUSIVE.DISABLE/ENABLE [ REPLICA | ALWAYS ] RULE#Эти формы настраивают срабатывание правил перезаписи, относящихся к таблице. Отключённое правило сохраняется в системе, но не применяется во время переписывания запроса. По сути эти операции подобны операциям включения/отключения триггеров. Однако это не распространяется на правила
ON SELECT— они применяются всегда, чтобы представления продолжали работать, даже в сеансах, исполняющих не основную роль репликации.На механизм срабатывания правил также оказывает влияние конфигурационная переменная session_replication_role, подобное тому, что описано выше применительно к триггерам.
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 WITHOUT OIDS#Обеспечивающий обратную совместимость синтаксис удаления системного столбца
oid. Так как добавить системные столбцыoidтеперь невозможно, это указание фактически не действует.SET ACCESS METHOD#Эта форма изменяет метод доступа к таблице, переписывая её с использованием указанного метода доступа. Если указать
DEFAULT, будет выбран метод, заданный в конфигурационном параметре default_table_access_method. За дополнительными сведениями обратитесь к Главе 59.При этом в секционированной таблице данных для перезаписи нет, однако созданные позже секции будут иметь значение метода доступа по умолчанию, пока их не перезапишут с использованием предложения
USING. Если указатьDEFAULT, ранее установленное значение удалится, и в результате новые секции будут использовать метод по умолчанию, заданный вdefault_table_access_method.SET TABLESPACE#Эта форма меняет табличное пространство таблицы на заданное и перемещает файлы данных, связанные с таблицей, в новое пространство. Индексы таблицы, если они имеются, не перемещаются; однако их можно переместить отдельно дополнительными командами
SET TABLESPACE. В секционированной таблице при этом ничего не перемещается, но секции, созданные впоследствии с указаниемCREATE TABLE PARTITION OF, будут использовать это табличное пространство (если только оно не будет переопределено предложениемTABLESPACE).Форма
ALL IN TABLESPACEпозволяет перенести в другое табличное пространство все таблицы текущей базы данных в текущем пространстве, при этом она сначала блокирует все таблицы, а затем переносит каждую из них. Эта форма также поддерживает предложениеOWNED BY, с которым перемещаются только таблицы указанных владельцев. C указаниемNOWAITкоманда завершается ошибкой, если не может получить все требуемые блокировки немедленно. Заметьте, что системные каталоги эта форма не перемещает; если требуется переместить их, следует использоватьALTER DATABASEили явные вызовыALTER TABLE. Отношенияinformation_schemaне считаются частью системных каталогов и подлежат перемещению. См. также описаниеCREATE TABLESPACE.SET { LOGGED | UNLOGGED }#Эта форма меняет характеристику журналирования таблицы, делает таблицу журналируемой/нежурналируемой, соответственно (см.
UNLOGGED). К временной таблице она неприменима.При этом также меняется режим журналирования всех последовательностей, связанных с таблицей (с её столбцами идентификаторов или столбцами serial). Однако режим журналирования таких последовательностей можно изменить и отдельно.
SET (#параметр_хранения[=значение] [, ... ] )Эта форма меняет один или несколько параметров хранения таблицы. Подробнее допустимые параметры рассмотрены в разделе Параметры хранения описания
CREATE TABLE. Заметьте, что эта команда не меняет содержимое таблицы немедленно; в зависимости от параметра может потребоваться перезаписать таблицы, чтобы получить желаемый эффект. Это можно сделать с помощью командVACUUM FULL,CLUSTERили одной из формALTER TABLE, принудительно перезаписывающих таблицу. Изменения параметров, связанных с планировщиком, вступают в силу при следующей блокировке таблицы, так что в текущих запросах они не проявляются.Данная форма затребует блокировку
SHARE UPDATE EXCLUSIVEдля изменения параметров хранения, связанных с фактором заполнения, TOAST и автоочисткой, а также параметра планировщикаparallel_workers.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. При этом список имён и типов столбцов должен точно соответствовать тому, что образует составной тип. Кроме того, таблица не должна быть потомком какой-либо другой таблицы. Эти ограничения гарантируют, что командаCREATE TABLE OFпозволит создать таблицу с таким же определением.NOT OF#Эта форма разрывает связь типизированной таблицы с её типом.
OWNER TO#Эта форма меняет владельца таблицы, последовательности, представления, материализованного представления или сторонней таблицы на заданного пользователя.
REPLICA IDENTITY#Эта форма меняет информацию, записываемую в журнал предзаписи для идентификации изменяемых или удаляемых строк. В большинстве случаев старое значение в каждом столбце записывается, только если оно отличается от нового, но значение, хранящееся отдельно, записывается всегда, даже если оно не изменилось. Данный параметр действует только при использовании логической репликации.
DEFAULT#Записываются старые значения столбцов первичного ключа, если он есть. Это режим по умолчанию для несистемных таблиц.
USING INDEX#имя_индексаЗаписываются старые значения столбцов, составляющих заданный индекс, который должен быть уникальным, не частичным, не отложенным и включать только столбцы, помеченные
NOT NULL. Если этот индекс удалён, поведение будет таким же, как в режимеNOTHING.FULL#Записываются старые значения всех столбцов в строке.
NOTHING#Информация о старой строке не записывается. Это режим по умолчанию для системных таблиц.
RENAME#Формы
RENAMEменяют имя таблицы (или индекса, последовательности, представления, материализованного представления или сторонней таблицы), имя отдельного столбца таблицы или имя ограничения таблицы. При переименовании ограничения, у которого имеется нижележащий индекс, этот индекс также переименовывается. На хранимые данные это не влияет.SET SCHEMA#Эта форма перемещает таблицу в другую схему. Вместе с таблицей перемещаются связанные с ней индексы и ограничения, а также последовательности, принадлежащие столбцам таблицы.
ATTACH PARTITION#имя_секции{ FOR VALUESуказание_границ_секции| DEFAULT }Эта форма присоединяет существующую таблицу (которая тоже может быть секционированной) в качестве секции к целевой таблице. С указанием
FOR VALUESтаблица станет секцией для определённых значений, а с указаниемDEFAULT— секцией по умолчанию. Для каждого индекса в целевой таблице будет создан соответствующий индекс в присоединяемой таблице; или, если равнозначный индекс уже существует, он будет присоединён к индексу целевой таблицы, как при выполнении командыALTER INDEX ATTACH PARTITION. Заметьте, что если существующая таблица является сторонней, в настоящее время её нельзя присоединить в качестве секции к целевой таблице, в которой имеются уникальные индексы (UNIQUE). (См. также CREATE FOREIGN TABLE.) Также для каждого существующего в целевой таблице пользовательского триггера уровня строк будет создан такой же триггер в присоединяемой таблице.Для секции, добавляемой с
FOR VALUES, используется то жеуказание_границ_секции, что и вCREATE TABLE. Это указание должно соответствовать стратегии секционирования и ключу секционирования целевой таблицы. Присоединяемая таблица должна иметь те же столбцы, что и целевая, и никаких других; более того, должны совпадать и типы столбцов. Кроме того, в ней должны быть те же ограниченияNOT NULLиCHECK, что и в целевой таблице. ОграниченияFOREIGN KEYв настоящее время не учитываются. Если какое-либо из ограниченийCHECKприсоединяемой таблицы помечено какNO INHERIT, команда выдаст ошибку; такие ограничения нужно будет пересоздать без предложенияNO INHERIT.Если новая секция является обычной таблицей, чтобы убедиться, что ни одна строка в таблице не нарушает ограничение секции, производится полное сканирование таблицы. Такого сканирования можно избежать, добавив перед выполнением этой команды в таблицу действующее ограничение
CHECK, допускающее только такие строки, которые удовлетворяют задаваемому ограничению секции. Наличие этого ограничения позволит определить, что таблицу не нужно сканировать для проверки ограничения секции. Однако это не будет работать, если какие-либо ключи секционирования являются выражениями и секция не принимает значенияNULL. При присоединении секции по списку, не принимающей значенияNULL, также добавьте ограничениеNOT NULLв столбец ключа секционирования, если это не выражение.Если новая секция является сторонней таблицей, никакая проверка, удовлетворяют ли все строки сторонней таблицы ограничению секции, не выполняется. (Обсуждение ограничений сторонней таблицы вы можете найти в CREATE FOREIGN TABLE.)
Когда у таблицы есть секция по умолчанию, у данной секции при добавлении новой меняется ограничение секции. Секция по умолчанию не может содержать строки, которые должны быть перенесены в новую секцию, поэтому она будет просканирована и проверена на предмет их отсутствия. Этого сканирования, как и сканирования новой секции, можно избежать, если определить подходящее ограничение
CHECK. Кроме того, сканирование этой секции, как и новой, всегда пропускается, когда данная секция является сторонней таблицей.Для присоединения секции затребуется блокировка
SHARE UPDATE EXCLUSIVEв родительской таблице, помимо блокировокACCESS EXCLUSIVEв присоединяемых таблицах и секции по умолчанию (при наличии).Подобные блокировки также должны устанавливаться во всех вложенных секциях, если присоединяемая таблица либо секция по умолчанию в свою очередь является секционированной таблицей. Блокировки вложенных секций можно избежать, добавив ограничение
CHECK, как это описано в Подразделе 5.12.2.2.DETACH PARTITION#имя_секции[ CONCURRENTLY | FINALIZE ]Эта форма отсоединяет заданную секцию от целевой таблицы. Отсоединяемая секция продолжит существовать как отдельная таблица, но более не будет иметь никаких связей с таблицей, от которой была отсоединена. Все индексы, которые были присоединены к индексам целевой таблицы, отсоединяются, а триггеры, созданные как копии существующих в целевой таблице, удаляются. Таблицы, ссылающиеся на секционированную таблицу через внешние ключи, блокируются в режиме
SHARE.С указанием
CONCURRENTLYэта операция выполняется с пониженным уровнем блокировок во избежание блокирования других сеансов, которые могут обращаться к данной секционированной таблице. В этом режиме отсоединение производится в двух транзакциях. В первой транзакции в родительской таблице и заданной секции устанавливается блокировкаSHARE UPDATE EXCLUSIVE, а секция помечается как отсоединяемая, после чего транзакция фиксируется; затем должны завершиться все остальные транзакции, использующие секционированную таблицу. Когда все они завершаются, вторая транзакция получает блокировкуSHARE UPDATE EXCLUSIVEдля секционированной таблицы иACCESS EXCLUSIVEдля отсоединяемой секции, после чего процесс отсоединения заканчивается. В секцию добавляется ограничениеCHECK, повторяющее ограничение секции. УказаниеCONCURRENTLYнельзя использовать в блоке транзакции, а также оно не допускается, если секционированная таблица содержит секцию по умолчанию.Указание
FINALIZEпозволяет завершить операциюDETACH CONCURRENTLY, прерванную или отменённую ранее. В один момент времени в состоянии отсоединения от некоторой секционированной таблицы может находиться не более одной секции.SPLIT PARTITION#имя_секцииINTO (PARTITIONимя_секции1{ FOR VALUESуказание_границ_секции| DEFAULT }, PARTITIONимя_секции2{ FOR VALUESуказание_границ_секции| DEFAULT } [, ...])Эта форма разделяет секцию целевой таблицы. Секционирование по хешу не поддерживается. Границы новых секций не должны пересекаться с новыми и существующими секциями (за исключением
имя_секции). Если разделённая секция была секцией по умолчанию (DEFAULT), то одна из новых секций должна также стать секцией по умолчанию. Если одна из новых или существующих секций является секцией по умолчанию (DEFAULT), то у новых секцийимя_секции1,имя_секции2и т.д. могут быть пробелы между границами с другими секциями. Если в секционированной таблице нет секции по умолчанию (DEFAULT), таковой можно назначить одну из новых секций.Если в секционированной таблице и среди новых секций нет секции по умолчанию (
DEFAULT), должны соблюдаться следующие условия: сумма границ всех новых секций (имя_секции1,имя_секции2и т.д.) должна равняться границе разделяемой секцииимя_секции. Одна из новых секцийимя_секции1,имя_секции2и т.д может иметь одинаковое имя с разделяемой секциейимя_секции(это удобно, если разделяется секция по умолчанию: после разделения остаётся секция с таким же именем). Разделять можно только простые, ещё не разделённые секции.Новые секции создаются так же, как таблицы при помощи SQL-команды
CREATE TABLE. Индексы и идентификаторы создаются после переноса данных в новые секции. Расширенная статистика не копируется из родительской таблицы в целях согласованности с командойимя_секцииN(LIKEимяINCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)CREATE TABLE PARTITION OF. Новые секции наследуют метод доступа от родительских таблиц. Если родительская таблица постоянная, то и новые секции будут созданы как постоянные. Если родительская таблица временная, то и секции будут временные. Новые секции создаются в том же табличном пространстве, что и родительские.Примечание
Данная команда получает блокировку
ACCESS EXCLUSIVE. При большой нагрузке это серьёзно ограничивает использование данной команды для работы с большими секционированными таблицами.MERGE PARTITIONS (#имя_секции1,имя_секции2[, ...]) INTOимя_секцииЭта форма объединяет несколько секций в одну секцию целевой таблицы. Секционирование по хешу не поддерживается. Если секции по умолчанию
DEFAULTнет в списке секцийимя_секции1,имя_секции2и т. д.:Для таблиц, секционируемых по диапазонам, необходимо, чтобы диапазоны секций
имя_секции1,имя_секции2и т. д. можно было объединить в один диапазон без пробелов и пересечений, иначе возникнет ошибка. Объединённый диапазон включает в себя диапазон секцииимя_секции.Для таблиц, секционируемых по спискам, списки значений всех секций
имя_секции1,имя_секции2и т.д. соединяются и формируют список значений секцииимя_секции.
Если секция по умолчанию
DEFAULTесть в списке секцийимя_секции1,имя_секции2и т. д.:Секция
имя_секциистановится секцией по умолчаниюDEFAULT.Для таблиц, секционируемых по диапазонам или спискам, диапазоны или списки значений объединённых секций могут быть любыми.
У новой секции
имя_секцииможет быть такое же имя, как у одной из объединённых секций. Объединять можно только простые, ещё не разделённые секции.Новая секция создаётся так же, как таблица при помощи SQL-команды
CREATE TABLE. Индексы и идентификаторы создаются после переноса данных в новую секцию. Расширенная статистика не копируется из родительской таблицы в целях согласованности с командойимя секции(LIKEимяINCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)CREATE TABLE PARTITION OF. Новая секция наследует метод доступа от родительских таблиц. Если родительская таблица постоянная, то и новая секция будет создана как постоянная. Если родительская таблица временная, то и секция будет временной. Новая секция создаётся в том же табличном пространстве, что и родительская таблица.Примечание
Данная команда получает блокировку
ACCESS EXCLUSIVE. При большой нагрузке это серьёзно ограничивает использование данной команды для работы с большими секционированными таблицами.
Все формы ALTER TABLE, затрагивающие одну таблицу, кроме RENAME, SET SCHEMA, ATTACH PARTITION, DETACH PARTITION, SPLIT PARTITION, а также MERGE PARTITIONS можно объединить в набор множественных изменений и применить вместе. Например, можно добавить несколько столбцов и/или изменить тип столбцов в одной команде. Это особенно полезно для больших таблиц, так как вся таблица обрабатывается за один проход.
Выполнить ALTER TABLE может только владелец соответствующей таблицы. Чтобы сменить схему или табличное пространство таблицы, необходимо также иметь право CREATE в новой схеме или табличном пространстве. Чтобы сделать таблицу потомком другой таблицы, нужно быть владельцем и родительской таблицы. Также, чтобы подсоединить таблицу к другой в качестве секции, необходимо быть владельцем подсоединяемой таблицы. Чтобы сменить владельца, необходимо иметь право SET ROLE для новой роли-владельца, а эта роль должна иметь право CREATE в схеме таблицы. (С такими ограничениями при смене владельца не происходит ничего такого, что нельзя было бы сделать, имея право удалить и вновь создать таблицу. Однако суперпользователь может сменить владельца таблицы в любом случае.) Чтобы добавить столбец, сменить тип столбца или применить предложение OF, необходимо также иметь право USAGE для соответствующего типа данных.
Параметры
IF EXISTS#Не считать ошибкой, если таблица не существует. В этом случае будет выдано замечание.
имя#Имя (возможно, дополненное схемой) существующей таблицы, подлежащей изменению. Если перед именем таблицы указано
ONLY, изменяется только заданная таблица. БезONLYизменяется и заданная таблица, и все её потомки (если таковые есть). После имени таблицы можно также добавить необязательное указание*, чтобы явно обозначить, что изменению подлежат все дочерние таблицы.имя_столбца#Имя нового или существующего столбца.
новое_имя_столбца#Новое имя существующего столбца.
новое_имя#Новое имя таблицы.
тип_данных#Тип данных нового столбца или новый тип данных существующего столбца.
ограничение_таблицы#Новое ограничение таблицы.
имя_ограничения#Имя нового или существующего ограничения.
CASCADE#Автоматически удалять объекты, зависящие от удаляемого столбца или ограничения (например, представления, содержащие этот столбец), и, в свою очередь, все зависящие от них объекты (см. Раздел 5.15).
RESTRICT#Отказать в удалении столбца или ограничения, если существуют зависящие от них объекты. Это поведение по умолчанию.
имя_триггера#Имя включаемого или отключаемого триггера.
ALL#Отключить или включить все триггеры, принадлежащие таблице. (Для этого требуются права суперпользователя, если в числе этих триггеров оказываются сгенерированные внутрисистемные триггеры исключений, например те, что реализуют ограничения внешнего ключа или отложенные ограничения уникальности и исключений.)
USER#Отключить или включить все триггеры, принадлежащие таблице, за исключением сгенерированных внутрисистемных триггеров исключений, например, тех, что реализуют ограничения внешнего ключа или отложенные ограничения уникальности и исключений.
имя_индекса#Имя существующего индекса.
параметр_хранения#Имя параметра хранения таблицы
значение#Новое значение параметра хранения таблицы. Это может быть число или строка, в зависимости от параметра.
таблица_родитель#Родительская таблица, с которой будет установлена или разорвана связь данной таблицы.
новый_владелец#Имя пользователя, назначаемого новым владельцем таблицы.
новый_метод_доступа#Имя метода доступа, который будет использоваться для таблицы после её преобразования.
новое_табл_пространство#Имя табличного пространства, в которое будет перемещена таблица.
новая_схема#Имя схемы, в которую будет перемещена таблица.
имя_секции#Имя таблицы, присоединяемой в качестве новой секции, или наоборот, отсоединяемой от данной таблицы, или имя разделяемой секции, или имя новой объединяемой секции.
указание_границ_секции#Указание границ для новой секции. Подробнее синтаксис этого указания рассматривается в описании CREATE TABLE.
Замечания #
Ключевое слово COLUMN не несёт смысловой нагрузки и может быть опущено.
Когда конструкция ADD COLUMN добавляет столбец и для него задано неизменчивое выражение DEFAULT, значение по умолчанию вычисляется во время выполнения оператора и сохраняется в метаданных таблицы. Это значение затем будет использовано в качестве содержимого столбца для всех существующих строк. Если указание DEFAULT отсутствует, столбец будет содержать NULL. В обоих случаях перезапись таблицы не требуется.
Добавление столбца с изменчивым выражением DEFAULT или изменение типа существующего столбца влечёт за собой перезапись всей таблицы и её индексов. Но возможно исключение при смене типа существующего столбца: если предложение USING не меняет содержимое столбца и старый тип двоично приводится к новому или является неограниченным доменом поверх нового типа, то перезапись таблицы не требуется. Тем не менее, индексы нужно перестраивать в любом случае, кроме случаев, когда система может определить, что новый индекс будет логически эквивалентен существующему. Например, когда меняется правило сортировки для столбца, индекс требуется перестроить всегда, так как новый порядок сортировки может быть другим. Однако если правило сортировки не меняется, тип столбца можно поменять с text на varchar (или наоборот) без перестроения индексов, так как эти типы данных сортируются одинаково. Перестроение больших таблиц и/или их индексов может быть весьма длительной процедурой, которая при этом временно требует вдвое больше места на диске.
Добавление ограничений CHECK или NOT NULL влечёт за собой необходимость просканировать таблицу, чтобы проверить, что все существующие строки удовлетворяют ограничению, но перезаписывать таблицу при этом не требуется.
Подобным образом, при присоединении новой секции может производиться её сканирование для проверки, соответствуют ли существующие строки ограничению секции.
Возможность объединения множества изменений в одну команду ALTER TABLE полезна в основном тем, что позволяет совместить сканирования и перезаписи таблицы, требуемые этим операциям, и выполнить их за один проход.
Сканирование большой таблицы для проверки нового внешнего ключа или ограничения-проверки может занять длительное время и будет препятствовать внесению других изменений до фиксирования команды ALTER TABLE ADD CONSTRAINT. Основное предназначение указания NOT VALID при добавлении ограничения состоит в уменьшении влияния этой операции на параллельные изменения данных. С указанием NOT VALID команда ADD CONSTRAINT не сканирует таблицу и может быть зафиксирована немедленно. После этого можно выполнить команду VALIDATE CONSTRAINT, которая проверит все существующие строки на соответствие ограничению. Эта команда не будет препятствовать параллельным изменениям, так как ей известно, что в других транзакциях для добавляемых или изменяемых строк ограничение уже будет действовать; проверить нужно только уже существующие строки. Таким образом, для этой проверки в таблице затребуется только блокировка SHARE UPDATE EXCLUSIVE. (Если ограничение является внешним ключом, то в целевой таблице этого ключа также затребуется блокировка ROW SHARE.) Помимо оптимизации параллельной работы, указание NOT VALID и предложение VALIDATE CONSTRAINT полезно в случаях, когда заведомо известно, что в таблице есть строки, нарушающие ограничения. После создания ограничения добавить новые недопустимые строки будет невозможно, а все существующие проблемы могут разрешаться в удобное время, пока VALIDATE CONSTRAINT не выполнится успешно.
Форма DROP COLUMN не удаляет столбец физически, а просто делает его невидимым для операций SQL. При последующих операциях добавления или изменения в этот столбец будет записываться значение NULL. Таким образом, удаление столбца выполняется быстро, но при этом размер таблицы на диске не уменьшается, так как пространство, занимаемое удалённым столбцом, не высвобождается. Это пространство будет освобождено со временем, по мере изменения существующих строк.
Чтобы принудительно высвободить пространство, занимаемое столбцом, который был удалён, можно выполнить одну из форм ALTER TABLE, производящих перезапись всей таблицы. В результате все строки будут воссозданы так, что в удалённом столбце будет содержаться NULL.
Перезаписывающие формы ALTER TABLE небезопасны с точки зрения MVCC. После перезаписи таблица будет выглядеть пустой для параллельных транзакций, если они работают со снимком, полученным до момента перезаписи. За подробностями обратитесь к Разделу 13.6.
В указании USING предложения SET DATA TYPE на самом деле можно записать выражение со старыми значениями строки; то есть, оно может ссылаться как на преобразуемые столбцы, так и на другие. Это позволяет записывать в SET DATA TYPE очень общие преобразования данных. Ввиду такой гибкости, выражение USING не применяется к значению по умолчанию данного столбца (если таковое есть); результат может быть не константным выражением, что требуется для значения по умолчанию. Это означает, что в случае отсутствия явного приведения или присваивания старого типа новому, SET DATA TYPE может не справиться с преобразованием значения по умолчанию, несмотря на то, что применяется предложение USING. В этих случаях нужно удалить значение по умолчанию с помощью DROP DEFAULT, выполнить ALTER TYPE, а затем с помощью SET DEFAULT задать новое подходящее значение по умолчанию. Подобные соображения применимы и в отношении индексов и ограничений с этим столбцом.
Если у таблицы имеются дочерние таблицы, то добавлять, переименовывать столбцы или менять их тип в родительской таблице, не повторяя ту же операцию в дочерних таблицах, нельзя. Это правило гарантирует, что столбцы в дочерних таблицах всегда соответствуют родительской. Подобным образом, нельзя переименовать ограничение CHECK в родительской таблице, не переименовывая его во всех дочерних таблицах, что тоже гарантирует соответствие всех ограничений CHECK. (Однако это не касается ограничений, построенных на индексах.) И так как выборка из родительской таблицы влечёт за собой выборку из всех потомков, ограничение родителя не может быть помечено как действующее, если оно также не является действующим в потомках. Во всех этих случаях команда ALTER TABLE ONLY не будет выполнена.
Рекурсивная операция DROP COLUMN удалит столбец из дочерней таблицы, только если этот столбец не наследуется от каких-то других родителей и никогда не был определён в дочерней таблице независимо. Нерекурсивная операция DROP COLUMN (т. е., ALTER TABLE ONLY ... DROP COLUMN) никогда не удаляет унаследованные столбцы; вместо этого она помечает их как независимо определённые, а не наследуемые. С секционированной таблицей нерекурсивная команда DROP COLUMN выдаст ошибку, так как все секции таблицы должны содержать те же столбцы, что и главная таблица.
Действия для столбцов идентификации (ADD GENERATED, SET и т. д., DROP IDENTITY), а также действия CLUSTER, OWNER и TABLESPACE, никогда не распространяются рекурсивно на дочерние таблицы; то есть они всегда выполняются так, как будто указано ONLY. Действия, влияющие на состояния триггеров, распространяются рекурсивно на секции секционированных таблиц (если не указано ONLY), но не на потомков в традиционной иерархии наследования. Операция добавления ограничения выполняется рекурсивно только для ограничений CHECK, не помеченных как NO INHERIT.
Какие-либо изменения таблиц системного каталога не допускаются.
За более подробным описанием допустимых параметров обратитесь к CREATE TABLE. Дополнительно о наследовании можно узнать в Главе 5.
Примеры
Добавление в таблицу столбца типа varchar:
ALTER TABLE distributors ADD COLUMN address varchar(30);
При этом во всех существующих строках таблицы новый столбец получит значение null.
Добавление столбца со значением по умолчанию (отличным от NULL):
ALTER TABLE measurements ADD COLUMN mtime timestamp with time zone DEFAULT now();
В существующих строках новый столбец будет содержать текущее время, а в добавляемых впоследствии строках — время их добавления.
Добавление столбца и заполнение его значением, отличным от значения по умолчанию, которое будет использоваться в дальнейшем:
ALTER TABLE transactions ADD COLUMN status varchar(30) DEFAULT 'old', ALTER COLUMN status SET default 'current';
Существующие строки будут заполнены значением old, но для последующих команд значением по умолчанию будет current. Результат этих двух указаний в одной команде будет таким же, как и при выполнении их в отдельных командах ALTER TABLE.
Удаление столбца из таблицы:
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;Присоединение секции к таблице, секционируемой по диапазонам:
ALTER TABLE measurement
ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');Присоединение секции к таблице, секционируемой по списку:
ALTER TABLE cities
ATTACH PARTITION cities_ab FOR VALUES IN ('a', 'b');Присоединение секции к таблице, секционируемой по хешу:
ALTER TABLE orders
ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3);Присоединение секции по умолчанию к секционированной таблице:
ALTER TABLE cities
ATTACH PARTITION cities_partdef DEFAULT;Удаление секции из секционированной таблицы:
ALTER TABLE measurement
DETACH PARTITION measurement_y2015m12;Разделение секции таблицы, секционированной по диапазонам:
ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2023 INTO
(PARTITION sales_feb2023 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'),
PARTITION sales_mar2023 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'),
PARTITION sales_apr2023 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01'));Разделение секции таблицы, секционированной по списку:
ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
(PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));Объединение нескольких секций в одну в целевой таблице:
ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central)
INTO sales_all;Совместимость
Формы ADD (без USING INDEX), DROP [COLUMN], DROP IDENTITY, RESTART, SET DEFAULT, SET DATA TYPE (без USING), SET GENERATED и SET соответствуют стандарту SQL. Другие формы являются расширениями стандарта SQL, реализованными в Postgres Pro. Кроме того, расширением является возможность указать в одной команде параметр_последовательностиALTER TABLE несколько операций изменения.
ALTER TABLE DROP COLUMN позволяет удалить единственный столбец таблицы и оставить таблицу без столбцов. Это является расширением стандарта SQL, который не допускает существование таблиц с нулём столбцов.