Spec-Zone.ru › MySQL 5.7

13.1.8 Заявление ALTER TABLE

  • 13.1.8.1 Операции ALTER TABLE для разделов
  • 13.1.8.2 ALTER TABLE и сгенерированные столбцы
  • 13.1.8.3 Примеры ALTER TABLE
ALTER TABLE tbl_name
    [alter_option [, alter_option] ...]
    [partition_options]

alter_option: {
    table_options
  | ADD [COLUMN] col_name column_definition
        [FIRST | AFTER col_name]
  | ADD [COLUMN] (col_name column_definition,...)
  | ADD {INDEX | KEY} [index_name]
        [index_type] (key_part,...) [index_option] ...
  | ADD {FULLTEXT | SPATIAL} [INDEX | KEY] [index_name]
        (key_part,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]] PRIMARY KEY
        [index_type] (key_part,...)
        [index_option] ...
  | ADD [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY]
        [index_name] [index_type] (key_part,...)
        [index_option] ...
  | ADD [CONSTRAINT [symbol]] FOREIGN KEY
        [index_name] (col_name,...)
        reference_definition
  | ADD CHECK (expr)
  | ALGORITHM [=] {DEFAULT | INPLACE | COPY}
  | ALTER [COLUMN] col_name {
        SET DEFAULT {literal | (expr)}
      | DROP DEFAULT
    }
  | CHANGE [COLUMN] old_col_name new_col_name column_definition
        [FIRST | AFTER col_name]
  | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]
  | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
  | {DISABLE | ENABLE} KEYS
  | {DISCARD | IMPORT} TABLESPACE
  | DROP [COLUMN] col_name
  | DROP {INDEX | KEY} index_name
  | DROP PRIMARY KEY
  | DROP FOREIGN KEY fk_symbol
  | FORCE
  | LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
  | MODIFY [COLUMN] col_name column_definition
        [FIRST | AFTER col_name]
  | ORDER BY col_name [, col_name] ...
  | RENAME {INDEX | KEY} old_index_name TO new_index_name
  | RENAME [TO | AS] new_tbl_name
  | {WITHOUT | WITH} VALIDATION
}

partition_options:
    partition_option [partition_option] ...

partition_option: {
    ADD PARTITION (partition_definition)
  | DROP PARTITION partition_names
  | DISCARD PARTITION {partition_names | ALL} TABLESPACE
  | IMPORT PARTITION {partition_names | ALL} TABLESPACE
  | TRUNCATE PARTITION {partition_names | ALL}
  | COALESCE PARTITION number
  | REORGANIZE PARTITION partition_names INTO (partition_definitions)
  | EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH | WITHOUT} VALIDATION]
  | ANALYZE PARTITION {partition_names | ALL}
  | CHECK PARTITION {partition_names | ALL}
  | OPTIMIZE PARTITION {partition_names | ALL}
  | REBUILD PARTITION {partition_names | ALL}
  | REPAIR PARTITION {partition_names | ALL}
  | REMOVE PARTITIONING
  | UPGRADE PARTITIONING
}

key_part:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH}

index_option: {
    KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
}

table_options:
    table_option [[,] table_option] ...

table_option: {
    AUTO_INCREMENT [=] value
  | AVG_ROW_LENGTH [=] value
  | [DEFAULT] CHARACTER SET [=] charset_name
  | CHECKSUM [=] {0 | 1}
  | [DEFAULT] COLLATE [=] collation_name
  | COMMENT [=] 'string'
  | COMPRESSION [=] {'ZLIB' | 'LZ4' | 'NONE'}
  | CONNECTION [=] 'connect_string'
  | {DATA | INDEX} DIRECTORY [=] 'absolute path to directory'
  | DELAY_KEY_WRITE [=] {0 | 1}
  | ENCRYPTION [=] {'Y' | 'N'}
  | ENGINE [=] engine_name
  | INSERT_METHOD [=] { NO | FIRST | LAST }
  | KEY_BLOCK_SIZE [=] value
  | MAX_ROWS [=] value
  | MIN_ROWS [=] value
  | PACK_KEYS [=] {0 | 1 | DEFAULT}
  | PASSWORD [=] 'string'
  | ROW_FORMAT [=] {DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT}
  | STATS_AUTO_RECALC [=] {DEFAULT | 0 | 1}
  | STATS_PERSISTENT [=] {DEFAULT | 0 | 1}
  | STATS_SAMPLE_PAGES [=] value
  | TABLESPACE tablespace_name [STORAGE {DISK | MEMORY}]
  | UNION [=] (tbl_name[,tbl_name]...)
}

partition_options:
    (see CREATE TABLE options)

ALTER TABLE изменяет структуру таблицы. Например, вы можете добавлять или удалять столбцы, создавать или удалять индексы, изменять тип существующих столбцов или переименовывать столбцы или саму таблицу. Также можно изменить характеристики, такие как движок хранения, используемый для таблицы, или комментарий к таблице.

  • Для использования ALTER TABLE, вам необходимы права ALTER, CREATE и INSERT для таблицы. Переименование таблицы требует ALTER и DROP на старой таблице, ALTER, CREATE и INSERT на новой таблице.

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

  • Синтаксис многих разрешенных изменений похож на предложения из оператора CREATE TABLE. column_definition предложения используют тот же синтаксис для ADD и CHANGE, что и для CREATE TABLE. Более подробная информация приведена в Разделе 13.1.18, «Заявление CREATE TABLE».

  • Слово COLUMN является необязательным и может быть опущено.

  • Несколько ADD, ALTER, DROP и CHANGE предложений разрешены в одном операторе ALTER TABLE, разделенных запятыми. Это расширение MySQL для стандартного SQL, которое допускает только по одному предложению каждого типа в одном операторе ALTER TABLE. Например, чтобы удалить несколько столбцов в одном операторе, сделайте так:

    ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
    
  • Если движок хранения не поддерживает попытку операции ALTER TABLE, может появиться предупреждение. Такие предупреждения можно отобразить с помощью SHOW WARNINGS. См. Раздел 13.7.5.40, «Заявление SHOW WARNINGS». Сведения о устранении неполадок с ALTER TABLE см. в Разделе B.3.6.1, «Проблемы с ALTER TABLE».

  • Дополнительную информацию о сгенерированных столбцах см. в Разделе 13.1.8.2, «ALTER TABLE и сгенерированные столбцы».

  • Примеры использования см. в Разделе 13.1.8.3, «Примеры ALTER TABLE».

  • С помощью функции C API можно узнать, сколько строк было скопировано оператором ALTER TABLE. См. .

Существуют и другие аспекты оператора ALTER TABLE, которые описаны в следующих разделах этого раздела:

  • Параметры таблицы

  • Производительность и требования к пространству

  • Управление одновременностью

  • Добавление и удаление столбцов

  • Переименование, переопределение и переупорядочивание столбцов

  • Первичные ключи и индексы

  • Внешние ключи и другие ограничения

  • Изменение набора символов

  • Удаление и импорт табличных пространств InnoDB

  • Порядок строк для таблиц MyISAM

  • Параметры разбиения

Параметры таблицы

table_options обозначает параметры таблицы, которые можно использовать в операторе CREATE TABLE, такие как ENGINE, AUTO_INCREMENT, AVG_ROW_LENGTH, MAX_ROWS, ROW_FORMAT или TABLESPACE.

Описания всех параметров таблицы см. в Разделе 13.1.18, «Заявление CREATE TABLE». Однако, ALTER TABLE игнорирует DATA DIRECTORY и INDEX DIRECTORY, если они указаны как параметры таблицы. ALTER TABLE разрешает их только в качестве параметров разбиения и, начиная с MySQL 5.7.17, требует права FILE.

Использование параметров таблицы с оператором ALTER TABLE обеспечивает удобный способ изменения характеристик одной таблицы. Например:

  • Если t1 в настоящее время не является таблицей InnoDB, данное утверждение изменяет её движок хранения на InnoDB:

    ALTER TABLE t1 ENGINE = InnoDB;
    
    • См. раздел 14.6.1.5, «Преобразование таблиц из MyISAM в InnoDB» для учёта особенностей при переключении таблиц на движок хранения InnoDB.

    • При указании условия ENGINE, ALTER TABLE перестраивает таблицу. Это справедливо даже в том случае, если таблица уже имеет указанный движок хранения.

    • Выполнение ALTER TABLE tbl_name ENGINE=INNODB над существующей таблицей InnoDB выполняет операцию “null” ALTER TABLE, которая может использоваться для дефрагментации таблицы InnoDB, как описано в разделе 14.12.4, «Дефрагментация таблицы». Выполнение ALTER TABLE tbl_name FORCE над таблицей InnoDB выполняет ту же функцию.

    • ALTER TABLE tbl_name ENGINE=INNODB и ALTER TABLE tbl_name FORCE используют онлайн DDL. Более подробную информацию см. в разделе 14.13, «InnoDB и онлайн DDL».

    • Результат попытки изменения движка хранения таблицы зависит от доступности требуемого движка хранения и настройки SQL-режима NO_ENGINE_SUBSTITUTION, как описано в разделе 5.1.10, «Серверные SQL-режимы».

    • Для предотвращения непреднамеренной потери данных, ALTER TABLE нельзя использовать для изменения движка хранения таблицы на MERGE или BLACKHOLE.

  • Чтобы изменить таблицу InnoDB для использования сжатого формата хранения строк:

    ALTER TABLE t1 ROW_FORMAT = COMPRESSED;
    
  • Чтобы включить или отключить шифрование для таблицы InnoDB в файловой табличной области:

    ALTER TABLE t1 ENCRYPTION='Y';
    ALTER TABLE t1 ENCRYPTION='N';
    

    Для использования опции ENCRYPTION необходимо установить и настроить плагин хранилища ключей. Дополнительную информацию см. в разделе 14.14, «Шифрование данных InnoDB в постоянной памяти».

    Опция ENCRYPTION поддерживается только движком хранения InnoDB; поэтому она работает только если таблица уже использует InnoDB (и вы не меняете движок хранения таблицы) или если в операторе ALTER TABLE также указано ENGINE=InnoDB. В противном случае оператор отклоняется.

  • Чтобы сбросить текущее значение автоинкремента:

    ALTER TABLE t1 AUTO_INCREMENT = 13;
    

    Вы не можете сбросить счётчик до значения, меньшего или равного текущему используемому значению. Для обоих InnoDB и MyISAM, если значение меньше или равно максимальному значению в столбце AUTO_INCREMENT, значение сбрасывается до текущего максимального значения столбца AUTO_INCREMENT плюс единица.

  • Чтобы изменить кодировку по умолчанию для таблицы:

    ALTER TABLE t1 CHARACTER SET = utf8;
    

    См. также Изменение кодировки.

  • Чтобы добавить (или изменить) комментарий к таблице:

    ALTER TABLE t1 COMMENT = 'New table comment';
    
  • Используйте ALTER TABLE с опцией TABLESPACE для перемещения таблиц InnoDB между существующими таблицами, таблицами и . См. Перемещение таблиц между таблицами с помощью ALTER TABLE.

    • Операции ALTER TABLE ... TABLESPACE всегда приводят к полной перестройке таблицы, даже если атрибут TABLESPACE не изменился по сравнению с предыдущим значением.

    • Синтаксис ALTER TABLE ... TABLESPACE не поддерживает перемещение таблицы из временной табличной области в постоянную табличную область.

    • Оператор DATA DIRECTORY, поддерживаемый оператором CREATE TABLE ... TABLESPACE, не поддерживается оператором ALTER TABLE ... TABLESPACE и игнорируется при указании.

    • Дополнительную информацию о возможностях и ограничениях опции TABLESPACE см. в CREATE TABLE.

  • MySQL NDB Cluster 7.5.2 и более поздние версии поддерживают настройку опций NDB_TABLE для управления балансом разделов таблицы (тип фрагментов), возможностью чтения из любого реплики, полным репликацией или любой комбинацией из них в качестве части комментария к таблице для оператора ALTER TABLE таким же образом, как и для CREATE TABLE, как показано в этом примере:

    ALTER TABLE t1 COMMENT = "NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RA_BY_NODE";
    

    Также можно настроить опции NDB_COMMENT для столбцов таблиц NDB в рамках оператора ALTER TABLE, как в этом примере:

    ALTER TABLE t1
      CHANGE COLUMN c1 c1 BLOB
        COMMENT = 'NDB_COLUMN=MAX_BLOB_PART_SIZE';
    

    Учитывайте, что ALTER TABLE ... COMMENT ... отбрасывает любой существующий комментарий к таблице. Дополнительную информацию и примеры см. в разделе «Установка опций NDB_TABLE».

Для проверки того, что опции таблицы были изменены как нужно, используйте SHOW CREATE TABLE или запросите таблицу схемы данных TABLES.

Производительность и требования к объёму памяти

Операции ALTER TABLE обрабатываются с помощью одного из следующих алгоритмов:

  • COPY: Операции выполняются на копии исходной таблицы, и данные таблицы копируются из исходной таблицы в новую таблицу строка за строкой. Одновременные операции DML запрещены.

  • INPLACE: Операции избегают копирования данных таблицы, но могут перестроить таблицу на месте. В фазах подготовки и выполнения операции может кратковременно захватываться эксклюзивная метаданные блокировка таблицы. Как правило, поддерживаются одновременные операции DML.

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

  • COPY: NDB создаёт копию таблицы и изменяет её; обработчик NDB Cluster затем копирует данные между старой и новой версиями таблицы. Впоследствии NDB удаляет старую таблицу и переименовывает новую.

    Это иногда также называется “копированием” или “офлайн” ALTER TABLE.

  • INPLACE: Узлы данных выполняют необходимые изменения; обработчик NDB Cluster не копирует данные и не участвует в иных действиях.

    Это иногда также называется “не-копированием” или “онлайн” ALTER TABLE.

См. раздел 21.6.12, «Операции в режиме реального времени с ALTER TABLE в NDB Cluster» для получения дополнительной информации.

Оператор ALGORITHM необязателен. Если оператор ALGORITHM опущен, MySQL использует ALGORITHM=INPLACE для движков хранения и ALTER TABLE операторов, которые его поддерживают. В противном случае используется ALGORITHM=COPY.

Указание оператора ALGORITHM требует использования указанного алгоритма для операторов и движков хранения, которые его поддерживают, или отклонения операции с ошибкой в противном случае. Указание ALGORITHM=DEFAULT эквивалентно опущению оператора ALGORITHM.

Операции ALTER TABLE, использующие алгоритм COPY, ожидают завершения других операций, изменяющих таблицу. После применения изменений к копии таблицы, данные копируются, исходная таблица удаляется, а копия таблицы переименовывается в имя исходной таблицы. Пока выполняется операция ALTER TABLE, исходная таблица доступна для чтения другими сеансами (за исключением указанного случая). Обновления и записи в таблицу, начатые после начала операции ALTER TABLE, приостанавливаются до готовности новой таблицы, после чего автоматически перенаправляются в новую таблицу. Временная копия таблицы создаётся в каталоге базы данных исходной таблицы, если это не операция RENAME TO, которая перемещает таблицу в базу данных, расположенную в другом каталоге.

Исключение, о котором говорилось ранее, заключается в том, что ALTER TABLE блокирует чтение (а не только запись) в тот момент, когда оно готово установить новую версию таблицы .frm файл, удалить старый файл и очистить устаревшие структуры таблиц из кэшей таблицы и определения таблицы. В этот момент он должен получить эксклюзивную блокировку. Для этого он ожидает завершения текущих операций чтения и блокирует новые операции чтения и записи.

Операция ALTER TABLE, использующая алгоритм COPY, предотвращает одновременные операции DML. Одновременные запросы все еще разрешены. То есть операция копирования таблицы всегда включает в себя, по крайней мере, ограничения по одновременности, как у LOCK=SHARED (разрешены запросы, но не DML). Вы можете дополнительно ограничить одновременность для операций, поддерживающих предложение LOCK, указав LOCK=EXCLUSIVE, что предотвращает DML и запросы. Дополнительную информацию см. в разделе Управление одновременностью.

Чтобы принудительно использовать алгоритм COPY для операции ALTER TABLE, которая в противном случае его не использует, включите системную переменную old_alter_table или укажите ALGORITHM=COPY. Если есть конфликт между настройкой old_alter_table и предложением ALGORITHM со значением, отличным от DEFAULT, предложение ALGORITHM имеет приоритет.

Для таблиц InnoDB операция ALTER TABLE, использующая алгоритм COPY для таблицы, находящейся в табличном пространстве, может увеличить занимаемое пространство табличным пространством. Такие операции требуют столько дополнительного пространства, сколько данных в таблице плюс индексы. Для таблицы, находящейся в общем табличном пространстве, дополнительное пространство, используемое во время операции, не возвращается операционной системе, как это происходит для таблицы, находящейся в табличном пространстве.

Дополнительную информацию о требованиях к пространству для онлайн-операций DDL см. в разделе Раздел 14.13.3, «Требования к онлайн-пространству DDL».

Операции ALTER TABLE, которые поддерживают алгоритм INPLACE, включают:

  • Операции ALTER TABLE, поддерживаемые функцией InnoDB. См. Раздел 14.13.1, «Онлайн-операции DDL».

  • Переименование таблицы. MySQL переименовывает файлы, соответствующие таблице tbl_name, без создания копии. (Также можно использовать оператор RENAME TABLE для переименования таблиц. См. Раздел 13.1.33, «Оператор RENAME TABLE».) Предоставленные разрешения для переименованной таблицы не мигрируются в новое имя. Их необходимо изменить вручную.

  • Операции, которые изменяют только метаданные таблицы. Эти операции выполняются немедленно, поскольку сервер изменяет только файл .frm таблицы, не затрагивая содержимое таблицы. К операциям, воздействующим только на метаданные, относятся:

    • Переименование столбца.

    • Изменение значения по умолчанию столбца (кроме таблиц NDB).

    • Изменение определения столбца типа ENUM или SET, добавление новых элементов перечисления или множества в конец списка допустимых значений элементов, при условии, что размер хранения типа данных не изменится. Например, добавление элемента в столбец типа SET, который имеет 8 элементов, изменяет необходимое хранилище на значение с 1 байта до 2 байт; это требует копирования таблицы. Добавление элементов в середину списка приводит к переиндексации существующих элементов, что требует копирования таблицы.

  • Переименование индекса.

  • Добавление или удаление вторичного индекса для таблиц InnoDB и NDB. См. Раздел 14.13, «InnoDB и онлайн-DDL».

  • Для таблиц NDB, операции, добавляющие и удаляющие индексы по столбцам переменной длины. Эти операции происходят онлайн, без копирования таблицы и без блокировки одновременных операций DML на большей части их продолжительности. См. Раздел 21.6.12, «Онлайн-операции с ALTER TABLE в NDB Cluster».

Операции ALTER TABLE обновляют временные столбцы MySQL 5.5 до формата 5.6 для операций ADD COLUMN, CHANGE COLUMN, MODIFY COLUMN, ADD INDEX и FORCE. Это преобразование нельзя выполнить с помощью алгоритма INPLACE, потому что таблица должна быть перестроена, поэтому указание ALGORITHM=INPLACE в этих случаях приводит к ошибке. При необходимости укажите ALGORITHM=COPY.

Если операция ALTER TABLE на многостолбцовом индексе, используемом для разбиения таблицы по KEY, изменяет порядок столбцов, её можно выполнить только с помощью ALGORITHM=COPY.

Предложения WITHOUT VALIDATION и WITH VALIDATION влияют на то, выполняет ли ALTER TABLE операцию на месте для изменений. См. Раздел 13.1.8.2, «ALTER TABLE и сгенерированные столбцы».

NDB Cluster ранее поддерживал онлайн-операции ALTER TABLE, используя ключевые слова ONLINE и OFFLINE. Эти ключевые слова больше не поддерживаются; их использование приводит к синтаксической ошибке. MySQL NDB Cluster 7.5 (и более поздние версии) поддерживает онлайн-операции, используя тот же синтаксис ALGORITHM=INPLACE, что и стандартный MySQL Server. NDB не поддерживает изменение табличного пространства онлайн. См. Раздел 21.6.12, «Онлайн-операции с ALTER TABLE в NDB Cluster» для получения дополнительной информации.

ALTER TABLE с DISCARD ... PARTITION ... TABLESPACE или IMPORT ... PARTITION ... TABLESPACE не создаёт временных таблиц или временных файлов разбиений.

ALTER TABLE с ADD PARTITION, DROP PARTITION, COALESCE PARTITION, REBUILD PARTITION или REORGANIZE PARTITION не создаёт временных таблиц (за исключением использования с таблицами NDB); однако эти операции могут и создают временные файлы разбиений.

Операции ADD или DROP для разбиений RANGE или LIST — это немедленные или почти немедленные операции. Операции ADD или COALESCE для разбиений HASH или KEY копируют данные между всеми разбиениями, если не было использовано LINEAR HASH или LINEAR KEY; это по сути то же самое, что создание новой таблицы, хотя операция ADD или COALESCE выполняется разбиение за разбиением. Операции REORGANIZE копируют только изменённые разбиения и не трогают неизменённые.

Для таблиц MyISAM можно ускорить пересоздание индексов (самой медленной части процесса изменения) путём установки системной переменной myisam_sort_buffer_size на высокое значение.

Управление одновременностью

Для операций ALTER TABLE, которые это поддерживают, можно использовать предложение LOCK для управления уровнем одновременного чтения и записи в таблице во время её изменения. Указание значения, отличного от значения по умолчанию для этого предложения, позволяет потребовать определённого уровня одновременного доступа или эксклюзивности во время операции изменения и останавливает операцию, если требуемая степень блокировки недоступна. Параметры предложения LOCK следующие:

  • LOCK = DEFAULT

    Максимальный уровень одновременности для данного предложения ALGORITHM (если таковое имеется) и операции ALTER TABLE: Разрешить одновременные чтение и запись, если поддерживается. Если нет, разрешить одновременное чтение, если поддерживается. Если нет, применить эксклюзивный доступ.

  • LOCK = NONE

    Если поддерживается, разрешить одновременные чтение и запись. В противном случае произойдёт ошибка.

  • LOCK = SHARED

    Если поддерживается, разрешить одновременное чтение, но заблокировать запись. Записи блокируются даже если одновременные записи поддерживаются хранилищем для данного предложения ALGORITHM (если таковое имеется) и операции ALTER TABLE. Если одновременное чтение не поддерживается, произойдёт ошибка.

  • LOCK = EXCLUSIVE

    Применить эксклюзивный доступ. Это делается даже если одновременные чтение/запись поддерживаются хранилищем для данного предложения ALGORITHM (если таковое имеется) и операции ALTER TABLE.

Добавление и удаление столбцов

Используйте ADD для добавления новых столбцов в таблицу и DROP для удаления существующих столбцов. DROP col_name — это расширение MySQL к стандартному SQL.

Для добавления столбца в определённой позиции строки таблицы используйте FIRST или AFTER col_name. По умолчанию столбец добавляется в конец.

Если таблица содержит только один столбец, его нельзя удалить. Если вы хотите удалить таблицу, используйте оператор DROP TABLE вместо этого.

Если столбцы удаляются из таблицы, они также удаляются из любого индекса, частью которого они являются. Если все столбцы, составляющие индекс, удаляются, то индекс также удаляется.

id="alter-table-redefine-column">Переименование, переопределение и переупорядочивание столбцов

Операторы CHANGE, MODIFY и ALTER позволяют изменять имена и определения существующих столбцов. Они обладают следующими сравнительными характеристиками:

  • CHANGE:

    • Может переименовать столбец и изменить его определение, или оба.

    • Обладает большей функциональностью, чем MODIFY, но за счёт удобства для некоторых операций. CHANGE требует указания имени столбца дважды, если имя не изменяется.

    • С помощью FIRST или AFTER можно переупорядочить столбцы.

  • MODIFY:

    • Может изменить определение столбца, но не его имя.

    • Более удобен, чем CHANGE, для изменения определения столбца без переименования.

    • С помощью FIRST или AFTER можно переупорядочить столбцы.

  • ALTER: Используется только для изменения значения по умолчанию столбца.

CHANGE — расширение MySQL для стандартного SQL. MODIFY — расширение MySQL для совместимости с Oracle.

Для изменения имени и определения столбца используйте CHANGE, указав старое и новое имена, а также новое определение. Например, чтобы переименовать столбец INT NOT NULL из a в b и изменить его определение на использование типа данных BIGINT, сохранив атрибут NOT NULL, сделайте следующее:

ALTER TABLE t1 CHANGE a b BIGINT NOT NULL;

Для изменения определения столбца без изменения имени используйте CHANGE или MODIFY. С помощью CHANGE синтаксис требует двух имён столбцов, поэтому необходимо указать то же имя дважды, чтобы оставить имя без изменений. Например, чтобы изменить определение столбца b, сделайте следующее:

ALTER TABLE t1 CHANGE b b INT NOT NULL;

MODIFY удобнее для изменения определения без изменения имени, поскольку требует имени столбца только один раз:

ALTER TABLE t1 MODIFY b INT NOT NULL;

Для изменения имени столбца без изменения его определения используйте CHANGE. Синтаксис требует определения столбца, поэтому, чтобы оставить определение без изменений, необходимо повторно указать текущее определение столбца. Например, чтобы переименовать столбец INT NOT NULL из b в a, сделайте следующее:

ALTER TABLE t1 CHANGE b a INT NOT NULL;

При изменении определения столбца с помощью CHANGE или MODIFY определение должно включать тип данных и все атрибуты, которые должны применяться к новому столбцу, кроме атрибутов индекса, таких как PRIMARY KEY или UNIQUE. Атрибуты, присутствующие в исходном определении, но не указанные в новом определении, не переносятся. Предположим, что столбец col1 определён как INT UNSIGNED DEFAULT 1 COMMENT 'my column', и вы изменяете столбец следующим образом, намереваясь изменить только INT на BIGINT:

ALTER TABLE t1 MODIFY col1 BIGINT;

Это утверждение изменяет тип данных с INT на BIGINT, но также удаляет атрибуты UNSIGNED, DEFAULT и COMMENT. Чтобы сохранить их, утверждение должно включать их явно:

ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column';

При изменении типа данных с помощью CHANGE или MODIFY MySQL пытается преобразовать существующие значения столбцов в новый тип, насколько это возможно.

Предупреждение

Это преобразование может привести к изменению данных. Например, если вы сократите строковый столбец, значения могут быть усечены. Чтобы предотвратить успешное выполнение операции, если преобразование в новый тип данных приведёт к потере данных, включите строгий режим SQL перед использованием ALTER TABLE (см. Раздел 5.1.10, «Режимы SQL сервера»).

Если вы используете CHANGE или MODIFY для сокращения столбца, на котором существует индекс, и полученная длина столбца меньше длины индекса, MySQL автоматически сокращает индекс.

Для столбцов, переименованных с помощью CHANGE, MySQL автоматически переименовывает ссылки на переименованный столбец:

  • Индексы, которые ссылаются на старый столбец, включая индексы и отключенные MyISAM индексы.

  • Внешние ключи, которые ссылаются на старый столбец.

Для столбцов, переименованных с помощью CHANGE, MySQL не переименовывает автоматически ссылки на переименованный столбец:

  • Сгенерированные столбцы и выражения разбиения, которые ссылаются на переименованный столбец. Вы должны использовать CHANGE для переопределения таких выражений в том же операторе ALTER TABLE, что и оператор переименования столбца.

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

Для переупорядочивания столбцов в таблице используйте FIRST и AFTER в операциях CHANGE или MODIFY.

ALTER ... SET DEFAULT или ALTER ... DROP DEFAULT задают новое значение по умолчанию для столбца или удаляют старое значение по умолчанию соответственно. Если старое значение по умолчанию удаляется, и столбец может быть NULL, новым значением по умолчанию является NULL. Если столбец не может быть NULL, MySQL задаёт значение по умолчанию, как описано в Разделе 11.6, «Значения по умолчанию типов данных».

ALTER ... SET DEFAULT нельзя использовать с функцией CURRENT_TIMESTAMP.

id="alter-table-index">Первичные ключи и индексы

DROP PRIMARY KEY удаляет первичный ключ. Если первичный ключ отсутствует, возникает ошибка. Сведения о характеристиках производительности первичных ключей, особенно для InnoDB таблиц, см. в Разделе 8.3.2, «Оптимизация первичных ключей».

Если вы добавляете UNIQUE INDEX или PRIMARY KEY в таблицу, MySQL сохраняет его перед любым не уникальным индексом, чтобы можно было как можно раньше обнаружить дубликаты ключей.

DROP INDEX удаляет индекс. Это расширение MySQL для стандартного SQL. См. Раздел 13.1.25, «Оператор DROP INDEX». Для определения имён индексов используйте SHOW INDEX FROM tbl_name.

Некоторые типы таблиц позволяют задавать тип индекса при его создании. Синтаксис спецификатора index_type — USING type_name. Подробности об USING см. в Разделе 13.1.14, «Оператор CREATE INDEX». Предпочтительное положение — после списка столбцов. Вы должны ожидать, что поддержка использования опции перед списком столбцов будет удалена в будущих выпусках MySQL.

Значения index_option задают дополнительные параметры для индекса. Подробности о допустимых значениях index_option см. в Разделе 13.1.14, «Оператор CREATE INDEX».

RENAME INDEX old_index_name TO new_index_name переименовывает индекс. Это расширение MySQL для стандартного SQL. Содержимое таблицы остается неизменным. old_index_name должно быть именем существующего индекса в таблице, который не удаляется тем же оператором ALTER TABLE. new_index_name — новое имя индекса, которое не может дублировать имя индекса в результирующей таблице после применения изменений. Ни одно из имён индексов не может быть PRIMARY.

Если вы используете ALTER TABLE с MyISAM таблицей, все неуникальные индексы создаются в отдельной группе (как для REPAIR TABLE). Это должно сделать ALTER TABLE значительно быстрее, если у вас много индексов.

Для MyISAM таблиц обновление ключей можно управлять явно. Используйте ALTER TABLE ... DISABLE KEYS, чтобы указать MySQL на остановку обновления неуникальных индексов. Затем используйте ALTER TABLE ... ENABLE KEYS для повторного создания отсутствующих индексов. MyISAM делает это с помощью специального алгоритма, который значительно быстрее, чем вставка ключей по одному, поэтому отключение ключей перед выполнением операций массовой вставки должна значительно ускорить процесс. Для использования ALTER TABLE ... DISABLE KEYS требуется привилегия INDEX в дополнение к ранее упомянутым привилегиям.

Пока неуникальные индексы отключены, они игнорируются для операторов, таких как SELECT и EXPLAIN, которые в противном случае их использовали.

END_OF_DOCUMENT_MARKER

После оператора ALTER TABLE, может потребоваться запустить оператор ANALYZE TABLE для обновления информации о кардинальности индексов. См. Раздел 13.7.5.22, «Оператор SHOW INDEX».

Внешние ключи и другие ограничения

Операторы FOREIGN KEY и REFERENCES поддерживаются хранилищами InnoDB и NDB, которые реализуют ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (...) REFERENCES ... (...). См. Раздел 1.6.3.2, «Ограничения FOREIGN KEY». Для других хранилищ операторы будут проанализированы, но проигнорированы.

Ограничение CHECK анализируется, но игнорируется всеми хранилищами. См. Раздел 13.1.18, «Оператор CREATE TABLE». Причина принятия, но игнорирования синтаксических операторов заключается в совместимости, чтобы упростить портирование кода с других SQL-серверов и запуск приложений, создающих таблицы с ссылками. См. Раздел 1.6.2, «Отличия MySQL от стандартного SQL».

Для оператора ALTER TABLE, в отличие от CREATE TABLE, оператор ADD FOREIGN KEY игнорирует index_name, если оно задано, и использует автоматически сгенерированное имя внешнего ключа. В качестве обходного пути, включите оператор CONSTRAINT для указания имени внешнего ключа:

ADD CONSTRAINT name FOREIGN KEY (....) ...
Важно

MySQL игнорирует встроенные REFERENCES спецификации, где ссылки определены как часть спецификации столбца. MySQL принимает только REFERENCES операторы, определенные в отдельной FOREIGN KEY спецификации.

Примечание

Разделенные InnoDB таблицы не поддерживают внешние ключи. Это ограничение не относится к NDB таблицам, включая те, которые явно разделены с помощью [LINEAR] KEY. Дополнительная информация представлена в Разделе 22.6.2, «Ограничения разбиения, связанные с хранилищами».

MySQL Server и NDB Cluster поддерживают использование ALTER TABLE для удаления внешних ключей:

ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;

Добавление и удаление внешнего ключа в одном операторе ALTER TABLE поддерживается для ALTER TABLE ... ALGORITHM=INPLACE, но не для ALTER TABLE ... ALGORITHM=COPY.

Сервер запрещает изменения столбцов внешнего ключа, которые могут привести к потере целостности ссылок. В качестве обходного пути используйте ALTER TABLE ... DROP FOREIGN KEY перед изменением определения столбца и ALTER TABLE ... ADD FOREIGN KEY после него. Примеры запрещенных изменений включают:

  • Изменения типа данных столбцов внешнего ключа, которые могут быть небезопасными. Например, изменение VARCHAR(20) на VARCHAR(30) разрешено, но изменение на VARCHAR(1024) запрещено, так как это изменяет количество байтов длины, необходимых для хранения отдельных значений.

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

MySQL изменяет имена ограничений внешних ключей, сгенерированные автоматически и определенные пользователем, которые начинаются со строки “tbl_name_ibfk_” для отражения нового имени таблицы. MySQL интерпретирует имена ограничений внешних ключей, которые начинаются со строки “tbl_name_ibfk_” как сгенерированные автоматически.

Изменение набора символов

Для изменения набора символов по умолчанию таблицы и всех символьных столбцов (CHAR, VARCHAR, TEXT) на новый набор символов используйте оператор подобный этому:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

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

Для столбца с типом данных VARCHAR или одним из типов TEXT, CONVERT TO CHARACTER SET изменяет тип данных по мере необходимости, чтобы убедиться, что новый столбец достаточно длинный для хранения столько же символов, сколько и исходный столбец. Например, столбец TEXT имеет два байта длины, которые хранят длину значений в столбце, до максимального значения 65 535. Для столбца latin1 TEXT, каждый символ требует одного байта, поэтому столбец может хранить до 65 535 символов. Если столбец преобразуется в utf8, каждый символ может потребовать до трех байтов, для максимально возможной длины 3 × 65 535 = 196 605 байтов. Эта длина не подходит для байтов длины столбца TEXT, поэтому MySQL преобразует тип данных в MEDIUMTEXT, который является самым маленьким строковым типом, для которого байты длины могут записать значение 196 605. Аналогично, столбец VARCHAR может быть преобразован в MEDIUMTEXT.

Чтобы избежать изменений типа данных, описанных выше, не используйте CONVERT TO CHARACTER SET. Вместо этого используйте MODIFY для изменения отдельных столбцов. Например:

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;

Если вы указываете CONVERT TO CHARACTER SET binary, столбцы CHAR, VARCHAR и TEXT преобразуются в соответствующие бинарные строковые типы (BINARY, VARBINARY, BLOB). Это означает, что у столбцов больше нет набора символов, и последующая операция CONVERT TO не применяется к ним.

Если charset_name равно DEFAULT в операции CONVERT TO CHARACTER SET, используется набор символов, указанный переменной системы character_set_database.

Предупреждение

Операция CONVERT TO преобразует значения столбцов между исходным и указанным набором символов. Это не то, что вам нужно, если у вас есть столбец в одном наборе символов (например, latin1), но сохраненные значения фактически используют другой, несовместимый набор символов (например, utf8). В этом случае необходимо выполнить следующие действия для каждого такого столбца:

ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;

Причина, по которой это работает, заключается в том, что преобразования не происходят при преобразовании в или из столбцов BLOB.

Чтобы изменить только набор символов по умолчанию для таблицы, используйте этот оператор:

ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;

Слово DEFAULT необязательно. Набор символов по умолчанию — это набор символов, который используется, если вы не указываете набор символов для столбцов, которые вы добавляете в таблицу позже (например, с помощью ALTER TABLE ... ADD column).

При включенном системном параметре foreign_key_checks, что является значением по умолчанию, преобразование кодировки символов запрещено для таблиц, содержащих строковый столбец, используемый в ограничении внешнего ключа. Для решения проблемы необходимо отключить foreign_key_checks перед выполнением преобразования кодировки. Преобразование необходимо выполнить для обеих таблиц, участвующих в ограничении внешнего ключа, прежде чем снова включить foreign_key_checks. Если вы снова включите foreign_key_checks после преобразования только одной из таблиц, операция ON DELETE CASCADE или ON UPDATE CASCADE может привести к повреждению данных в таблице-ссылке из-за неявного преобразования, которое происходит во время этих операций (Ошибка #45290, Ошибка #74816).

Удаление и импорт пространств таблиц InnoDB

Таблицу InnoDB, созданную в собственном пространстве таблиц, можно импортировать из резервной копии или с другого сервера MySQL, используя DISCARD TABLEPACE и IMPORT TABLESPACE предложения. См. Раздел 14.6.1.3, “Импорт таблиц InnoDB”.

Порядок строк для таблиц MyISAM

ORDER BY позволяет создавать новую таблицу со строками в определенном порядке. Этот параметр полезен в основном в тех случаях, когда известно, что строки часто запрашиваются в определенном порядке. Используя этот параметр после крупных изменений в таблице, можно повысить производительность. В некоторых случаях это может упростить сортировку для MySQL, если таблица отсортирована по столбцу, по которому она будет сортироваться в дальнейшем.

Примечание

Таблица не сохраняет указанный порядок после вставок и удалений.

Синтаксис ORDER BY позволяет указать одно или несколько имен столбцов для сортировки, каждое из которых необязательно может быть последо-вано ASC или DESC для указания возрастающего или убывающего порядка сортировки соответственно. По умолчанию используется возрастающий порядок. В качестве критериев сортировки допускаются только имена столбцов; произвольные выражения недопустимы. Это предложение должно быть указано в последнюю очередь после всех других предложений.

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

При использовании с разбиениой таблицей ALTER TABLE ... ORDER BY упорядочивает строки только в пределах каждого раздела.

Параметры разбиения

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

В операторе ALTER TABLE может содержаться PARTITION BY или REMOVE PARTITIONING предложение помимо других спецификаций изменения, но PARTITION BY или REMOVE PARTITIONING предложение должно быть указано в последнюю очередь после всех других спецификаций. Параметры ADD PARTITION, DROP PARTITION, DISCARD PARTITION, IMPORT PARTITION, COALESCE PARTITION, REORGANIZE PARTITION, EXCHANGE PARTITION, ANALYZE PARTITION, CHECK PARTITION и REPAIR PARTITION не могут быть объединены с другими спецификациями изменения в одном ALTER TABLE, так как перечисленные параметры действуют только на отдельные разделы.

Для получения дополнительной информации об параметрах разбиения см. Раздел 13.1.18, “Оператор CREATE TABLE” и Раздел 13.1.8.1, “Операции разбиения ALTER TABLE”. Сведения о операторах ALTER TABLE ... EXCHANGE PARTITION и примерах см. в Разделе 22.3.3, “Обмен разделами и подразделами с таблицами”.

До версии MySQL 5.7.6 разбиениые таблицы InnoDB использовали общий обработчик разбиения ha_partition, используемый MyISAM и другими движками хранения, не предоставляющими собственных обработчиков разбиения; в MySQL 5.7.6 и более поздних версиях такие таблицы создаются с помощью собственного (или “родного”) обработчика разбиения движка хранения InnoDB. Начиная с MySQL 5.7.9, вы можете обновить таблицу InnoDB, созданную в MySQL 5.7.6 или ранее (то есть созданную с использованием ha_partition), до родного обработчика разбиения InnoDB, используя ALTER TABLE ... UPGRADE PARTITIONING. (Ошибка #76734, Ошибка #20727344) Этот ALTER TABLE синтаксис не принимает других параметров и может использоваться только для одной таблицы за раз. Вы также можете использовать mysql_upgrade в MySQL 5.7.9 или более поздних версиях для обновления старых разбиениых таблиц InnoDB до родного обработчика разбиения.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/alter-table.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API