Эта глава описывает синтаксис для запросов SQL в MySQL.
ALTER {DATABASE | SCHEMA} [db_name
]alter_specification
...alter_specification
: [DEFAULT] CHARACTER SET [=]charset_name
| [DEFAULT] COLLATE [=]collation_name
ALTER DATABASE
позволяет Вам изменить полные характеристики базы данных. Эти характеристики
сохранены в словаре данных. Чтобы использовать
ALTER DATABASE
, нужна
привилегия ALTER
на базе данных. ALTER SCHEMA
синоним ALTER DATABASE
.
Имя базы данных может быть пропущено для первого синтаксиса, когда запрос относится к базе данных значения по умолчанию.
CHARACTER SET
изменяет набор символов базы данных по
умолчанию. COLLATE
изменяет сопоставление базы данных по
умолчанию. Раздел 11.1 обсуждает имена
сопоставления и набор символов.
Вы можете видеть, какие наборы символов и сопоставления доступны,
соответственно, через SHOW
CHARACTER SET
и SHOW
COLLATION
. См. разделы
14.7.5.3 и 14.7.5.4.
Если Вы изменяете набор символов по умолчанию или сопоставление для базы данных, сохраненные подпрограммы, которые используют значения по умолчанию базы данных, должны быть обновлены так, чтобы они использовали новые значения по умолчанию. В сохраненной подпрограмме переменные с символьными типами данных используют значения по умолчанию базы данных, если набор символов или сопоставление не определены явно. См. раздел 14.1.13.
ALTER [DEFINER = {user
| CURRENT_USER }] EVENTevent_name
[ON SCHEDULEschedule
] [ON COMPLETION [NOT] PRESERVE] [RENAME TOnew_event_name
] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'comment
'] [DOevent_body
]
ALTER EVENT
изменяет одну или больше характеристик существующего события без потребности
обновить это. Синтаксис для DEFINER
, ON SCHEDULE
,
ON COMPLETION
, COMMENT
,
ENABLE
/ DISABLE
и
DO
точно тот же самый, как с
CREATE EVENT
. См.
раздел 14.1.10.
Любой пользователь может изменить событие, определенное в базе данных, для
которой этот пользователь имеет привилегию
EVENT
. Когда пользователь выполняет успешный запрос
ALTER EVENT
,
этот пользователь становится определителем для затронутого события.
ALTER EVENT
работает только с существующим событием:
mysql> ALTER EVENT no_such_event
> ON SCHEDULE
> EVERY '2:3' DAY_HOUR;
ERROR 1517 (HY000): Unknown event 'no_such_event'
В каждом из следующих примеров, предположите, что событие называется
myevent
и определено, как показано здесь:
CREATE EVENT myevent ON SCHEDULE EVERY 6 HOUR COMMENT 'A sample comment.' DO UPDATE myschema.mytable SET mycol = mycol + 1;Следующий запрос изменяет график для
myevent
с
однажды каждые шесть часов с немедленным стартом на однажды каждые двенадцать
часов, запускаясь четыре часа со времени выполнения запроса:
ALTER EVENT myevent ON SCHEDULE EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 4 HOUR;Возможно изменить многократные характеристики в единственном запросе. Этот пример изменяет запрос SQL, выполненный
myevent
к тому, который удаляет все записи из
mytable
, это также изменяет график, таким образом, что это
выполняется однажды, спустя один день после этого
ALTER EVENT
.
ALTER EVENT myevent ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY DO TRUNCATE TABLE myschema.mytable;Определите опции в
ALTER EVENT
только для тех характеристик, которые Вы хотите изменить, пропущенные опции
сохраняют свои существующие значения. Это включает любые значения по
умолчанию для CREATE
EVENT
, например, ENABLE
.
Чтобы выключить myevent
, используйте
ALTER EVENT
:
ALTER EVENT myevent DISABLE;
ON SCHEDULE
может использовать выражения, вовлекающие встроенные
функции MySQL и пользовательские переменные, чтобы получить любое из значений
timestamp
или interval
, которые
это содержит. Вы не можете использовать сохраненные подпрограммы или
определяемые пользователем функции в таких выражениях, и Вы не можете
использовать табличные ссылки, однако, Вы можете использовать
SELECT FROM DUAL
. Это верно для
ALTER EVENT
и
CREATE EVENT
.
Ссылки на сохраненные подпрограммы, определяемые пользователем функции и
таблицы в таких случаях определенно не разрешены и терпят неудачу с
ошибкой (см. Bug #22830).
Хотя ALTER EVENT
, который
содержит другой ALTER EVENT
в
DO
, кажется, преуспевает, когда сервер
пытается запустить получающееся запланированное событие, выполнение
терпит неудачу с ошибкой.
Чтобы переименовать событие, используйте
ALTER EVENT
RENAME TO
. Это запрос
переименовывает myevent
в yourevent
:
ALTER EVENT myevent RENAME TO yourevent;Вы можете также переместить событие в иную базу данных через
ALTER EVENT ... RENAME TO ...
с
db_name.event_name
:
ALTER EVENT olddb.myevent RENAME TO newdb.myevent;Чтобы выполнить предыдущий запрос, пользователь, выполняющий это, должен иметь привилегию
EVENT
на обоих базах данных olddb
и newdb
.
Запроса RENAME EVENT
нет.
DISABLE ON SLAVE
используется на ведомом устройстве вместо
ENABLE
или DISABLE
, чтобы указать на событие,
которое создавалось на ведущем устройстве и копировалось к ведомому
устройству, но это не выполнено на ведомом устройстве. Обычно
DISABLE ON SLAVE
установлен автоматически как требуется, однако,
есть некоторые обстоятельства, при которых Вы можете хотеть или должны
изменить это вручную. См.
раздел 19.4.1.12.
ALTER FUNCTIONЭто запрос может использоваться, чтобы изменить характеристики сохраненной функции. Больше чем одно изменение может быть определено вfunc_name
[characteristic
...]characteristic
: COMMENT 'string
' | LANGUAGE SQL | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER }
ALTER FUNCTION
.
Однако, Вы не можете изменить параметры или тело сохраненной функции,
используя это запрос, чтобы произвести такие изменения, Вы должны обновить
функцию через DROP FUNCTION
и CREATE FUNCTION
.
Вы должны иметь привилегию
ALTER ROUTINE
для функции (предоставляется автоматически
создателю). Если двоичное журналирование включено,
ALTER FUNCTION
может также потребовать привилегию
SUPER
, см.
раздел 21.7.
ALTER INSTANCE ROTATE INNODB MASTER KEY
ALTER INSTANCE
определяет действия, применимые к серверу
MySQL. Требует привилегии SUPER
.
ALTER INSTANCE ROTATE INNODB MASTER KEY
используется для
ротации основного ключа шифрования, используемого для InnoDB
.
Плагин keyring должен быть загружен, чтобы использовать этот запрос. По
умолчанию сервер MySQL загружает плагин keyring_file
.
ALTER INSTANCE ROTATE INNODB MASTER KEY
поддерживает параллельный DML. Однако, это не может быть выполнено
одновременно с CREATE TABLE ...
ENCRYPTION
или ALTER TABLE ...
ENCRYPTION
, и блокировки взяты, чтобы предотвратить конфликты,
которые могли явиться результатом параллельного выполнения этих запросов.
Если один из противоречивых запросов работает, он должен завершиться прежде,
чем другой может продолжиться.
ALTER INSTANCE
записан в двоичный журнал так, чтобы он мог
быть выполнен на копируемых серверах.
ALTER PROCEDUREЭтот запрос может использоваться, чтобы изменить характеристики хранимой процедуры. Больше чем одно изменение может быть определено вproc_name
[characteristic
...]characteristic
: COMMENT 'string
' | LANGUAGE SQL | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER }
ALTER PROCEDURE
.
Однако, Вы не можете изменить параметры или тело хранимой процедуры,
используя этот запрос, здесь нужно применить
DROP PROCEDURE
и
CREATE PROCEDURE
.
Вы должны иметь привилегию
ALTER ROUTINE
для процедуры. По умолчанию эту привилегию
предоставляют автоматически создателю процедуры. Это поведение может быть
изменено, отключая
automatic_sp_privileges
. См.
раздел 21.2.2.
ALTER SERVERМеняет информацию сервера дляserver_name
OPTIONS (option
[,option
] ...)
server_name
,
корректируя любую из опций, разрешенных в
CREATE SERVER
.
Соответствующие области в mysql.servers
обновлены соответственно. Этот запрос требует привилегии
SUPER
.
Например, чтобы обновить USER
:
ALTER SERVER s OPTIONS (USER 'sally');
ALTER SERVER
не вызывает автоматическое завершение транзакции.
В MySQL 8.0 ALTER SERVER
не записан в двоичный журнал,
независимо от формата журналирования, который используется.
ALTER TABLEtbl_name
[alter_specification
[,alter_specification
] ...] [partition_options
]alter_specification
:table_options
| ADD [COLUMN]col_name
column_definition
[FIRST | AFTERcol_name
] | ADD [COLUMN] (col_name
column_definition
,...) | ADD {INDEX|KEY} [index_name
] [index_type
] (index_col_name
,...) [index_option
] ... | ADD [CONSTRAINT [symbol
]] PRIMARY KEY [index_type
] (index_col_name
,...) [index_option
] ... | ADD [CONSTRAINT [symbol
]] UNIQUE [INDEX|KEY] [index_name
] [index_type
] (index_col_name
,...) [index_option
] ... | ADD FULLTEXT [INDEX|KEY] [index_name
] (index_col_name
,...) [index_option
] ... | ADD SPATIAL [INDEX|KEY] [index_name
] (index_col_name
,...) [index_option
] ... | ADD [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
,...)reference_definition
| ALGORITHM [=] {DEFAULT|INPLACE|COPY} | ALTER [COLUMN]col_name
{SET DEFAULTliteral
| DROP DEFAULT} | CHANGE [COLUMN]old_col_name
new_col_name
column_definition
[FIRST|AFTERcol_name
] | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE} | MODIFY [COLUMN]col_name
column_definition
[FIRST | AFTERcol_name
] | DROP [COLUMN]col_name
| DROP PRIMARY KEY | DROP {INDEX|KEY}index_name
| DROP FOREIGN KEYfk_symbol
| ALTER INDEXindex_name
{VISIBLE | INVISIBLE} | DISABLE KEYS | ENABLE KEYS | RENAME [TO|AS]new_tbl_name
| RENAME {INDEX|KEY}old_index_name
TOnew_index_name
| ORDER BYcol_name
[,col_name
] ... | CONVERT TO CHARACTER SETcharset_name
[COLLATEcollation_name
] | [DEFAULT] CHARACTER SET [=]charset_name
[COLLATE [=]collation_name
] | DISCARD TABLESPACE | IMPORT TABLESPACE | FORCE | {WITHOUT|WITH} VALIDATION | ADD PARTITION (partition_definition
) | DROP PARTITIONpartition_names
| DISCARD PARTITION {partition_names
| ALL} TABLESPACE | IMPORT PARTITION {partition_names
| ALL} TABLESPACE | TRUNCATE PARTITION {partition_names
| ALL} | COALESCE PARTITIONnumber
| REORGANIZE PARTITIONpartition_names
INTO (partition_definitions
) | EXCHANGE PARTITIONpartition_name
WITH TABLEtbl_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 PARTITIONINGindex_col_name
:col_name
[(length
)] [ASC | DESC]index_type
: USING {BTREE | HASH}index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| WITH PARSERparser_name
| COMMENT 'string
' | {VISIBLE | INVISIBLE}table_options
:table_option
[[,]table_option
] ... (см. опцииCREATE TABLE
)partition_options
: (см. опцииCREATE TABLE
)
ALTER TABLE
изменяет структуру таблицы. Например, Вы можете добавить или удалить столбцы,
создать или разрушить индекс, изменить тип существующих столбцов,
переименовать столбцы или таблицу непосредственно. Вы можете также изменить
характеристики, такие как механизм хранения, используемый для таблицы
или табличного комментария.
После имени таблицы, определите изменения, которые будут сделаны. Если ни
одно не дано, ALTER TABLE
ничего не делает.
Синтаксис для многих из допустимых изменений подобен параметрам
CREATE TABLE
. См.
раздел 14.1.15.
table_options
показывает табличные опции вида,
который может использоваться в CREATE
TABLE
, например, ENGINE
, AUTO_INCREMENT
,
AVG_ROW_LENGTH
, MAX_ROWS
, ROW_FORMAT
или TABLESPACE
. Для списка всех табличных опций и описания
каждой см. раздел 14.1.15. Однако,
ALTER TABLE
игнорирует
опции DATA DIRECTORY
и INDEX DIRECTORY
.
Использование табличных опций с ALTER
TABLE
обеспечивает удобный способ изменить единственные табличные
характеристики. Например, если t1
сейчас не таблица
InnoDB
, этот запрос изменяет механизм хранения на
InnoDB
:
ALTER TABLE t1 ENGINE = InnoDB;Изменить
InnoDB
, чтобы использовать на сжатый
формат хранения строки:
ALTER TABLE t1 ROW_FORMAT = COMPRESSED;Если опция шифрования табличного пространства активирована (см. раздел 16.7.10), шифрование для
t1
может быть включено или отключено:
ALTER TABLE t1 ENCRYPTION='Y'; ALTER TABLE t1 ENCRYPTION='N';Чтобы отключить шифрование для
InnoDB
, установите
ENCRYPTION='N'
, используя
ALTER TABLE
.
Сбрасывать текущее значение auto-increment:
ALTER TABLE t1 AUTO_INCREMENT = 13;Изменить табличный набор символов по умолчанию:
ALTER TABLE t1 CHARACTER SET = utf8;Добавить (или изменить) табличный комментарий:
ALTER TABLE t1 COMMENT = 'New table comment';Чтобы проверить, что табличные опции были изменены, удобно использовать
SHOW CREATE TABLE
.
partition_options
показывает опции, которые могут
использоваться с разделенными таблицами для того, чтобы повторно разделить,
добавить, удалить, импортировать, слить и разделить разделение, и для того,
чтобы выполнить обслуживание разделения. Это возможно для
ALTER TABLE
, который включает
параметр 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
, так как опции только перечислены на отдельном
разделе. Для получения дополнительной информации об опциях разделения см.
разделы 14.1.15 и
14.1.7.1.
До 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
(Bug #76734, Bug #20727344). Эта версия ALTER TABLE
не принимает никакие другие опции и может использоваться только на
единственной таблице за один раз.
Вы можете также использовать mysql_upgrade, чтобы обновить более старые разделенные таблицы InnoDB.
Некоторые операции могут привести к предупреждениям, если предприняты на
таблице, для которой механизм хранения не поддерживает такую работу. Эти
предупреждения могут быть выведены на экран
SHOW WARNINGS
. См. раздел
14.7.5.40.
Для информации о поиске неисправностей
ALTER TABLE
см.
раздел B.5.6.1.
В большинстве случаев ALTER TABLE
делает временную копию оригинальной таблицы. MySQL ждет других
операций, которые изменяют таблицу, затем продолжается. Это включает
изменение в копию, удаляет оригинальную таблицу и переименовывает новую.
В то время как ALTER TABLE
выполняется, оригинальная таблица читаема другими сеансами. Обновления и
записи таблицы, которые начинаются после
ALTER TABLE
остановлены, пока новая таблица не готова, затем автоматически перенаправлена
к новой таблице без любых неудавшихся обновлений. Временная копия
оригинальной таблицы создается в каталоге базы данных новой таблицы. Это
может отличаться от каталога базы данных оригинальной таблицы для
ALTER TABLE
, которые
переименовывают таблицу к иной базе данных.
Исключение, упомянутое ранее, это блокировка чтения
ALTER TABLE
(не только записи) в пункте, где это готово очистить устаревшие структуры
таблиц от таблицы и табличных кэшей определения. В этом пункте это должно
приобрести исключительную блокировку. Чтобы сделать так, это ждет
завершения текущих чтений и блокирует новые чтения и записи.
Для таблиц MyISAM
Вы можете убыстрить воссоздание индекса
(самая медленная часть процесса изменения), устанавливая к высокому значению
myisam_sort_buffer_size
.
Для некоторых операций, оперативное выполнение
ALTER TABLE
возможно, которое
не требует временной таблицы:
ALTER TABLE
без любых других опций MySQL просто переименовывает любые файлы, которые
соответствуют таблице tbl_name
RENAME TO new_tbl_name
tbl_name
.
Вы можете также использовать RENAME
TABLE
, чтобы переименовать таблицы. См.
раздел 14.1.29.
Любые привилегии, предоставленные определенно для переименованной таблицы,
не мигрируются к новому имени. Они должны быть изменены вручную.
Переименование столбца.
ENUM
или
SET
, добавляя новое перечисление или
членов набора в конец списка допустимых членских значений, пока размер
хранения типа данных не изменяется. Например, добавление участника к
SET
, у которого есть 8 участников,
изменяет необходимое хранение для значения от 1 байта до 2 байтов,
это потребует табличной копии. Добавление участников в середине изменения
нумерации списка существующих участников, тоже требует табличной копии.
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
копирует только измененный раздел и
не касается неизменных.
InnoDB
.ALTER INDEX
.Вы можете предписать ALTER TABLE
работу, которая иначе не
потребовалась бы, чтобы табличная копия использовала временный табличный
метод (как поддержано в MySQL 5.0), устанавливая
old_alter_table
в ON
, или указав параметр ALGORITHM=COPY
в
alter_specification
. Если есть конфликт между
old_alter_table
и параметром ALGORITHM
со значением кроме DEFAULT
, ALGORITHM
имеет приоритет. ALGORITHM=DEFAULT
аналогичен
отсутствию ALGORITHM
вовсе.
Определение ALGORITHM=INPLACE
заставляет использовать
оперативный метод для пунктов и механизмов хранения, которые поддерживают
это, и приводит к ошибке иначе, таким образом избегая длинной табличной
копии, если Вы пытаетесь изменить таблицу, которая использует иной механизм
хранения, чем Вы ожидаете. См. раздел
16.12.
Для таблиц InnoDB
копирование
ALTER TABLE
на таблице, которая находится в совместно используемом табличном
пространстве, таком как общее
табличное пространство или
системное табличное пространство может увеличить количество пространства,
использованного табличным пространством. Такие операции требуют такого
большого количества дополнительного пространства, как данные в таблице плюс
индекс. Для таблицы, которая находится в совместно используемом табличном
пространстве, дополнительное пространство, используемое во время копирования
таблицы ALTER TABLE
не выпущено назад к операционной системе, как для таблицы, которая находится
в табличном пространстве
file-per-table.
С MySQL 5.7.4 ALTER TABLE
обновляет временные столбцы MySQL 5.5 до формата 5.6 для ADD
COLUMN
, CHANGE COLUMN
, MODIFY COLUMN
,
ADD INDEX
и FORCE
.
Это преобразование не может быть сделано, используя алгоритм
INPLACE
, потому что таблица должна быть восстановлена, таким
образом, определение ALGORITHM=INPLACE
в этих случаях приводит к
ошибке. Определите ALGORITHM=COPY
в случае необходимости.
С MySQL 5.7.6 ALTER TABLE
на многостолбцовом индексе
используемом, чтобы разделить таблицу по KEY
не может быть выполнен онлайн, когда работа изменила бы порядок столбцов. В
таких случаях Вы должны использовать копирование
ALTER TABLE
(Bug #17896265).
Вы можете управлять уровнем параллельного чтения и записи
таблицы, в то время как это изменяется, используя параметр LOCK
.
Определение значения не по умолчанию для этого пункта позволяет Вам требовать
определенного количества параллельного доступа или исключительности во время
изменений и останавливает работу, если требуемая степень блокировки
недоступна. Параметры для LOCK
:
LOCK = DEFAULTМаксимальный уровень параллелизма для данного
ALGORITHM
(если есть) и ALTER TABLE
: допускает
параллельные чтения и записи, если поддержаны. В противном случае разрешает
параллельные чтения, если поддержано. В противном случае проводит в
жизнь эксклюзивный доступ.LOCK = NONEЕсли поддержано, разрешит параллельные чтения и записи. Иначе, возвратит сообщение об ошибке.
LOCK = SHAREDЕсли поддержано, разрешите параллельные чтения, но блокирует записи. Отметьте, что запись будет заблокирована, даже если параллельные записи поддержаны механизмом хранения для данного
ALGORITHM
(если есть)
и ALTER TABLE
. Если параллельные чтения не поддержаны, возвратит
сообщение об ошибке.LOCK = EXCLUSIVEПроведет в жизнь эксклюзивный доступ. Это будет сделано, даже если параллельные чтения и записи поддержаны механизмом хранения для данного
ALGORITHM
(если есть) и ALTER TABLE
.WITHOUT VALIDATION
и WITH VALIDATION
затрагивают ALTER TABLE
,
если он выполняет оперативную работу для модификаций
произведенных
виртуальных столбцов. См.
раздел 14.1.7.2.
Вы можете также использовать
ALTER TABLE
, чтобы выполнить
null-работу, которая восстанавливает таблицу. Для
получения дополнительной информации см.
раздел 16.12.1.tbl_name
FORCE
Чтобы использовать ALTER TABLE
, нужны привилегии
ALTER
,
CREATE
и
INSERT
для таблицы.
Переименование таблицы требует
ALTER
и
DROP
на старой таблице,
ALTER
,
CREATE
и
INSERT
на новой.
table_option
показывает табличную опцию вида, который может использоваться в
CREATE TABLE
, например, в
ENGINE
, AUTO_INCREMENT
,
AVG_ROW_LENGTH
, MAX_ROWS
, ROW_FORMAT
или TABLESPACE
. См. раздел
14.1.15. Но ALTER TABLE
игнорирует табличные опции DATA DIRECTORY
и
INDEX DIRECTORY
.
Например, чтобы преобразовать таблицу в InnoDB
:
ALTER TABLE t1 ENGINE = InnoDB;См. раздел 16.8.4 для соображений переключения таблицы на
InnoDB
.
Когда Вы определяете параметр ENGINE
,
ALTER TABLE
пересоздает таблицу. Это истина, даже если у таблицы уже есть
указанный механизм хранения.
Запуск ALTER TABLE
на существующей
таблице tbl_name
ENGINE=INNODBInnoDB
выполняет
null ALTER
TABLE
, что можно использовать для дефрагментации таблицы, см.
раздел 16.11.4. Запуск
ALTER TABLE
на таблице
tbl_name
FORCEInnoDB
выполняет ту же самую функцию.
ALTER
TABLE
и
tbl_name
ENGINE=INNODBALTER TABLE
применяют
online DDL
(tbl_name
FORCEALGORITHM=COPY
). См.
раздел 16.12.1.
Результат попытки изменить механизм хранения таблицы затронут тем,
доступен ли желаемый механизм хранения, и установкой режима SQL
NO_ENGINE_SUBSTITUTION
, см. раздел
6.1.8.
Чтобы предотвратить потерю данных,
ALTER TABLE
не может использоваться, чтобы изменить механизм хранения таблицы к
MERGE
или BLACKHOLE
.
AUTO_INCREMENT
для новых строк:
ALTER TABLE t2 AUTO_INCREMENT = value
;
Вы не можете сбросить счетчик к значению
меньше или равным значению, которое используется в настоящее время. Для
InnoDB
и MyISAM
,
если значение в настоящее время меньше или равно максимальному значению в
столбце AUTO_INCREMENT
,
значение сброшено к текущему максимуму AUTO_INCREMENT
+1.ALTER TABLE
с TABLESPACE
, чтобы переместить неразделенные таблицы InnoDB
между существующими
общими табличными пространствами,
табличными пространствами
file-per-table и
системным табличным пространством.
Для разделенных таблиц ALTER TABLE tbl_name TABLESPACE [=]
только изменяет табличное
пространство по умолчанию таблицы. Это не перемещает разделение от одного
табличного пространства в другое. Чтобы переместить табличное разделение, Вы
должны переместить каждый раздел, используя tablespace_name
ALTER TABLE
.tbl_name
REORGANIZE PARTITION
ALTER TABLE ... TABLESPACE
всегда вызывают пересоздание таблицы, даже если TABLESPACE
не изменился от его предыдущего значения.
ALTER TABLE ... TABLESPACE
не поддерживает перемещение
таблицы от временного табличного пространства в постоянное.
DATA DIRECTORY
, который поддержан с
CREATE TABLE ... TABLESPACE
,
не поддержан с ALTER TABLE ... TABLESPACE
и проигнорирован, если определен.
ADD
,
ALTER
, DROP
и CHANGE
в одном
ALTER TABLE
, отделенных
запятыми. Это расширение MySQL к стандартному SQL, который разрешает только
один из каждого типа параметра за запрос
ALTER TABLE
.
Например, чтобы удалить много столбцов в единственном запросе, сделайте это:
ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
CHANGE col_name
,
DROP col_name
и
DROP INDEX
расширения MySQL к стандартному SQL.COLUMN
является дополнительным и может быть пропущено.column_definition
использует тот же самый синтаксис для ADD
и
CHANGE
как в CREATE
TABLE
. См. раздел 14.1.15.CHANGE
old_col_name
new_col_name
column_definition
.
Чтобы сделать так, определите старые и новые имена столбцов и определение,
которое в настоящее время имеет столбец. Например, чтобы переименовать
INTEGER
из
a
в b
:
ALTER TABLE t1 CHANGE a b INTEGER;Чтобы изменить тип столбца, но не имя,
CHANGE
все еще требует старого и нового имени столбца, даже если они одинаковы:
ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;Вы можете также использовать
MODIFY
, чтобы
изменить тип столбца, не переименовывая это:
ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
MODIFY
расширение ALTER
TABLE
для совместимости с Oracle.
Когда Вы используете CHANGE
или MODIFY
,
column_definition
должен включать тип данных и все
признаки, которые должны относиться к новому столбцу, кроме индексных
признаков вроде PRIMARY KEY
или UNIQUE
.
Признаки, существующие в оригинальном определении, но не определенные для
нового определения, не применены. Предположите, что столбец
col1
определен как INT UNSIGNED DEFAULT 1 COMMENT
'my column'
, и Вы изменяете столбец следующим образом:
ALTER TABLE t1 MODIFY col1 BIGINT;Получающийся столбец будет определен как
BIGINT
,
но не будет включать признаки
UNSIGNED DEFAULT 1 COMMENT 'my column'
.
Чтобы сохранить их, запрос должен быть:
ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column';
CHANGE
или MODIFY
, MySQL пытается преобразовать существующие значения
столбцов в новый тип так, как возможно.
Это преобразование может привести к изменению данных. Например, если Вы
сокращаете строковый столбец, значения могут быть усеченными. Чтобы
препятствовать этому, если бы преобразования в новый тип данных привело бы к
потере данных, включите строгий режим SQL перед использованием
ALTER TABLE
(см.
раздел 6.1.8).
FIRST
или AFTER col_name
. Значение по умолчанию должно добавить последний столбец.
Вы можете также использовать FIRST
и AFTER
в
CHANGE
или MODIFY
, чтобы переупорядочить
столбцы в пределах таблицы.ALTER ... SET DEFAULT
или ALTER ... DROP DEFAULT
определит новое значение по умолчанию для столбца или удалит старое
значение по умолчанию, соответственно. Если старое значение по умолчанию
удалено, и столбец может быть NULL
, новое значение по умолчанию
NULL
. Если столбец не может быть NULL
, MySQL
назначает значение по умолчанию как описано в
разделе 12.7.DROP INDEX
удаляет индекс. Это расширение MySQL к стандартному SQL. См.
раздел 14.1.22.
Если Вы неуверены в имени индекса, надо использовать
SHOW INDEX FROM tbl_name
.CHANGE
или
MODIFY
, чтобы сократить столбец, для которого индекс
существует на столбце, и получающаяся длина столбца меньше, чем длина
индекса, MySQL сокращает индексирование автоматически.DROP TABLE
.DROP PRIMARY KEY
удаляет
primary key.
Если нет никакого первичного ключа, ошибка происходит. Для информации о
технических характеристиках первичных ключей, специально для
InnoDB
, см. раздел
9.3.2.
Если Вы добавляете UNIQUE INDEX
или PRIMARY KEY
,
MySQL хранит это прежде, чем любой групповой индекс, чтобы обнаружить
дубликаты ключа как можно раньше.
index_type
:
USING type_name
. См.
раздел 14.1.12.
Привилегированная позиция после списка столбца. Поддержка использования опции
перед списком столбца будет удалена в будущем выпуске MySQL.
index_option
определяют дополнительные опции для
индексирования. USING
одна такая опция. Для деталей о допустимых
значениях index_option
см.
раздел 14.1.12.
RENAME INDEX old_index_name
TO
new_index_name
переименовывает индекс.
Это расширение MySQL к стандартному SQL. Контент таблицы остается неизменным.
old_index_name
должно быть названием существующего
индекса в таблице, которая не удалена тем же самым
ALTER TABLE
.
new_index_name
новое индексное имя, которое не может дублировать
название индексирования в получающейся таблице после того, как изменения были
применены. Ни одно имя индекса не может быть PRIMARY
.ALTER TABLE
может быть необходимо выполнить ANALYZE
TABLE
, чтобы обновить индексируют информацию о количестве
элементов. См. раздел 14.7.5.22.ORDER BY
позволяет Вам составить новую таблицу со строками в
определенном порядке. Эта опция полезна прежде всего, когда Вы знаете, что
должны главным образом запросить строки в определенном порядке большую часть
времени. При использовании этой опции после существенных изменений таблицы Вы
могли бы быть в состоянии получить более высокую производительность.
В некоторых случаях, это могло бы сделать сортировку легче для MySQL, если
таблица в порядке столбцов, которым Вы хотите упорядочить это позже.
Таблица не остается в указанном порядке после вставок и удалений.
ORDER BY
разрешает одному или более именам столбцов быть
определенными для того, чтобы быть критерием сортировки, каждый из которых
произвольно может сопровождаться ASC
или DESC
,
чтобы указать на сортировку по возрастанию или сортировку по убыванию,
соответственно. Значение по умолчанию: по возрастанию. Только имена столбцов
разрешены как критерии сортировки, произвольные выражения не разрешены. Этот
параметр должен быть дан последним после любых других.
ORDER BY
не имеет смысла для InnoDB
, потому что
InnoDB
всегда обрабатывает строки таблицы согласно
кластеризируемому индексу.
Когда используется на разделенной таблице, ALTER TABLE ...
ORDER BY
сортирует строки только в пределах каждого раздела.
ALTER INDEX
разрешает индексированию быть сделанным видимым
или невидимым. Невидимый индекс не используется оптимизатором.
Модификация невидимости относится к индексам кроме первичных ключей (явных
или неявных). С MySQL 8.0.1 эта особенность поддержана для любого механизма
хранения. В MySQL 8.0.0 это применяется только к InnoDB
.
См. раздел 9.3.10.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
,
это иначе использовало бы их.
VARCHAR(20)
на
VARCHAR(30)
разрешено, но изменение
этого к VARCHAR(1024)
нет, потому что это изменяет число байтов длины, требуемых, чтобы сохранить
отдельные значения. Обходное решение должно использовать
ALTER TABLE ... DROP FOREIGN KEY
прежде, чем изменить определение столбца и
ALTER TABLE ... ADD
FOREIGN KEY
после.FOREIGN KEY
и REFERENCES
поддержаны InnoDB
, который осуществляет
ADD [CONSTRAINT [symbol
]] FOREIGN KEY
[index_name
] (...) REFERENCES ... (...)
. См.
раздел 16.8.6.
Для других механизмов хранения параметры разобраны, но проигнорированы.
CHECK
разобран, но проигнорирован всеми механизмами хранения.
См. раздел 14.1.15.
Причина того, чтобы принять, но проигнорировать пункты синтаксиса: для
совместимости, чтобы облегчить перенос кода от других SQL-серверов и
запускать приложения, которые составляют таблицы со ссылками. См.
раздел 1.8.2.
Для ALTER TABLE
,
в отличие от этого CREATE TABLE
, ADD FOREIGN KEY
игнорирует index_name
, если дано и использовано автоматически произведенное имя внешнего
ключа. Как обходное решение, включайте CONSTRAINT
, чтобы
определить имя внешнего ключа:
ADD CONSTRAINT name
FOREIGN KEY (....) ...
Действующие технические требования REFERENCES
,
где ссылки определены как часть спецификации столбца, тихо проигнорированы.
MySQL принимает только REFERENCES
, определенные как часть
отдельной спецификации FOREIGN KEY
.
Разделенные таблицы InnoDB
не поддерживают внешние ключи. См.
раздел 20.6.2.
ALTER TABLE
, чтобы удалить внешние ключи:
ALTER TABLEСм. раздел 16.8.6.tbl_name
DROP FOREIGN KEYfk_symbol
;
ALTER TABLE
поддержано для ALTER TABLE ...
ALGORITHM=INPLACE
, но не для
ALTER TABLE ... ALGORITHM=COPY
.InnoDB
, которая составлена с ее собственным
табличным пространством
file-per-table в файле
.ibd
, от того файла можно отказаться и импортировать другой.
Отказаться от файла .ibd
так:
ALTER TABLE tbl_name
DISCARD TABLESPACE;
Это удаляет текущий файл .ibd
,
так что надо убедиться, что у Вас есть резервная копия. Попытка изменить
табличное содержание, в то время как от файла табличного пространства
отказываются приводит к ошибке. Вы можете выполнить операции DDL,
перечисленные в раздел 16.12
в то время, как от файла табличного пространства отказываются.
Чтобы импортировать резервный файл .ibd
назад в таблицу, скопируйте его в каталог базы данных, а затем
сделайте этот запрос:
ALTER TABLE tbl_name
IMPORT TABLESPACE;
Файл табличного пространства не должен обязательно быть создан на сервере, в
который он будет импортирован позже. В MySQL 8.0 импорт файла табличного
пространства из другого сервера работает, если у обоих серверов есть статус
GA (General Availablility), и их версии в пределах того же самого ряда. Иначе
файл должен быть создан на сервере, в который он импортирован.
ALTER TABLE ... IMPORT TABLESPACE
не проводит в жизнь ограничения внешнего ключа
на импортированные данные.
ALTER TABLE ...
DISCARD TABLESPACE
и
ALTER TABLE
...IMPORT TABLESPACE
не поддержаны для таблиц, которые принадлежат
общему табличному пространству.
См. раздел 16.7.4.
CHAR
,
VARCHAR
,
TEXT
)
к новому набору символов, используйте запрос:
ALTER TABLEЗапрос также изменяет сопоставление всех символьных столбцов. Если Вы не определяетеtbl_name
CONVERT TO CHARACTER SETcharset_name
;
COLLATE
, чтобы указать, которое сопоставление
использовать, запрос использует сопоставление по умолчанию набора символов.
Если это сопоставление является несоответствующим для намеченного табличного
использования (например, если это изменило бы от чувствительного к регистру
сопоставления до нечувствительного к регистру),
определите сопоставление явно.
Для столбца, у которого есть тип данных
VARCHAR
, или один из типов
TEXT
, CONVERT TO
CHARACTER SET
изменит тип данных по мере необходимости, чтобы
гарантировать, что новый столбец достаточно длинен, чтобы сохранить так много
символов, как оригинальный столбец. Например, у
TEXT
есть
два байта длины, которые хранят длину значений в столбце, до максимума
65535. Для столбца latin1
TEXT
каждый символ требует единственный байт, таким образом, столбец может
сохранить до 65535 символов. Если столбец преобразован в utf8
,
каждый символ мог бы потребовать до трех байтов для максимальной возможной
длины 3 * 65535 = 196605 байт. Та длина не будет помещаться в
байты длины столбца TEXT
,
таким образом, MySQL преобразует тип данных в
MEDIUMTEXT
,
который является самым маленьким строковым типом, для которого байты длины
могут сделать запись значения 196605. Точно так же
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
преобразовывает значения столбцов между наборами
символов. Это не то, что Вы хотите, если у Вас есть столбец в одном наборе
символов (как latin1
) но сохраненные значения фактически
используют некоторый другой, несовместимый, набор символов (как
utf8
). В этом случае, Вы должны сделать следующее для
каждого такого столбца:
ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;Причина того, что это работает, состоит в том, что нет никакого преобразования, когда Вы преобразовываете в или от
BLOB
.
Чтобы изменить только набор символов default для таблицы, используйте этот запрос:
ALTER TABLEСловоtbl_name
DEFAULT CHARACTER SETcharset_name
;
DEFAULT
опционально. Набор символов значения по умолчанию
это набор символов, который используется, если Вы не определяете набор
символов для столбцов, которые Вы добавляете к таблице позже (например, с
помощью ALTER TABLE ... ADD column
).
При включении
foreign_key_checks
, что является настройкой по умолчанию,
преобразование набора символов не разрешено на таблицах, которые включают
столбец строки символов, используемый в ограничении внешнего ключа. Обходное
решение должно отключить
foreign_key_checks
прежде, чем выполнить преобразование набора символов. Вы должны
выполнить преобразование на обеих таблицах, вовлеченных в ограничение
внешнего ключа перед включением
foreign_key_checks
. Если Вы повторно включаете
foreign_key_checks
после преобразования только одной из таблиц,
ON DELETE CASCADE
или ON UPDATE CASCADE
могут повредить данные в таблице ссылки из-за неявного преобразования,
которое происходит во время этих операций (Bug #45290, Bug #74816).
С функцией mysql_info()
C API Вы можете узнать, сколько было скопировано строк
ALTER TABLE
. См.
раздел 25.8.7.36.
Связанные с разделением параметры
ALTER TABLE
могут использоваться с разделенными таблицами для
того, чтобы повторно разделить, добавить, удалить, отказаться,
импортировать, слить и разделить разделы и выполнить обслуживание разделения.
Просто использование partition_options
с
ALTER TABLE
на разделенной таблице перераспределяет таблицу, согласно схеме разделения,
определенной partition_options
.
Этот пункт всегда начинается PARTITION BY
и
и следует за тем же самым синтаксисом и другими правилами, как в
partition_options
для
CREATE TABLE
(см.
раздел 14.1.15),
может также использоваться, чтобы разделить существующую таблицу, которая еще
не разделена. Например, считайте (неразделенную) таблицу определенной,
как показано здесь:
CREATE TABLE t1 (id INT, year_col INT);Эта таблица может быть разделена
HASH
с применением столбца
id
как ключа разделения на 8 разделов посредством этого запроса:
ALTER TABLE t1 PARTITION BY HASH(id) PARTITIONS 8;MySQL поддерживает
ALGORITHM
с
[SUB]PARTITION BY [LINEAR] KEY
. ALGORITHM=1
заставляет сервер использовать те же самые хеширующие ключ функции как в
MySQL 5.1, вычисляя размещение строк в разделении, ALGORITHM=2
указывает, что сервер использует хеширующие ключ функции, осуществленные и
используемые по умолчанию для новых разделенных таблиц
KEY
в MySQL 5.5 и выше.
Разделенные таблицы, составленные с хеширующими ключ функциями,
используемыми в MySQL 5.5 и позже, не могут использоваться MySQL 5.1.
Не определение опции имеет тот же самый эффект, как использование
ALGORITHM=2
. Эта опция предназначена для использования в
основном, обновляя или удаляя разделенные таблицы [LINEAR] KEY
между MySQL 5.1 и более поздними версиями MySQL, или для того, чтобы
составить таблицы, разделенные KEY
или
LINEAR KEY
в MySQL 5.5 или более позднем сервере, которые могут
использоваться на MySQL 5.1.
Чтобы обновить разделенную таблицу KEY
, которая была
составлена в MySQL 5.1, сначала выполните
SHOW CREATE TABLE
и отметьте точные столбцы и число показанного разделения. Теперь выполните
ALTER TABLE
, использующий точно тот же самый список столбцов и
число разделов, как в CREATE TABLE
, добавляя
ALGORITHM=2
сразу после PARTITION BY
.
Вы должны также включать LINEAR
, если это использовалось для
оригинального табличного определения. Пример сеанса в
mysql:
mysql> SHOW CREATE TABLE p\G *************************** 1. row *************************** Table: p Create Table: CREATE TABLE `p` ( `id` int(11) NOT NULL AUTO_INCREMENT, `cd` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LINEAR KEY (id) PARTITIONS 32 */ 1 row in set (0.00 sec) mysql> ALTER TABLE p PARTITION BY LINEAR KEY ALGORITHM=2 (id) PARTITIONS 32; Query OK, 0 rows affected (5.34 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> SHOW CREATE TABLE p\G *************************** 1. row *************************** Table: p Create Table: CREATE TABLE `p` ( `id` int(11) NOT NULL AUTO_INCREMENT, `cd` datetime NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LINEAR KEY (id) PARTITIONS 32 */ 1 row in set (0.00 sec)Понижение версии таблицы создало использование хеширования ключа значения по умолчанию, используемого в MySQL 5.5 и позже, позволяя его использование в MySQL 5.1, кроме как в случае использования
ALGORITHM=1
, чтобы
вынудить разделение таблицы быть восстановленным, используя хеширующие ключ
функции MySQL 5.1. Рекомендуется, чтобы Вы не делали этого кроме тех случаев,
когда необходимо для совместимости с MySQL 5.1, так как улучшенная функция
хеширования KEY
, используемая по умолчанию в MySQL 5.5 и позже,
обеспечивает затруднительные положения для многих проблем, найденных в
более старом исполнении.
Таблица, обновленная посредством ALTER TABLE ...
PARTITION BY ALGORITHM=2 [LINEAR] KEY ...
больше не может использоваться MySQL 5.1.
Такая таблица должна была бы быть удалена с ALTER TABLE ...
PARTITION BY ALGORITHM=1 [LINEAR] KEY ...
прежде, чем это могло использоваться снова MySQL 5.1.
Таблица, которая следует из использования ALTER TABLE
... PARTITION BY
должна следовать тем же самым правилам, как
создаваемая с CREATE TABLE ... PARTITION BY
.
Это включает правила, управляющие отношениями между любыми уникальными
ключами (включая любой первичный ключ), который таблица могла бы иметь, и
столбец или столбцы, используемые в выражении разделения, как обсуждено в
разделе 20.6.1. Правила CREATE TABLE ... PARTITION BY
для того, чтобы определить число разделов, также относятся к
ALTER TABLE ... PARTITION BY
.
partition_definition
для
ALTER TABLE ADD PARTITION
поддерживает те же самые опции как
параметр с тем же самым названием в
CREATE TABLE
(см.
раздел 14.1.15).
Предположим, что Вы создали разделенную таблицу как показано здесь:
CREATE TABLE t1 (id INT, year_col INT) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999));Вы можете добавить новый раздел
p3
к этой таблице для того, чтобы сохранить значения меньше 2002
:
ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));
ADD PARTITION
может также использоваться с
TABLESPACE
, чтобы добавить новый раздел к существующему общему
табличному пространству, к табличному пространству file-per-table
или к системному табличному пространству.
ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (2015) TABLESPACE = `ts1`); ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (2015) TABLESPACE = `innodb_file_per_table`); ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (2015) TABLESPACE = `innodb_system`);
Если опция TABLESPACE =
не определена, tablespace_name
ALTER TABLE ... ADD
PARTITION
добавляет раздел к табличному пространству по умолчанию
таблицы, которое может быть определено на табличном уровне во время
CREATE TABLE
или
ALTER TABLE
.
DROP PARTITION
может использоваться, чтобы удалить один или
больше разделов RANGE
или LIST
.
Этот запрос не может использоваться с HASH
или KEY
,
вместо этого используйте COALESCE PARTITION
.
Любые данные, которые хранились в удаленном разделе, названном в
partition_names
потеряны. Например, учитывая таблицу
t1
определенную ранее, Вы можете удалить разделы
p0
и p1
:
ALTER TABLE t1 DROP PARTITION p0, p1;
ADD PARTITION
и DROP PARTITION
в настоящее время не поддерживают IF [NOT] EXISTS
.
DISCARD
PARTITION ... TABLESPACE
и
IMPORT
PARTITION ... TABLESPACE
расширяют
мобильную
особенность табличного пространства на табличные разделы. Каждый раздел
InnoDB
имеет свой собственный файл табличного пространства
(.idb
).
Мобильная особенность облегчает копирование табличных пространств с
рабочего случая сервера MySQL на другой рабочий случай или выполнение
восстановления на том же самом случае. Обе опции берут список разделенных
запятой значений одного или более имен разделов. Например:
ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE; ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;При запуске
DISCARD
PARTITION ... TABLESPACE
и
IMPORT PARTITION ... TABLESPACE
на подразделенных таблицах позволены имена разделения и подразделения.
Когда имя разделения определено, подразделение того разделения включено.
Мобильная
особенность также поддерживает копирование или восстановление разделенных
таблиц InnoDB
(все разделение сразу). Для дополнительной
информации см. раздел 16.7.6.
Переименование разделенной таблицы поддержано. Вы можете переименовать
отдельное разделение, косвенно используя ALTER TABLE
... REORGANIZE PARTITION
, но эта работа делает копию данных.
Возможно удалить строки из выбранного разделения, используя
TRUNCATE PARTITION
. Эта опция берет список разделенных запятой
значений одного или более имен разделов. Рассмотрите таблицу t1
:
CREATE TABLE t1 (id INT, year_col INT) PARTITION BY RANGE (year_col) (PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999), PARTITION p3 VALUES LESS THAN (2003), PARTITION p4 VALUES LESS THAN (2007));Чтобы удалить все строки из раздела
p0
,
Вы можете использовать:
ALTER TABLE t1 TRUNCATE PARTITION p0;Это имеет тот же самый эффект, как этот
DELETE
:
DELETE FROM t1 WHERE year_col < 1991;Усекая много разделов, разделение не должно быть непрерывным: это может очень упростить операции на разделенных таблицах, которые иначе потребовали бы очень сложный
WHERE
при применении
DELETE
.
Например, этот запрос удаляет все строки из разделов
p1
и p3
:
ALTER TABLE t1 TRUNCATE PARTITION p1, p3;Аналогичный
DELETE
выглядит так:
DELETE FROM t1 WHERE (year_col >= 1991 AND year_col < 1995) OR (year_col >= 2003 AND year_col < 2007);Вы можете использовать ключевое слово
ALL
вместо списка имен разделов, в этом случае запрос действует на
все разделение в таблице.
TRUNCATE PARTITION
просто удаляет строки,
это не изменяет определение таблицы или любого ее раздела.
Вы можете проверить, что строки были удалены, проверяя
INFORMATION_SCHEMA.PARTITIONS
, используя такой запрос, как этот:
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1';
COALESCE PARTITION
может использоваться с таблицей, которая
разделена HASH
или KEY
, чтобы сократить количество
разделов number
. Предположите, что Вы составили таблицу
t2
:
CREATE TABLE t2 (name VARCHAR (30), started DATE) PARTITION BY HASH(YEAR(started)) PARTITIONS 6;Вы можете сократить количество разделов
t2
с 6 до 4:
ALTER TABLE t2 COALESCE PARTITION 2;Данные в последних разделах
number
слиты в остающиеся разделы. В этом случае разделы 4 и 5 будут слиты в первые
4 раздела (0, 1, 2 и 3).
Чтобы изменить некоторые, но не все разделы, Вы можете использовать
REORGANIZE PARTITION
. Этот запрос может
использоваться несколькими способами:
Слить ряд разделов в единственный раздел.
Это может быть сделано, называя несколько разделов в списке
partition_names
и заданием единственного определения
для partition_definition
.
partition_names
и несколько
partition_definitions
.VALUES LESS THAN
или значение для подмножества разделов,
определенного, используя VALUES IN
.Для разделения, которое явно не назвали, MySQL автоматически обеспечивает
имена по умолчанию p0
, p1
, p2
и т.д.
Это верно и относительно подразделов.
Для более подробной информации и примеров
ALTER TABLE ... REORGANIZE PARTITION
см.
раздел 20.3.1.
ALTER TABLE ... EXCHANGE
PARTITION
, то есть, чтобы переместить любые существующие строки в
разделение или подразделение к неразделенной таблице, и любые существующие
строки в неразделенной таблице к табличному разделению или подразделению.
См. раздел 20.3.3 .
CHECK TABLE
и
REPAIR TABLE
(которые также поддержаны для разделенных таблиц, см.
раздел 14.7.2).
Они включают ANALYZE PARTITION
, CHECK PARTITION
,
OPTIMIZE PARTITION
, REBUILD
PARTITION
и REPAIR PARTITION
.
Каждая из этих опций берет partition_names
, состоящий
из одного или более названий разделов, отделенных запятыми.
Разделение должно уже существовать в целевой таблице. Вы можете также
использовать ALL
вместо partition_names
,
когда запрос действует на все разделение в таблице. Для получения
дополнительной информации и примеров см.
раздел 20.3.4.
InnoDB
в настоящее время не поддерживает оптимизацию по разделам,
ALTER TABLE ... OPTIMIZE PARTITION
пересоздает и анализирует всю таблицу (Bug #11751825, Bug #42822).
Чтобы работать вокруг этой проблемы, используйте
ALTER TABLE ... REBUILD PARTITION
и
ALTER TABLE ... ANALYZE PARTITION
.
ANALYZE PARTITION
, CHECK PARTITION
,
OPTIMIZE PARTITION
и REPAIR PARTITION
не поддержаны для таблиц, которые не разделены.
REMOVE PARTITIONING
позволяет Вам удалить раздел таблицы,
не затрагивая таблицу или ее данные. Эта опция может быть объединена с
другими ALTER TABLE
,
например, добавить, удалить или переименовать столбцы или индексы.ENGINE
с
ALTER TABLE
, чтобы сменить
механизм хранения, используемый таблицей, не затрагивая разделение. Целевой
механизм хранения должен обеспечить свой собственный обработчик разделения.
Только InnoDB
и NDB
имеют родные обработчики
разделения, NDB
в настоящее время не поддерживается в MySQL 8.0.
ALTER TABLE
может содержать PARTITION BY
или
REMOVE PARTITIONING
в дополнении к другим изменениям технических
требований, но PARTITION BY
или REMOVE PARTITIONING
должен быть определен последний после любых других технических требований.
ADD PARTITION
, DROP
PARTITION
, COALESCE PARTITION
,
REORGANIZE PARTITION
, ANALYZE
PARTITION
, CHECK PARTITION
и
REPAIR PARTITION
не могут быть объединены с другими изменениями
технических требований в ALTER TABLE
. Для получения
дополнительной информации см.
раздел 14.1.7.1.
Только единственный случай любой из следующих опций может использоваться в
данном ALTER TABLE
:
PARTITION BY
, ADD PARTITION
,
DROP PARTITION
, TRUNCATE PARTITION
,
EXCHANGE PARTITION
, REORGANIZE PARTITION
или
COALESCE PARTITION
, ANALYZE PARTITION
,
CHECK PARTITION
, OPTIMIZE PARTITION
,
REBUILD PARTITION
, REMOVE PARTITIONING
.
Например, следующие два запроса недопустимы:
ALTER TABLE t1 ANALYZE PARTITION p1, ANALYZE PARTITION p2; ALTER TABLE t1 ANALYZE PARTITION p1, CHECK PARTITION p2;В первом случае Вы можете проанализировать разделы
p1
и p2
табьлицы t1
одновременно, используя единственный запрос ANALYZE PARTITION
,
который перечисляет оба раздела, что будет проанализировано так:
ALTER TABLE t1 ANALYZE PARTITION p1, p2;Во втором случае невозможно сделать
ANALYZE
и CHECK
на разных разделах той же самой таблицы одновременно. Вместо этого Вы должны
сделать два отдельных запроса:
ALTER TABLE t1 ANALYZE PARTITION p1; ALTER TABLE t1 CHECK PARTITION p2;
REBUILD
в настоящее время не поддерживаются для подразделения.
REBUILD
явно отвергнуто с подразделением, и
ALTER TABLE
выдаст ошибку.
CHECK PARTITION
и REPAIR PARTITION
терпят неудачу, когда разделение, которое будет проверено или восстановлено,
содержит любые ошибки дубликата ключа.
См. раздел 20.3.4.
Действия ALTER TABLE
, разрешенные для произведенных столбцов:
ADD
, MODIFY
и CHANGE
.
Могут быть добавлены произведенные столбцы.
ADD COLUMN
не оперативная работа для сохраненных столбцов
(обходится без использования временной таблицы), потому что выражение должно
быть оценено сервером. Для сохраненных столбцов индексирующие изменения
сделаны на месте, изменения выражения не сделаны на месте. Изменения
комментариев столбца сделаны на месте.ADD COLUMN
и DROP COLUMN
оперативные операции для виртуальных столбцов. Однако, добавление или
удаление виртуального столбца не может быть выполнено в комбинации с другим
ALTER TABLE
.InnoDB
допускает вторичные индексы
на произведенных виртуальных столбцах. Добавление или удаление вторичного
индекса на произведенном виртуальном столбце это оперативная работа.
Для получения дополнительной информации см.
раздел
14.1.15.6.VIRTUAL
добавлен к таблице или изменен, он не обеспечен данными, вычисляемыми
произведенным выражением столбца, неизвестно, не будут ли они вне диапазона
для столбца. Это может привести к непоследовательным возвращаемым данным и
неожиданным сбоям запросов. Чтобы решить, происходит ли проверка допустимости
для таких столбцов, ALTER TABLE
поддерживает опции
WITHOUT VALIDATION
и WITH VALIDATION
:
С WITHOUT VALIDATION
(значение по умолчанию, если
никакой пункт не определен), оперативная работа выполнена (если возможно),
целостность данных не проверена, и запрос заканчивается более быстро.
Однако, более поздние чтения таблицы могли бы сообщить о предупреждениях или
ошибках для столбца, если значения вне диапазона.
WITH VALIDATION
ALTER TABLE
копирует таблицу. Если ошибка происходят, запрос терпит неудачу. Поскольку
табличная копия выполнена, запрос занимает больше времени.WITHOUT VALIDATION
и WITH VALIDATION
разрешаются только с ADD COLUMN
, CHANGE COLUMN
и
MODIFY COLUMN
. Иначе происходит ошибка
ER_WRONG_USAGE
.
ALTER TABLE
заканчивается с ошибкой, и работа DDL отклонена.ALTER TABLE
, который
изменяет значение по умолчанию столбца col_name
,
также изменяет значение произведенного выражения столбца, которое обращается
к использованию столбца col_name
, что может изменить
значение произведенного выражения столбца, которое обращается к использованию
столбца DEFAULT(col_name
)
. Поэтому ALTER
TABLE
, который изменяет определение столбца, вызывает пересоздание
таблицы, если какое-либо произведенное выражение столбца использует
DEFAULT()
.
Начните с таблицы t1
. Она создается как показано здесь:
CREATE TABLE t1 (a INTEGER,b CHAR(10));Переименуем ее из
t1
в t2
:
ALTER TABLE t1 RENAME t2;Изменить столбец
a
с
INTEGER
на
TINYINT NOT NULL
(имя то же самое) и изменить столбец
b
с CHAR(10)
на CHAR(20)
с
переименованием этого с b
на c
:
ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);Добавить новый столбец
TIMESTAMP
d
:
ALTER TABLE t2 ADD d TIMESTAMP;Добавить индексирование на столбце
d
и индекс
UNIQUE
на a
:
ALTER TABLE t2 ADD INDEX (d), ADD UNIQUE (a);Удалить столбец
c
:
ALTER TABLE t2 DROP COLUMN c;Добавить новый столбец
AUTO_INCREMENT
целого числа
c
:
ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (c);Мы индексировали
c
(как PRIMARY KEY
), потому что
столбцы AUTO_INCREMENT
должны быть индексированы, и мы объявляем
c
как NOT NULL
, потому что столбцы первичного ключа
не могут быть NULL
.
Когда Вы добавляете AUTO_INCREMENT
, значения столбцов
заполнены порядковыми номерами автоматически. Для таблиц MyISAM
Вы можете установить первый порядковый номер, выполняя
SET INSERT_ID=
до
value
ALTER TABLE
или используя
опцию таблицы AUTO_INCREMENT=
. См.
раздел 6.1.5.value
С MyISAM
если Вы не изменяете столбец
AUTO_INCREMENT
, порядковый номер не затронут. Если Вы удаляете
AUTO_INCREMENT
и затем добавляете другой столбец
AUTO_INCREMENT
, числа повторно упорядочены, начиная с 1.
При использовании репликации, добавление столбца
AUTO_INCREMENT
к таблице не может произвести то же самое
упорядочивание строк на ведомом устройстве и ведущем устройстве. Это
происходит, потому что порядок, в котором пронумерованы строки, зависит от
определенного механизма хранения, используемого для таблицы и порядка, в
который были вставлены строки. Если важно иметь тот же самый порядок на
ведущее устройство и ведомое устройство, строки должны быть упорядочены
прежде, чем назначить число AUTO_INCREMENT
.
Допустим, что Вы хотите добавить AUTO_INCREMENT
к таблице
t1
, следующие запросы производят новую таблицу
t2
, идентичную t1
, но со столбцом
AUTO_INCREMENT
:
CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY) SELECT * FROM t1 ORDER BY col1, col2;Это предполагает, что таблица
t1
имеет столбцы
col1
и col2
.
Этот набор запросов также произведет новую таблицу t2
,
идентичную t1
, с добавлением столбца
AUTO_INCREMENT
:
CREATE TABLE t2 LIKE t1; ALTER TABLE t2 ADD id INT AUTO_INCREMENT PRIMARY KEY; INSERT INTO t2 SELECT * FROM t1 ORDER BY col1, col2;
Гарантировать то же самое упорядочивание на ведущем устройстве и на
ведомом устройстве всех столбцов t1
можно,
указанием в ORDER BY
.
Независимо от метода, используемого, чтобы создать и заполнить копию,
имеющую столбец AUTO_INCREMENT
, заключительный шаг должен
удалить оригинальную таблицу и затем переименовать копию:
DROP TABLE t1; ALTER TABLE t2 RENAME t1;
ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = {Этот запрос изменяет определение представления, которое должно существовать. Синтаксис подобенuser
| CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER }] VIEWview_name
[(column_list
)] ASselect_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
CREATE VIEW
,
эффект тот же самый, как для CREATE OR
REPLACE VIEW
. См. раздел 14.1.18.
Это запрос требует привилегий
CREATE VIEW
и DROP
для представления и некоторой привилегии для каждого столбца,
упомянутого в SELECT
.
ALTER VIEW
разрешен только определителю или пользователям с привилегией
SUPER
.
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS]db_name
[create_specification
] ...create_specification
: [DEFAULT] CHARACTER SET [=]charset_name
| [DEFAULT] COLLATE [=]collation_name
CREATE DATABASE
создает базу данных с именем. Чтобы использовать этот запрос, Вы нуждаетесь в
привилегии CREATE
для базы данных. CREATE SCHEMA
это синоним для CREATE DATABASE
.
Ошибка происходит, если база данных существует, и Вы не определяли
IF NOT EXISTS
.
В MySQL 8.0 CREATE DATABASE
не разрешен в пределах сеанса, у которого есть активный
LOCK TABLES
.
create_specification
определяют характеристики базы
данных. Характеристики базы данных сохранены в словаре данных.
CHARACTER SET
определяет набор символов базы данных по
умолчанию. COLLATE
определяет сопоставление базы данных
по умолчанию. Раздел 11.1
обсуждает имена сопоставления и набора символов.
База данных в MySQL осуществлена как каталог, содержащий файлы, которые
соответствуют таблицам в базе данных. Поскольку нет никаких таблиц в базе
данных, когда это первоначально создается,
CREATE DATABASE
создает только каталог в соответствии с каталогом данных MySQL. Правила для
допустимых имен базы данных даны в
разделе 10.2.
Если имя базы данных содержит специальные символы, название каталога базы
данных содержит закодированные версии тех символов как описано в
разделе 10.2.3.
Создание каталога базы данных, вручную создавая каталог в соответствии с каталогом данных (например, с помощью mkdir) временно не поддержано в MySQL 8.0.0.
Вы можете также использовать mysqladmin, чтобы создать базы данных. См. раздел 5.5.2.
CREATE [DEFINER = {Этот запрос создает и намечает новое событие. Оно не будет работать, если Планировщик Событий не будет включен. Для информации о проверке состояния Планировщика Событий и включении в случае необходимости см. раздел 21.4.2.user
| CURRENT_USER }] EVENT [IF NOT EXISTS]event_name
ON SCHEDULEschedule
[ON COMPLETION [NOT] PRESERVE] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'comment
'] DOevent_body
;schedule
: ATtimestamp
[+ INTERVALinterval
] ... | EVERYinterval
[STARTStimestamp
[+ INTERVALinterval
] ...] [ENDStimestamp
[+ INTERVALinterval
] ...]interval
:quantity
{YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
CREATE EVENT
требует
привилегию EVENT
для схемы, в которой должно быть создано событие. Это могло бы также
потребовать привилегию SUPER
, в зависимости от значения DEFINER
,
как описано позже в этом разделе.
Минимальные требования для допустимого
CREATE EVENT
:
Ключевые слова CREATE EVENT
с именем, которое уникально идентифицирует событие
в схеме базы данных.
ON SCHEDULE
, который определяет, когда и как
часто случай выполняется.DO
, который содержит запрос SQL,
который будет выполнен.Это пример минимального CREATE EVENT
:
CREATE EVENT myevent ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO UPDATE myschema.mytable SET mycol = mycol + 1;Предыдущий запрос создает событие
myevent
.
Это выполняется однажды в один час после его создания, выполняя запрос SQL,
который постепенно увеличивает значение столбца mycol
в таблице myschema.mytable
на 1.
event_name
должен быть допустимым идентификатором
MySQL с максимальной длиной 64 символа. Имена событий не являются
чувствительными к регистру, таким образом, у Вас не может быть двух событий,
названных myevent
и MyEvent
в той же самой схеме.
Вообще, правила, управляющие именами событий, являются теми же самыми, как
для названий сохраненных подпрограмм. См.
раздел 10.2.
Событие связано со схемой. Если никакая схема не обозначена как часть
event_name
, значение по умолчанию (текущая схема)
принято. Чтобы создать событие в определенной схеме, квалифицируйте имя
события с использованием имени схемы
.schema_name
.event_name
DEFINER
определяет учетную запись MySQL, которая будет
использоваться, проверяя привилегии доступа во время выполнения событий. Если
user
дано, это должна быть учетная запись MySQL,
определенная как '
,
user_name
'@'host_name
'CURRENT_USER
или
CURRENT_USER()
.
Значение по умолчанию DEFINER
: пользователь, который выполняет
CREATE EVENT
.
Это то же самое, как определение DEFINER = CURRENT_USER
.
Если Вы определяете DEFINER
,
эти правила определяют допустимые
пользовательские значения DEFINER
:
Если Вы не имеете привилегии
SUPER
, единственное разрешенное значение
user
Ваша собственная учетная запись, определенная
буквально или при использовании
CURRENT_USER
. Вы не можете установить определение в
некоторую другую учетную запись.
SUPER
, Вы можете определить любое синтаксически допустимое имя учетной
записи. Если учетная запись не существует, предупреждение произведено.DEFINER
,
ошибка происходит во время выполнения событий, если учетная
запись не существует.См. раздел 21.6.
В пределах события
CURRENT_USER()
возвращает учетную запись для проверки
привилегии во время выполнения события, то есть DEFINER
. См.
раздел 7.3.12.
IF NOT EXISTS
для
CREATE EVENT
имеет тот же
смысл, как для CREATE TABLE
:
если событие уже существует в той же самой схеме, никакие меры не
предприняты и никакой ошибки нет. (днако, предупреждение будет
произведено в таких случаях.
ON SCHEDULE
определяет когда, как часто, и как долго
event_body
определен для повторений событий.
Этот пункт принимает одну из двух форм:
AT
используется для одноразового случая. Это определяет, что событие
выполняется только один раз в дату и время, заданные
timestamp
timestamp
, что должно включать дату и время или должно
быть выражением, которое решается к значению datetime.
Вы можете использовать значение любого типа
DATETIME
или
TIMESTAMP
с этой целью. Если
дата в прошлом, происходит предупреждение, как показано здесь:
mysql> SELECT NOW(); +---------------------+ | NOW() | +---------------------+ | 2006-02-10 23:59:01 | +---------------------+ 1 row in set (0.04 sec) mysql> CREATE EVENT e_totals -> ON SCHEDULE AT '2006-02-10 23:59:00' -> DO INSERT INTO test.totals VALUES (NOW()); Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Note Code: 1588 Message: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation.
CREATE EVENT
, которые
являются самостоятельно неправильными, терпят неудачу с ошибкой.
Вы можете использовать
CURRENT_TIMESTAMP
, чтобы определить текущую дату и время.
В таком случае событие действует как только создается.
Создать событие, которое происходит в некоторый момент в будущем
относительно текущей даты и времени, скажем,
спустя три недели, можно, если использовать
дополнительный параметр + INTERVAL
. interval
interval
состоит из двух частей, количества
и единицы времени, и следует тем же самым правилам синтаксиса, которые
управляют интервалами, используемыми в функции
DATE_ADD()
(см.
раздел 13.7.
Ключевые слова модулей такие же, за исключением того, что Вы не можете
использовать модули, вовлекающие микросекунды, определяя событие. С
некоторыми типами интервала могут использоваться сложные единицы измерения
времени. Например, две минуты и десять секунд
может быть выражено как + INTERVAL '2:10' MINUTE_SECOND
.
Вы можете также объединить интервалы. Например, AT
CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY
задает
через три недели и два дня.
Каждая часть такого пункта должна начинаться с + INTERVAL
.
EVERY
. Ключевое слово EVERY
сопровождается
interval
, как описано в предыдущем обсуждении
параметра AT
. + INTERVAL
не
используется с EVERY
. Например, EVERY 6 WEEK
значит
каждые шесть недель.
Хотя + INTERVAL
не разрешены в EVERY
,
Вы можете использовать те же самые сложные единицы измерения времени,
разрешенные в + INTERVAL
.
EVERY
может содержать дополнительный параметр
STARTS
. STARTS
сопровождается
timestamp
, которое указывает, когда действие должно
начать повторяться, и может также использовать + INTERVAL
, чтобы определить количество времени
с текущего момента. Например,
interval
EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK
значит
каждые три месяца, начиная через одну неделю с текущего момента
. Точно так же Вы можете выразить каждые две
недели, начиная через шесть часов и пятнадцать минут с текущего момента
как EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL
'6:15' HOUR_MINUTE
. Не определение STARTS
аналогично
STARTS CURRENT_TIMESTAMP
, то есть, действие, определенное для
события, начинает повторяться непосредственно после создания.
EVERY
может содержать дополнительное ключевое слово
ENDS
. ENDS
сопровождается
timestamp
, которое говорит MySQL, когда событие должно
прекратить повторяться. Вы можете также использовать + INTERVAL
с interval
ENDS
, например,
EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS
CURRENT_TIMESTAMP + INTERVAL 4 WEEK
значит
каждые двенадцать часов, начиная через тридцать минут с этого
времени, и заканчивая через четыре недели с этого времени.
Не использование ENDS
значит, что событие
продолжает запускаться неопределенное число раз.
ENDS
поддерживает тот же самый синтаксис для сложных единиц
измерения времени, как STARTS
.
Вы можете использовать STARTS
, ENDS
, оба
или ни один в EVERY
.
Если повторяющееся событие не заканчивается в пределах его интервала
планирования, результат может быть многократными случаями события,
выполняющегося одновременно. Если это нежелательно, Вы должны установить
механизм, чтобы предотвратить одновременные случаи. Например, Вы могли
использовать функцию GET_LOCK()
, строчную или табличную блокировку.
ON SCHEDULE
может использовать выражения, вовлекающие
встроенные функции MySQL и пользовательские переменные, чтобы получить любое
из значений timestamp
или interval
, которые это содержит. Вы не можете использовать сохраненные функции
или определяемые пользователем функции в таких выражениях, и при этом Вы не
можете использовать табличные ссылки, однако, Вы можете использовать
SELECT FROM DUAL
. Это верно для
CREATE EVENT
и
ALTER EVENT
.
Ссылки на сохраненные функции, определяемые пользователем функции и таблицы в
таких случаях определенно не разрешены и терпят неудачу с ошибкой (Bug
#22830).
Времена в ON SCHEDULE
интерпретируются, используя значение
time_zone
текущего
сеанса. Это становится часовым поясом событий, то есть, часовой пояс, который
используется для планирования события, является текущим в пределах
события при выполнении. Эти времена преобразованы в UTC и сохранены наряду с
часовым поясом событий в таблице mysql.event
.
Это позволяет выполнению событий продолжиться как определено, независимо от
любых последующих изменений часового пояса сервера или эффектов летнего
времени. Для дополнительной информации о представлении времен событий см.
раздел 21.4.4. См. также разделы
14.7.5.18 и
22.7.
Обычно как только событие истекло, оно немедленно удалено.
Вы можете переопределить это поведение, определяя ON COMPLETION
PRESERVE
. Использование ON COMPLETION NOT PRESERVE
просто делает поведение по умолчанию явным.
Вы можете создать событие, но препятствовать тому, чтобы это было активно,
использованием ключевого слова DISABLE
.
Альтернативно, Вы можете использовать ENABLE
, чтобы
сделать явным состояние значения по умолчанию, которое является активным. Это
является самым полезным в соединении с
ALTER EVENT
(см. раздел 14.1.2).
Третье значение может также появиться вместо
ENABLE
или DISABLE
:
DISABLE ON SLAVE
установлен для состояния события на ведомом
устройстве, чтобы указать, что событие создавалось на ведущем устройстве и
копировалось к ведомому устройству, но не запущено на ведомом устройстве. См.
раздел 19.4.1.12.
Вы можете поставлять комментарий для события через
COMMENT
. comment
может быть любая строка до 64 символов, которые Вы хотите использовать для
того, чтобы описать случай. Текст комментария, будучи буквальной строкой,
должен быть окружен кавычками.
DO
определяет действие, которое
выполняет событие, и состоит из запросов SQL. Почти любой допустимый запрос
MySQL, который может использоваться в сохраненной подпрограмме, может также
использоваться в качестве действия для запланированного события, см.
раздел C.1.
Например, следующее событие e_hourly
удаляет все строки из
таблицы sessions
однажды в час, где эта таблица является частью
схемы site_activity
:
CREATE EVENT e_hourly ON SCHEDULE EVERY 1 HOUR COMMENT 'Clears out sessions table each hour.' DO DELETE FROM site_activity.sessions;MySQL хранит
sql_mode
,
когда событие создано или изменено, и всегда запускает событие с этой
установкой в силе, независимо от текущего режима SQL сервера, когда
событие начинает выполняться.
CREATE EVENT
,
который содержит ALTER EVENT
в DO
, кажется, преуспевает, однако,
когда сервер пытается запустить получающееся запланированное событие,
выполнение терпит неудачу с ошибкой.
Такие запросы, как SELECT
или
SHOW
, которые
просто возвращают набор результатов, не имеют никакого эффекта, когда
используются в событии: вывод от них не посылают MySQL Monitor,
и при этом он не сохранен нигде. Однако, Вы можете использовать такие
запросы, как SELECT ... INTO
и
INSERT INTO ... SELECT
,
которые сохраняют результат. См. следующий пример в этом разделе
для последнего случая.
Схема, которой принадлежит событие, является схемой по умолчанию для
табличных ссылок в DO
.
Любые ссылки на таблицы в других схемах должны быть квалифицированы с
надлежащим именем схемы.
Как с сохраненными подпрограммами, Вы можете использовать синтаксис
составного запроса DO
с ключевыми
словами BEGIN
и END
:
delimiter | CREATE EVENT e_daily ON SCHEDULE EVERY 1 DAY COMMENT 'Saves total number of sessions then clears the table each day' DO BEGIN INSERT INTO site_activity.totals (time, total) SELECT CURRENT_TIMESTAMP, COUNT(*) FROM site_activity.sessions; DELETE FROM site_activity.sessions; END | delimiter ;Этот пример использует команду
delimiter
, чтобы изменить
разделитель запроса. См. раздел
21.1.
Более сложные составные запросы, такие как используемые в сохраненных подпрограммах, возможны в событии. Этот пример использует местные переменные, обработчик ошибок и конструкцию управления потоками:
delimiter | CREATE EVENT e ON SCHEDULE EVERY 5 SECOND DO BEGIN DECLARE v INTEGER; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; SET v = 0; WHILE v < 5 DO INSERT INTO t1 VALUES (0); UPDATE t2 SET s1 = s1 + 1; SET v = v + 1; END WHILE; END | delimiter ;Нет никакого способа передать параметры непосредственно к или от событий, однако, возможно вызвать сохраненную подпрограмму с параметрами в пределах события:
CREATE EVENT e_call_myproc ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY DO CALL myproc(5, 27);Если определитель имеет привилегию
SUPER
, событие может читать и писать глобальные переменные.
Поскольку предоставление этой привилегии влечет за собой потенциал для
злоупотребления, экстремальная забота должна быть проявлена при этом.
Вообще, любые запросы , которые допустимы в сохраненных подпрограммах, могут использоваться для запросов действия, выполненных событиями. Для получения дополнительной информации о запросах, допустимых в пределах сохраненных подпрограмм см. раздел 21.2.1. Вы можете создать событие как часть сохраненной подпрограммы, но событие не может быть создано другим событием.
CREATE FUNCTION
используется, чтобы создать сохраненные функции и определяемые
пользователем функции (UDF):
Для информации о создании сохраненных функций см. раздел 14.1.13.
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEXindex_name
[index_type
] ONtbl_name
(index_col_name
,...) [index_option
] [algorithm_option
|lock_option
] ...index_col_name
:col_name
[(length
)] [ASC | DESC]index_type
: USING {BTREE | HASH}index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| WITH PARSERparser_name
| COMMENT 'string
' | {VISIBLE | INVISIBLE}algorithm_option
: ALGORITHM [=] {DEFAULT|INPLACE|COPY}lock_option
: LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
CREATE INDEX
отображен на
ALTER TABLE
, чтобы создать
индекс. См. раздел 14.1.7.
CREATE INDEX
не может использоваться, чтобы создать PRIMARY KEY
, используйте
ALTER TABLE
. См.
раздел 9.3.1.
Обычно Вы создаете все индексы на таблице в то время, когда таблица
составлена с CREATE TABLE
.
См. раздел 14.1.15. Это особенно важно для
InnoDB
, где первичный ключ определяет
физическое расположение строк в файле с данными.
CREATE INDEX
позволяет добавить индекс к существующим таблицам.
Список столбцов формы (col1,col2,...)
создает многостолбцовый индекс, значения ключа, сформированы, связывая
значения данных столбцов.
Для строковых столбцов может быть создан индекс, который использует только
ведущую часть значений столбцов, используя
,
чтобы определить длину префикса:col_name
(length
)
Префиксы могут быть определены для столбцов
CHAR
,
VARCHAR
,
BINARY
и
VARBINARY
.
BLOB
и
TEXT
.CREATE TABLE
,
ALTER TABLE
и
CREATE INDEX
интерпретируется как число символов для недвоичных строковых типов
(CHAR
,
VARCHAR
,
TEXT
)
и число байтов для двоичных строковых типов
(BINARY
,
VARBINARY
,
BLOB
).
Примите это во внимание, определяя длину префикса для недвоичного строкового
столбца, который использует многобайтовый набор символов.Запрос, показанный здесь, создает индекс с использованием первых 10
символов столбца name
(принимая, что
name
имеет недвоичной строковый тип):
CREATE INDEX part_of_name ON customer (name(10));Если имена в столбце обычно отличаются по первым 10 символам, это не должно быть намного медленнее, чем индекс, создаваемый из всего
name
. Кроме того, использование приставок столбца для индекса
может сделать индексный файл намного меньшим, что может сохранить много
дискового пространства и может также убыстрить
INSERT
.
Поддержка префиксов и длины (где поддержано) зависят от
механизма хранения. Например, приставка может составить до 767
байтов для InnoDB
, которые используют
формат строки
REDUNDANT
или
COMPACT
. Предел длины поднят до 3072 байтов для таблиц
InnoDB
, которые используют формат строки
DYNAMIC
или
COMPRESSED
. Для MyISAM
предел префикса составляет 1000 байтов.
Индекс UNIQUE
создает ограничение, таким образом, что все
значения в индексе должны быть отличными. Ошибка происходит, если Вы
пытаетесь добавить новую строку со значением ключа, которое соответствует
существующей строке. Для всех механизмов UNIQUE
допускает многократные NULL
для столбцов, которые могут
содержать NULL
. Если Вы определяете префикс столбца в
UNIQUE
, значения столбцов должны быть
уникальными в пределах префикса.
FULLTEXT
поддержаны только для
InnoDB
и
MyISAM
и могут включать только столбцы
CHAR
,
VARCHAR
и
TEXT
.
Индексация всегда происходит по всему столбцу. Префиксы столбца не
поддержаны, любая длина префикса проигнорирована, если определена. См.
раздел 13.9.
MyISAM
,
InnoDB
,
NDB
и
ARCHIVE
поддерживают пространственные столбцы, например,
POINT
и
GEOMETRY
.
См. раздел 12.5.
Однако, поддержка пространственной индексации столбца изменяется среди
механизмов. Пространственный и непространственный индексы доступны,
согласно следующим правилам.
Пространственный индекс (создаваемый использованием
SPATIAL INDEX
) имееет эти характеристики:
Доступный только для InnoDB
и MyISAM
.
Определение SPATIAL INDEX
для другого механизма
хранения приводит к ошибке.
NOT NULL
.Характеристики непространственных индексов (создаваемых с
INDEX
, UNIQUE
или PRIMARY KEY
):
Разрешены для любого механизма хранения, который поддерживает
пространственные столбцы, кроме
ARCHIVE
.
NULL
, если индексирование
не является первичным ключом.SPATIAL
индексе,
кроме столбцов POINT
,
длина префикса столбца должна быть определена. Это же самое требование
касается индексирования столбцов BLOB
. Длина префикса дана в байтах.SPATIAL
индекса
зависит от механизма хранения. В настоящее время используется B-tree.NULL
, только для InnoDB
,
MyISAM
и
MEMORY
.BLOB
или
TEXT
только для InnoDB
и
MyISAM
.
innodb_stats_persistent
, выполняется
ANALYZE TABLE
для таблицы
InnoDB
после создания индекса на этой таблице.InnoDB
допускает вторичные индексы
на виртуальных столбцах. Для получения дополнительной информации см.
раздел
14.1.15.6.
index_col_name
может закончиться
ASC
или DESC
. Эти ключевые слова разрешены для
будущих расширений для того, чтобы определить, что возрастание или убывание
индекса хранится. В настоящее время они разобраны, но проигнорированы,
индексные значения всегда сохранены в порядке возрастания.
После списка столбцов индекса могут быть даны опции.
Значение index_option
может быть любым следующим:
KEY_BLOCK_SIZE [=]
value
Для MyISAM
KEY_BLOCK_SIZE
произвольно определяет размер в байтах, чтобы
использовать для ключевых блоков индекса.
Значение обработано как подсказка, иной размер может использоваться в случае
необходимости. KEY_BLOCK_SIZE
, определенное для индивидуального
определения индекса, переопределяет KEY_BLOCK_SIZE
на уровне таблицы.
KEY_BLOCK_SIZE
не поддержан на уровне индексов для таблиц
InnoDB
. См.
раздел 14.1.15.
index_type
Некоторые механизмы хранения разрешают Вам определять тип индекса,
создавая индекс.
Таблица 14.1 показывает допустимые значения типа, поддержанные различными
механизмами хранения. Где указано несколько типов, первый это значение по
умолчанию, когда не дан спецификатор типа. Механизмы хранения, не
перечисленные в таблице, не поддерживают index_type
.
Таблица 14.1. Типы индексов в механизмах хранения
Механизм хранения | Допустимые типы |
---|---|
InnoDB |
BTREE |
MyISAM
| BTREE |
MEMORY
/HEAP | HASH , BTREE
|
NDB | HASH ,
BTREE |
Пример:
CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index ON lookup (id) USING BTREE;
index_type
не может использоваться для
FULLTEXT INDEX
или SPATIAL INDEX
.
Если Вы определяете тип индекса, который не допустим для данного механизма
хранения, но доступен другой тип, который механизм может использовать, не
затрагивая результаты запроса, механизм использует доступный тип. Анализатор
признает RTREE
как имя типа, но в настоящее время это не может
быть определено ни для какого механизма хранения.
Использование опции index_type
перед
ON
устарело,
поддержка использования опции в этой позиции будет удалена в будущем выпуске
MySQL. Если tbl_name
index_type
дана в ранней и в более поздней
позиции, заключительная опция применяется.
TYPE
синоним для type_name
USING
.
Но type_name
USING
привилегированная форма.
Для механизмов хранения, которые поддерживают
index_type
,
таблица 14.2 показывает некоторые характеристики индексов.
Таблица 14.2. Характеристики индексов
Механизм хранения | Индексный тип | Класс индекса | Хранит NULL? | Разрешены многократные NULL? | Тип просмотра IS NULL | Тип просмотра IS NOT NULL |
---|---|---|---|---|---|---|
InnoDB |
BTREE | Primary key | Нет | Нет | Нет данных | Нет данных |
Unique | Да | Да | Index | Index | ||
Key | Да | Да | Index | Index | ||
Неприменимо | FULLTEXT |
Да | Да | Table | Table | |
Неприменимо | SPATIAL |
Нет | Нет | Нет данных | Нет данных | |
MyISAM |
BTREE | Primary key | Нет | Нет | Нет данных | Нет данных |
Unique | Да | Да | Index | Index | ||
Key | Да | Да | Index | Index | ||
Неприменимо | FULLTEXT | Да | Да | Table | Table | |
Неприменимо | SPATIAL | Нет | Нет | Нет данных | Нет данных | |
MEMORY |
HASH | Primary key | Нет | Нет | Нет данных | Нет данных |
Unique | Да | Да | Index | Index | ||
Key | Да | Да | Index | Index | ||
BTREE |
Primary | Нет | Нет | Нет данных | Нет данных | |
Unique | Да | Да | Index | Index | ||
Key | Да | Да | Index | Index |
WITH PARSER parser_name
Эта опция может использоваться только с FULLTEXT
.
Это связывает плагин анализатора с индексированием, если полнотекстовая
индексация и поиск операций нуждаются в специальной обработке.
InnoDB
и
MyISAM
поддерживают полнотекстовые плагины анализатора. См.
раздел 26.2.4.4.
COMMENT 'string
'
Индексное определение может включать дополнительный комментарий до 1024 символов.
MERGE_THRESHOLD
указывает, как индексные страницы могут быть сконфигурированы для
индивидуального индекса использованием
index_option
и COMMENT
в
CREATE INDEX
:
CREATE TABLE t1 (id INT); CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';Если процент заполнения для индексной страницы падает ниже
MERGE_THRESHOLD
, когда строка удалена или когда строка сокращена
работой обновления, InnoDB
пытается слить индексную страницу с соседней индексной страницей. Значение по
умолчанию MERGE_THRESHOLD
50.
MERGE_THRESHOLD
может также быть определен на уровне индекса
и таблицы через CREATE TABLE
и ALTER TABLE
, см.
раздел 16.6.11.
VISIBLE
, INVISIBLE
Изменяет невидимость, индексы видимы по умолчанию.
Невидимый индекс не используется оптимизатором. Модификация невидимости
индекса относится к первичным ключам (явным или неявным). С MySQL 8.0.1
эта особенность нейтральна для механизма хранения (поддержана для любого
механизма). В MySQL 8.0.0 это применяется только к InnoDB
, см.
раздел 9.3.10.
ALGORITHM
и LOCK
могут быть даны, чтобы влиять
на табличный метод копирования и уровень параллелизма для чтения и записи
таблицы в то время, как индексы изменяются. У них есть то же самое значение,
что в ALTER TABLE
. См.
раздел 14.1.7
CREATE [DEFINER = {Эти запросы создают сохраненные подпрограммы. По умолчанию подпрограмма связана с базой данных значения по умолчанию. Чтобы связать подпрограмму явно с данной базой данных, определите имя какuser
| CURRENT_USER }] PROCEDUREsp_name
([proc_parameter
[,...]]) [characteristic
...]routine_body
CREATE [DEFINER = {user
| CURRENT_USER }] FUNCTIONsp_name
([func_parameter
[,...]]) RETURNStype
[characteristic
...]routine_body
proc_parameter
: [ IN | OUT | INOUT ]param_name
type
func_parameter
:param_name
type
type
:Any valid MySQL data type
characteristic
: COMMENT 'string
' | LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER }routine_body
:Valid SQL routine statement
db_name.sp_name
, когда Вы создаете это.
CREATE FUNCTION
также используется в MySQL, чтобы поддержать UDF (определяемые пользователем
функции). См. раздел 26.4.
UDF может быть расценен как внешняя сохраненная функция. Сохраненные функции
совместно используют свое пространство имен с UDF. См.
раздел 10.2.4.
Чтобы вызвать хранимую процедуру, используйте
CALL
(см.
раздел 14.2.1).
Чтобы вызвать сохраненную функцию, обратитесь к ней в выражении.
Функция возвращает значение во время оценки выражения.
CREATE PROCEDURE
и
CREATE FUNCTION
требуют
привилегию CREATE ROUTINE
. Они могли бы также потребовать привилегию
SUPER
, в зависимости от
значения DEFINER
, как описано позже в этом разделе. Если
двоичное журналирование включено,
CREATE FUNCTION
может потребовать привилегию
SUPER
, см.
раздел 21.7.
По умолчанию MySQL автоматически предоставляет привилегии
ALTER ROUTINE
и
EXECUTE
создателю подпрограммы. Это поведение может быть изменено, отключая
automatic_sp_privileges
. См.
раздел 21.2.2.
DEFINER
и SQL SECURITY
определяют контекст безопасности, который будет использоваться, проверяя
привилегии доступа в обычное время выполнения, как описано
позже в этом разделе.
Если имя подпрограммы совпадает с названием встроенной функции SQL, синтаксическая ошибка происходит, если Вы не используете пробел между именем и следующей круглой скобкой, определяя подпрограмму или вызывая это позже. Поэтому избегайте использования названий существующих функций SQL для Ваших собственных сохраненных подпрограмм.
Режим SQL IGNORE_SPACE
относится к встроенным функциям, но не к сохраненным
подпрограммам. Всегда допустимо иметь пробелы после имени сохраненной
подпрограммы, независимо от
IGNORE_SPACE
значения.
Список параметров в пределах круглых скобок должен всегда присутствовать.
Если нет никаких параметров, пустой список параметров ()
применен. Названия параметра не являются чувствительными к регистру.
Каждый параметр IN
это параметр по умолчанию. Чтобы
определить иное для параметра, используйте ключевое слово
OUT
или INOUT
перед названием параметра.
Определение параметра как IN
,
OUT
или INOUT
допустимо только для
PROCEDURE
. Для FUNCTION
параметры всегда расцениваются как IN
.
IN
передает значение в процедуру. Процедура могла бы изменить
значение, но модификация не видна вызывающему, когда процедура возвращается.
OUT
передает значение из процедуры назад. Его начальное значение
NULL
в пределах процедуры, и значение видимо вызывающему, когда
процедура возвращается. INOUT
инициализирован вызывающим, может
быть изменен процедурой, и любое изменение, произведенное процедурой, видимо
вызывающему, когда процедура возвращается.
Для каждого OUT
или INOUT
передайте определяемую пользователем переменную в
CALL
, которое вызывает процедуру так,
чтобы Вы могли получить ее значение, когда процедура возвращается. Если Вы
вызываете процедуру изнутри другой хранимой процедуры или функции, Вы можете
также передать параметр или местную переменную как
IN
или INOUT
.
На параметры нельзя сослаться в запросах, подготовленных в пределах подпрограммы, см. раздел C.1 .
Следующий пример показывает простую хранимую процедуру,
которая использует OUT
:
mysql> delimiter // mysql> CREATE PROCEDURE simpleproc (OUT param1 INT) -> BEGIN -> SELECT COUNT(*) INTO param1 FROM t; -> END// Query OK, 0 rows affected (0.00 sec) mysql> delimiter ; mysql> CALL simpleproc(@a); Query OK, 0 rows affected (0.00 sec) mysql> SELECT @a; +----+ | @a | +----+ | 3 | +----+ 1 row in set (0.00 sec)Пример использует команду
delimiter
, чтобы изменить разделитель
запросов с ;
на //
в то время, как процедура
определяется. Это позволяет разделитель ;
, используемый в теле
процедуры, который пройдет к серверу вместо того, чтобы интерпретироваться
mysql. См.
раздел 21.1.
RETURNS
может быть определен только для
FUNCTION
, для которой это принудительно. Это указывает на тип
возврата функции, и функциональное тело должно содержать команду
RETURN
. Если
value
RETURN
возвращает значение
иного типа, значение приведено к надлежащему типу. Например, если функция
определяет ENUM
или
SET
в RETURNS
, но
RETURN
возвращает целое число, значение, возвращенное из функции, является строкой
для передачи члена ENUM
или
SET
.
Следующая функция в качестве примера берет параметр, выполняет работу,
используя функцию SQL, и возвращает результат. В этом случае не нужно
использовать delimiter
, потому что функциональное определение
не содержит внутренний ;
:
mysql> CREATE FUNCTION hello (s CHAR(20)) mysql> RETURNS CHAR(50) DETERMINISTIC -> RETURN CONCAT('Hello, ',s,'!'); Query OK, 0 rows affected (0.00 sec) mysql> SELECT hello('world'); +----------------+ | hello('world') | +----------------+ | Hello, world! | +----------------+ 1 row in set (0.00 sec)Типы параметра и функциональные типы возвращения используют любой допустимый тип данных.
COLLATE
может использоваться, если предшествующий
признак CHARACTER SET
.
routine_body
состоит из допустимых запросов SQL.
Это может быть простым запросом, например,
SELECT
или
INSERT
,
или составным запросом с BEGIN
и END
.
Составные запросы могут содержать декларации, циклы и другие проверки
утверждения структуры. Синтаксис для этих запросов описан в
разделе 14.6.
MySQL разрешает подпрограммам содержать запросы DDL, такие как
CREATE
и DROP
. MySQL также разрешает хранимым
процедурам (но не сохраненным функциям) содержать операционные запросы SQL,
такие как COMMIT
.
Сохраненные функции, возможно, не содержат запросы, которые явно или неявно
закрывают транзакцию. Поддержка этих запросов не требуется стандартом SQL,
который заявляет, что каждый поставщик системы управления базами данных может
решить, разрешить ли их.
Запросы, которые возвращают набор результатов, могут использоваться в
пределах хранимой процедуры, но не в пределах сохраненной функции. Этот
запрет включает SELECT
, которые не
имеют INTO
, и другие запросы,
например, var_list
SHOW
,
EXPLAIN
и
CHECK TABLE
.
Для запросов, которые могут возвратить набор результатов, происходит ошибка
Not allowed to return a result set from a function
(ER_SP_NO_RETSET
).
Для запросов, которые могут во времени выполнения возвратить набор
результатов, происходит ошибка PROCEDURE %s can't return a result set
in the given context
(
ER_SP_BADSELECT
).
USE
в пределах сохраненных
подпрограмм не разрешены. Когда подпрограмма вызвана, неявный
USE
выполнен (и отменен, когда
подпрограмма заканчивается). Это сделано, чтобы иметь базу данных по
умолчанию, в то время как подпрограмма выполняется. Ссылки на объекты в базах
данных кроме базы данных значения по умолчанию должны быть квалифицированы с
соответствующим именем базы данных.db_name
MySQL хранит sql_mode
, установленную, когда подпрограмма создана или изменена, и всегда
выполняет подпрограмму с этой установкой,
независимо от текущего режима SQL сервера, когда
подпрограмма начинает выполняться.
Переключение режима SQL происходит после оценки параметров и назначения получающихся значений параметрам. Если Вы определяете подпрограмму в строгом режиме SQL, но вызываете в нестрогом режиме, назначение параметров обычным параметрам не имеет места в строгом режиме. Если Вы требуете, чтобы выражения, которые передают подпрограмме, были назначены в строгом режиме SQL, Вы должны вызвать подпрограмму со строгим режимом.
COMMENT
расширение MySQL, и может использоваться, чтобы
описать сохраненную подпрограмму. Эта информация выведена на экран
SHOW CREATE PROCEDURE
и SHOW CREATE FUNCTION
.
LANGUAGE
указывает на язык, на котором написана подпрограмма.
Сервер игнорирует эту характеристику, только подпрограммы SQL поддержаны.
Подпрограмму считают deterministic, если это
всегда приводит к тому же самому результату для тех же самых входных
параметров, и not deterministic иначе.
Если ни один из параметров DETERMINISTIC
или NOT
DETERMINISTIC
не задн в определении, значение по умолчанию
NOT DETERMINISTIC
. Чтобы объявить, что функция детерминирована,
Вы должны определить DETERMINISTIC
явно.
Оценка природы подпрограммы основана на
honesty создателя: MySQL не проверяет, что
подпрограмма, объявленная DETERMINISTIC
, свободна от запросов,
которые приводят к недетерминированным результатам. Однако,
DETERMINISTIC
подпрограмма могла бы затронуть результаты.
Объявление недетерминированной подпрограммы как NONDETERMINISTIC
может привести к неожиданным результатам, заставляя оптимизатор сделать
неправильный выбор плана выполнения. Объявление детерминированной
подпрограммы как NONDETERMINISTIC
могло бы уменьшить работу,
заставляя доступную оптимизацию не использоваться.
Если двоичное журналирование включено, DETERMINISTIC
влияет на обработку определений подпрограмм MySQL. См.
раздел 21.7.
Подпрограмма, которая содержит
NOW()
(возможно, синонимы) или
RAND()
недетерминирована, но это может быть безопасно для репликации. Для
NOW()
двоичной журнал включает timestamp и копирует правильно.
RAND()
также копирует правильно, пока вызывается только единственный раз
во время выполнения подпрограммы. Вы можете рассмотреть timestamp
и случайное число как неявные вводы, которые идентичны на
ведущем и ведомом устройствах.
Несколько характеристик предоставляют информацию о природе использования данных подпрограммой. В MySQL эти характеристики только консультация. Сервер не использует их, чтобы ограничить, какие виды запросов подпрограмме разрешат выполнить.
CONTAINS SQL
указывает, что подпрограмма не содержит
запросы, которые читают или пишут данные. Это значение по умолчанию, если ни
одна из этих характеристик не дана явно. Примеры таких запросов
SET @x = 1
или DO RELEASE_LOCK('abc')
,
которые выполняются, но данные не читают и не пишут.
NO SQL
указывает, что подпрограмма не содержит запросов SQL.
READS SQL DATA
указывает, что подпрограмма содержит запросы,
которые читают данные (например, SELECT
), но не запросы, которые пишут данные.MODIFIES SQL DATA
указывает, что подпрограмма содержит
запросы, которые могут писать данные (например,
INSERT
или
DELETE
).SQL SECURITY
может быть DEFINER
или
INVOKER
, чтобы определить контекст безопасности, то есть,
выполняет ли подпрограмма использование привилегий учетной записи, названной
в подпрограмме DEFINER
или пользователя, который вызывает.
У этой учетной записи должно быть разрешение получить доступ к базе данных, с
которой связана подпрограмма. Значение по умолчанию DEFINER
.
Пользователь, который вызывает подпрограмму, должен иметь привилегию
EXECUTE
для этого.
DEFINER
определяет учетную запись MySQL, которая будет
использоваться, проверяя привилегии доступа во время выполнения для
подпрограмм, которые имеют SQL SECURITY DEFINER
.
Если значение user
дано для DEFINER
,
это должна быть учетная запись MySQL, определенная как
'
, user_name
'@'host_name
'
CURRENT_USER
или CURRENT_USER()
. По умолчанию DEFINER
это пользователь, который
выполняет CREATE PROCEDURE
или CREATE FUNCTION
.
Это то же самое, как определение DEFINER = CURRENT_USER
явно.
Если Вы определяете DEFINER
, эти правила определяют
допустимые пользовательские значения DEFINER
:
Если Вы не имеете привилегии
SUPER
, единственное разрешенное значение
user
Ваша собственная учетная запись, определенная
буквально или при использовании
CURRENT_USER
. Вы не можете установить definer в некоторую
другую учетную запись.
SUPER
, Вы можете определить любое синтаксически допустимое имя учетной
записи. Если учетная запись не существует, предупреждение произведено.DEFINER
,
ошибка происходит во время выполнения, если SQL SECURITY
=
DEFINER
, но учетная запись не существует.См. раздел 21.6.
В пределах сохраненной подпрограммы, которая определена с SQL
SECURITY DEFINER
,
CURRENT_USER
возвращает значение DEFINER
.
Для информации об аудите пользователей в пределах сохраненных подпрограмм см.
раздел 7.3.12.
Рассмотрите следующую процедуру, которая выводит на экран количество
учетных записей MySQL, перечисленных в mysql.user
:
CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count() BEGIN SELECT 'Number of accounts:', COUNT(*) FROM mysql.user; END;Процедуре назначают
DEFINER
= 'admin'@'localhost'
,
независимо от того, какой пользователь определяет это. Это выполняется с
привилегиями той учетной записи, независимо от того, какой пользователь
вызывает это (потому что характеристика безопасности по умолчанию
DEFINER
). Процедура преуспевает или терпит неудачу в
зависимости от того, имеет ли вызывающий привилегию
EXECUTE
для нее,
и имеет ли 'admin'@'localhost'
привилегию
SELECT
на таблице
mysql.user
.
Теперь предположите, что процедура определена с
SQL SECURITY INVOKER
:
CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count() SQL SECURITY INVOKER BEGIN SELECT 'Number of accounts:', COUNT(*) FROM mysql.user; END;У процедуры все еще есть
DEFINER
=
'admin'@'localhost'
, но в этом случае, это выполняется с
привилегиями пользователя вызова. Таким образом, процедура преуспевает или
терпит неудачу в зависимости от того, имеет ли вызывающий привилегию
EXECUTE
для нее и
привилегию SELECT
для таблицы mysql.user
.
Сервер обрабатывает тип данных параметра, местной переменной,
создаваемой DECLARE
,
или функциональное возвращаемое значение следующим образом:
Назначения проверены на несоответствия типа данных и переполнение. Преобразование и проблемы переполнения приводят к предупреждениям или ошибкам в строгом режиме SQL.
SET x = (SELECT 1, 2)
не годится.CHARACTER SET
в декларации, указанный набор символов и его сопоставление по умолчанию
используются. Если указан COLLATE
, то используется указанное
сопоставление, а не сопоставление по умолчанию.
Если не указаны CHARACTER SET
и COLLATE
,
используются набор символов базы данных и сопоставление в действительности во
время создания подпрограммы. Чтобы избежать использования набор символов базы
данных и сопоставления сервера, обеспечивают явные параметры
CHARACTER SET
и COLLATE
для символьных параметров данных.
Если Вы изменяете набор символов по умолчанию базы данных или сопоставление, сохраненные подпрограммы, которые используют значения по умолчанию базы данных, должны быть удалены и обновлены так, чтобы они использовали новые значения по умолчанию.
Набор символов базы данных и сопоставление даны значениями
character_set_database
и
collation_database
. См. раздел 11.1.3.3.
CREATE SERVERЭто запрос создает определение сервера для использования с механизмом храненияserver_name
FOREIGN DATA WRAPPERwrapper_name
OPTIONS (option
[,option
] ...)option
: { HOSTcharacter-literal
| DATABASEcharacter-literal
| USERcharacter-literal
| PASSWORDcharacter-literal
| SOCKETcharacter-literal
| OWNERcharacter-literal
| PORTnumeric-literal
}
FEDERATED
. CREATE SERVER
создает новую строку в таблице servers
базы данных
mysql
. Этот запрос требует привилегии
SUPER
.
должен быть
уникальной ссылкой на сервер. Определения сервера глобальны в рамках сервера,
невозможно квалифицировать определение сервера для определенной базы данных.
server_name
имеет максимальную длину 64
символов (имена длиннее 64 символов являются тихо усеченными), и
нечувствительно к регистру. Вы можете определить имя как
заключенную в кавычки строку.server_name
должен быть
wrapper_name
mysql
, может быть заключен в кавычки с единственными кавычками.
Другие значения для
в настоящее время не поддерживаются.wrapper_name
Для каждой
Вы должны определить символьный или числовой литерал. Символьные литералы
UTF-8 поддерживают максимальную длину 64 символа и значение по умолчанию
пустая строка. Строковые литералы являются тихо усеченными к 64 символам.
Числовые должны быть числом между 0 и 9999, по умолчанию 0.option
OWNER
в настоящее время не применяется и не имеет никакого
эффекта на собственность или работу соединения сервера, которое создается.
CREATE SERVER
создает запись в таблице
mysql.servers
, которая может позже использоваться с
CREATE TABLE
, создавая
таблицу FEDERATED
. Опции, которые Вы определяете, будут
использоваться, чтобы заполнить столбцы в mysql.servers
.
Столбцы таблицы: Server_name
, Host
,
Db
, Username
,
Password
, Port
и Socket
.
Например:
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');Убедитесь, что определили все опции, необходимые, чтобы установить соединение с сервером. Имя пользователя, имя хоста и имя базы данных принудительны. Другие опции, такие как пароль, могли бы требоваться также.
Данные в таблице могут использоваться, создавая
соединение с таблицей FEDERATED
:
CREATE TABLE t (s1 INT) ENGINE=FEDERATED CONNECTION='s';См. раздел 17.8.
CREATE SERVER
автоматически закрывает транзакцию.
В MySQL 8.0 CREATE SERVER
не записан в двоичный журнал,
независимо от формата журналирования, который используется.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
(create_definition
,...) [table_options
] [partition_options
] CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
[(create_definition
,...)] [table_options
] [partition_options
] [IGNORE | REPLACE] [AS]query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
{ LIKEold_tbl_name
| (LIKEold_tbl_name
) }create_definition
:col_name
column_definition
| [CONSTRAINT [symbol
]] PRIMARY KEY [index_type
] (index_col_name
,...) [index_option
] ... | {INDEX|KEY} [index_name
] [index_type
] (index_col_name
,...) [index_option
] ... | [CONSTRAINT [symbol
]] UNIQUE [INDEX|KEY] [index_name
] [index_type
] (index_col_name
,...) [index_option
] ... | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name
] (index_col_name
,...) [index_option
] ... | [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
,...)reference_definition
| CHECK (expr
)column_definition
:data_type
[NOT NULL | NULL] [DEFAULTdefault_value
] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string
'] [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}] [reference_definition
] |data_type
[GENERATED ALWAYS] AS (expression
) [VIRTUAL | STORED] [UNIQUE [KEY]] [COMMENTcomment
] [NOT NULL | NULL] [[PRIMARY] KEY]data_type
: BIT[(length
)] | TINYINT[(length
)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length
)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length
)] [UNSIGNED] [ZEROFILL] | INT[(length
)] [UNSIGNED] [ZEROFILL] | INTEGER[(length
)] [UNSIGNED] [ZEROFILL] | BIGINT[(length
)] [UNSIGNED] [ZEROFILL] | REAL[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | FLOAT[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | DECIMAL[(length
[,decimals
])] [UNSIGNED] [ZEROFILL] | NUMERIC[(length
[,decimals
])] [UNSIGNED] [ZEROFILL] | DATE | TIME[(fsp
)] | TIMESTAMP[(fsp
)] | DATETIME[(fsp
)] | YEAR | CHAR[(length
)] [BINARY] [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | VARCHAR(length
) [BINARY] [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | BINARY[(length
)] | VARBINARY(length
) | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT [BINARY] [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | TEXT [BINARY] [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | MEDIUMTEXT [BINARY] [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | LONGTEXT [BINARY] [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | ENUM(value1
,value2
,value3
,...) [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | SET(value1
,value2
,value3
,...) [CHARACTER SETcharset_name
] [COLLATEcollation_name
] | JSON |spatial_type
index_col_name
:col_name
[(length
)] [ASC | DESC]index_type
: USING {BTREE | HASH}index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| WITH PARSERparser_name
| COMMENT 'string
' | {VISIBLE | INVISIBLE}reference_definition
: REFERENCEStbl_name
(index_col_name
,...) [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETEreference_option
] [ON UPDATEreference_option
]reference_option
: RESTRICT | CASCADE | SET NULL | NO ACTIONtable_options
:table_option
[[,]table_option
] ...table_option
: ENGINE [=]engine_name
| 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 DIRECTORY [=] 'absolute path to directory
' | DELAY_KEY_WRITE [=] {0 | 1} | ENCRYPTION [=] {'Y' | 'N'} | INDEX DIRECTORY [=] 'absolute path to directory
' | 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
| TABLESPACEtablespace_name
| UNION [=] (tbl_name
[,tbl_name
]...)partition_options
: PARTITION BY { [LINEAR] HASH(expr
) | [LINEAR] KEY [ALGORITHM={1|2}] (column_list
) | RANGE{(expr
) | COLUMNS(column_list
)} | LIST{(expr
) | COLUMNS(column_list
)} } [PARTITIONSnum
] [SUBPARTITION BY { [LINEAR] HASH(expr
) | [LINEAR] KEY [ALGORITHM={1|2}] (column_list
) } [SUBPARTITIONSnum
] ] [(partition_definition
[,partition_definition
] ...)]partition_definition
: PARTITIONpartition_name
[VALUES {LESS THAN {(expr
|value_list
) |MAXVALUE
} | IN (value_list
)}] [[STORAGE] ENGINE [=]engine_name
] [COMMENT [=]'comment_text'
] [DATA DIRECTORY [=] ''] [INDEX DIRECTORY [=] '
data_dir
'] [MAX_ROWS [=]
index_dir
max_number_of_rows
] [MIN_ROWS [=]min_number_of_rows
] [TABLESPACE [=] tablespace_name] [(subpartition_definition
[,subpartition_definition
] ...)]subpartition_definition
: SUBPARTITIONlogical_name
[[STORAGE] ENGINE [=]engine_name
] [COMMENT [=]'comment_text'
] [DATA DIRECTORY [=] ''] [INDEX DIRECTORY [=] '
data_dir
'] [MAX_ROWS [=]
index_dir
max_number_of_rows
] [MIN_ROWS [=]min_number_of_rows
] [TABLESPACE [=] tablespace_name]query_expression:
SELECT ... (Some valid select or union statement
)
CREATE TABLE
составляет таблицу с именем. Вы должны иметь привилегию
CREATE
для таблицы.
Правила для допустимых имен таблиц даны в
разделе 10.2.
По умолчанию таблица составлена в базе данных по умолчанию, используя
механизм хранения InnoDB
.
Ошибка происходит, если таблица существует, если нет никакой базы данных
по умолчанию, или если база данных не существует.
Имя таблицы может быть определено как
db_name.tbl_name
, чтобы составлять таблицу в
определенной базе данных. Это работает независимо от того, есть ли база
данных по умолчанию, предполагая, что база данных существует. Если Вы
используете заключенные в кавычки идентификаторы, то заключите в кавычки
имена базы данных и имена таблиц отдельно. Например,
`mydb`.`mytbl`
не `mydb.mytbl`
.
CREATE TABLE ... LIKE
составляет пустую таблицу, основанную
на определении другой таблицы, включая любые параметры столбца и индексы,
определенные в оригинальной таблице:
CREATE TABLEСм. раздел 14.1.15.1.new_tbl
LIKEorig_tbl
;
Чтобы составить одну таблицу от другой, добавьте
SELECT
в конце
CREATE TABLE
:
CREATE TABLEСм. раздел 14.1.15.2.new_tbl
SELECT * FROMorig_tbl
;
Вы можете использовать ключевое слово TEMPORARY
, составляя
таблицу. Таблица TEMPORARY
видима только текущему сеансу и
удалена автоматически, когда сеанс закрыт. Это означает, что два различных
сеанса могут использовать то же самое временное имя таблицы, не находясь в
противоречии друг с другом или с существующими не-TEMPORARY
таблицами. Существующая таблица скрыта, пока временная таблица не удалена.
Чтобы составить временные таблицы, Вы должны иметь привилегию
CREATE TEMPORARY TABLES
.
InnoDB
не поддерживает сжатые временные таблицы. Когда
innodb_strict_mode
включен (значение по умолчанию),
CREATE TEMPORARY TABLE
возвращает ошибку, если ROW_FORMAT=COMPRESSED
или
указан KEY_BLOCK_SIZE
. Если
innodb_strict_mode
отключен, предупреждения выпущены, и временная таблица
составлена, используя несжатый формат строки. Временные таблицы
InnoDB
составлены в совместно используемом временном табличном
пространстве ibtmp1
.
innodb_file_per-table
не затрагивает создание временных таблиц InnoDB
.
CREATE TABLE
автоматически не закрывает текущую активную транзакцию, если Вы используете
ключевое слово TEMPORARY
.
Таблицы TEMPORARY
имеют очень свободные отношения с базами
данных (схемами). Удаление базы данных автоматически не удаляет таблицы
TEMPORARY
в пределах той базы данных. Кроме того, Вы можете
создать таблицу TEMPORARY
в несуществующей базе данных, если Вы
квалифицируете имя таблицы с именем базы данных в
CREATE TABLE
. В этом случае все последующие ссылки на таблицу
должны быть квалифицированы с именем базы данных.
Ключевые слова IF NOT EXISTS
не дают ошибке произойти, если
таблица существует. Однако, нет никакой проверки, что у существующей таблицы
есть структура, идентичная обозначенной в
CREATE TABLE
.
Для таблицы InnoDB
в табличном пространстве file-per-table
или общем табличном пространстве табличных данные и связанные индексы
сохранены в файле ibd
в каталоге базы данных. Когда таблица InnoDB
составлена в системном табличном пространстве, табличные данные и индексы
сохранены в файлах ibdata*,
которые представляют системное табличное пространство.
innodb_file_per_table
управляет, составлены ли таблицы в табличных
пространствах file-per-table или системном табличном пространстве по
умолчанию. Опция TABLESPACE
может использоваться, чтобы поместить таблицу в табличное пространство
file-per-table, общее табличное пространство или системное табличное
пространство, независимо от
innodb_file_per_table
.
Для MyISAM
механизм хранения создает файлы с данными и
индексные файлы. Таким образом, для каждой таблицы MyISAM
tbl_name
есть два дисковых файла.
Файл | Назначение |
---|---|
| Данные |
|
Индексы |
Глава 17 описывает то, что регистрирует каждый механизм хранения, чтобы представить таблицы. Если имя таблицы содержит специальные символы, названия табличных файлов содержат закодированные версии тех символов как описано в разделе 10.2.3.
data_type
представляет тип данных в определении
столбца. spatial_type
представляет пространственный тип
данных. Показанный синтаксис типа данных является только образцом.
Для полного описания синтаксиса, доступного для определения типов данных
столбца, так же как и для информации о свойствах каждого типа см.
главу 12 и
раздел 12.5. Тип данных JSON
также поддержан для столбцов таблицы, см.
раздел 12.6.
Некоторые признаки не относятся ко всем типам данных.
AUTO_INCREMENT
применяется только к целому числу и типам
с плавающей запятой. DEFAULT
не относится к типам
BLOB
,
TEXT
, GEOMETRY
и
JSON
.
Если NULL
или NOT NULL
не определен,
столбец обработан как если бы был определен NULL
.
AUTO_INCREMENT
. Когда Вы вставляете значение
NULL
(рекомендуемый) или 0
в индексированный
столбец AUTO_INCREMENT
, столбец установлен в следующее значение
последовательности. Как правило, это value
+1
, где value
самое большое значение для столбца в
настоящее время в таблице. Последовательности AUTO_INCREMENT
начинаются с 1
.
Чтобы получить значение AUTO_INCREMENT
после вставки строки,
используйте
LAST_INSERT_ID()
или
mysql_insert_id()
C
API. См. разделы 13.14 и
25.8.7.38.
Если включен режим SQL
NO_AUTO_VALUE_ON_ZERO
, Вы можете сохранить 0
в
столбец AUTO_INCREMENT
именно как 0
,
не производя новое значение последовательности. См.
раздел 6.1.8.
Может быть только один столбец AUTO_INCREMENT
на таблицу, это должно быть индексировано, и у этого не может быть значения
DEFAULT
. AUTO_INCREMENT
работает должным образом,
только если он содержит только положительные значения. Вставка отрицательного
числа расценена как вставка очень большого положительного числа. Это сделано,
чтобы избежать проблем точности, когда числа
переходят с положительных на отрицательне и также
гарантировать, что Вы случайно не дойдете до 0
в
AUTO_INCREMENT
.
Для MyISAM
Вы можете определить вторичный столбец
AUTO_INCREMENT
в ключе из нескольких столбцов. См.
раздел 4.6.9.
Чтобы сделать MySQL совместимым с некоторыми приложениями ODBC, Вы можете
найти AUTO_INCREMENT
для последней вставленной
строки следующим запросом:
SELECT * FROMЭтот метод требует, чтобыtbl_name
WHEREauto_col
IS NULL
sql_auto_is_null
не был 0. См.
раздел 6.1.5.
Для информации о InnoDB
и AUTO_INCREMENT
см.
раздел 16.8.5.
Для информации о AUTO_INCREMENT
и репликации MySQL см.
раздел 19.4.1.1
.
CHAR
,
VARCHAR
,
TEXT
) могут включать атрибуты
CHARACTER SET
и COLLATE
, чтобы определить набор
символов и сопоставление для столбца. Для деталей см.
раздел 11.1. CHARSET
синоним
для CHARACTER SET
:
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);MySQL 8.0 интерпретирует технические требования длины в символьных определениях столбца в символах. Длины для
BINARY
и
VARBINARY
в байтах.
DEFAULT
определяет значение по умолчанию для столбца. С
одним исключением значение по умолчанию должно быть константой, это не может
быть функция или выражение. Это означает, например, что Вы не можете
установить значение по умолчанию для столбца даты, чтобы быть значением
функции, такой как NOW()
или CURRENT_DATE
.
Исключение: Вы можете определить
CURRENT_TIMESTAMP
как значение по умолчанию для
TIMESTAMP
или DATETIME
. См. раздел 12.3.5.
Если определение столбца включает неявное значение
DEFAULT
, MySQL определяет значение по умолчанию как описано в
раздел 12.7.
BLOB
,
TEXT
и
JSON
нельзя назначить значение по умолчанию.
Если режим SQL
NO_ZERO_DATE
или
NO_ZERO_IN_DATE
включен, и значение даты по умолчанию не
правильно, согласно тому режиму, CREATE
TABLE
производит предупреждение, если строгий режим SQL не
включен, и ошибку, если строгий режим включен. Например, с включенным
NO_ZERO_IN_DATE
c1 DATE DEFAULT '2010-00-00'
производит предупреждение.
COMMENT
до 1024 символов в длину. Комментарий выведен на экран
SHOW CREATE TABLE
и
SHOW FULL COLUMNS
.COLUMN_FORMAT
используется MySQL Cluster, чтобы определить
формат хранения столбца. Эта опция в настоящее время не имеет никакого
эффекта на столбцы таблиц, используя механизмы хранения, кроме
NDB
. В MySQL 8.0 и выше
COLUMN_FORMAT
тихо проигнорирован.KEY
синоним для INDEX
. Ключевой признак
PRIMARY KEY
может также быть определен как только
KEY
дано в определении столбца. Это было осуществлено для
совместимости с другими системами базы данных.UNIQUE
создает ограничение, таким образом, что все
значения в индексировании должны быть отличными. Ошибка происходит, если Вы
пытаетесь добавить новую строку со значением ключа, которое соответствует
существующей строке. Для всех механизмов UNIQUE
разрешает многократные значения NULL
для столбцов, которые могут содержать NULL
.PRIMARY KEY
уникальный индекс, где все ключевые столбцы
должны быть определены как NOT NULL
. Если они явно не объявлены
как NOT NULL
, MySQL объявляет их так неявно (и тихо). У таблицы
может быть только один PRIMARY KEY
. Имя PRIMARY KEY
всегда PRIMARY
, который таким образом не может использоваться
как имя любого другого индекса.
Если у Вас нет PRIMARY KEY
и приложение просит
PRIMARY KEY
в Ваших таблицах, MySQL возвращает первый индекс
UNIQUE
, который не имеет столбцов NULL
,
как PRIMARY KEY
.
В InnoDB
сохраните PRIMARY KEY
коротким, чтобы
минимизировать хранение для вторичного индекса. Каждая запись вторичного
индекса содержит копию столбцов первичного ключа для соответствующей строки.
См. раздел 16.8.8.
PRIMARY KEY
помещен сначала, сопровождается всеми UNIQUE
и затем
групповые индексы. Это помогает оптимизатору MySQL расположить по
приоритетам, которые индексы использовать, а также более быстро обнаружить
дублированный ключ UNIQUE
.PRIMARY KEY
может быть многостолбцовым.
Однако, Вы не можете создать многостолбцовый индекс с использованием
PRIMARY KEY
в спецификации столбца. Выполнение этого только
помечает единственный столбец как основной. Вы должны использовать отдельный
параметр PRIMARY KEY(index_col_name
, ...)
.
PRIMARY KEY
или UNIQUE
состоит только из одного столбца, у которого есть тип целого числа, Вы можете
также обратиться к столбцу как к _rowid
в
SELECT
.PRIMARY KEY
PRIMARY
.
Для других индексов, если Вы не назначаете имя, индексу назначают имя первого
индексированного столбца с дополнительным суффиксом (_2
,
_3
, ...
), чтобы сделать это уникальным. Вы можете
видеть названия для таблицы, используя SHOW INDEX FROM
tbl_name
. См.
раздел 14.7.5.22.index_type
:
USING type_name
.
Например:
CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;Привилегированная позиция для
USING
после списка столбцов
индекса. Это может быть дано перед списком столбца, но поддержка
использования опции в той позиции устарела
и будет удалена в будущем выпуске MySQL.
index_option
определяют дополнительные опции для
индекса. USING
одна такая опция. WITH PARSER
может использоваться только с FULLTEXT
. Это связывает плагин
анализатора с индексированием, если полнотекстовая индексация и поиск
операций нуждаются в специальной обработке.
InnoDB
и
MyISAM
поддерживают полнотекстовые плагины анализатора. Если у Вас есть таблица
MyISAM
со связанным полнотекстовым плагином анализатора, Вы можете преобразовать
таблицу в InnoDB
через ALTER TABLE
.
InnoDB
, MyISAM
и
MEMORY
поддерживают индекс на столбцах, которые могут иметь
значения NULL
. В других случаях Вы должны объявить
индексированные столбцы как NOT NULL
или будет ошибка.CHAR
,
VARCHAR
,
BINARY
и
VARBINARY
может быть создан индекс, который использует только начальную часть
значений столбцов, используя col_name
(
length
)
, чтобы определить длину префикса.
BLOB
и
TEXT
также могут быть индексированы, но длина префикса
должна быть задана явно. Длины префикса даны в символах
для недвоичных строковых типов и в байтах для двоичных строковых типов. Таким
образом, индексная запись состоит из первых length
символов каждого значения столбца для
CHAR
,
VARCHAR
и
TEXT
или первых
length
байт каждого значения столбца для
BINARY
,
VARBINARY
и
BLOB
.
Индексация только префиксов значений столбцов может сделать индексный файл
намного меньшим. Для дополнительной информации о префиксах см.
раздел 14.1.12.
Только InnoDB
и MyISAM
имеют поддержку индексов BLOB
и
TEXT
:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));Префиксы могут составить до 767 байтов для таблиц
InnoDB
,
которые используют формат строки
REDUNDANT
или COMPACT
.
Предел длины поднят до 3072 байтов для таблиц InnoDB
,
которые используют формат строки
DYNAMIC
или
COMPRESSED
. Для MyISAM предел префикса составляет 1000 байт.
Пределы префиксов измерены в байтах, тогда как длина префикса в
CREATE TABLE
,
ALTER TABLE
и
CREATE INDEX
интерпретируется как число символов для недвоичных строковых типов
(CHAR
,
VARCHAR
,
TEXT
)
и число байтов для двоичных строковых типов
(BINARY
,
VARBINARY
,
BLOB
).
Примите это во внимание, определяя длину префикса для недвоичного строкового
столбца, который использует многобайтовый набор символов.
index_col_name
может закончиться
ASC
или DESC
.
Эти ключевые слова разрешены для будущих расширений для того, чтобы
определить хранение значения по возрастанию или убыванию. В настоящее время
они разобраны, но проигнорированы, индексные значения всегда
сохранены в порядке возрастания.ORDER BY
или GROUP BY
на столбце в SELECT
,
сервер сортирует значения, используя только начальное число байтов,
обозначенное
max_sort_length
.FULLTEXT
,
который используется для полнотекстовых поисков. Только
InnoDB
и
MyISAM
имеют поддержку FULLTEXT
. Они могут быть созданы только из
столбцов CHAR
,
VARCHAR
и
TEXT
.
Индексация всегда происходит по всему столбцу, префиксы столбца не
поддержаны, любая длина префикса проигнорирована, если определена. См.
раздел 13.9.
WITH PARSER
может быть определен как
index_option
, чтобы связать плагин анализатора с
индексированием, если полнотекстовая индексация и поиск операций нуждаются в
специальной обработке. Этот пункт допустим только для FULLTEXT
.
InnoDB
и
MyISAM
поддерживают полнотекстовые плагины анализатора. См.
раздел 26.2.4.4.SPATIAL
на пространственных типах
данных. Пространственные типы поддержаны только для
InnoDB
и MyISAM
, и индексированные столбцы должны
быть объявлены как NOT NULL
. См.
раздел 12.5.InnoDB
поддерживает вторичные индексы на
произведенных
виртуальных столбцах. См.
раздел
14.1.15.6.JSON
не могут быть индексированы. Вы можете создать индекс на произведенном
столбце, который извлекает скалярное значение из JSON
. См.
раздел
14.1.15.6.InnoDB
поддерживают
проверку ограничений внешнего ключа. Столбцы таблицы, на которую ссылаются,
нужно всегда явно называть. ON DELETE
и ON UPDATE
действуют на внешних ключах. Для более подробной информации и примеров см.
раздел 14.1.15.3.
Для других механизмов хранения MySQL Server разбирает и игнорирует
FOREIGN KEY
и REFERENCES
в
CREATE TABLE
. Параметр
CHECK
разобран, но проигнорирован всеми механизмами хранения.
См. раздел 1.8.2.3.
Для пользователей, знакомых с ANSI/ISO SQL Standard,
отметьте, что никакой механизм хранения, включая InnoDB
,
не признает или проводит в жизнь MATCH
,
используемый в определениях ограничения целостности. Использование явного
MATCH
не будет иметь указанного эффекта, и также вызывает
ON DELETE
и ON UPDATE
, которые будут
проигнорированы. По этим причинам, определять MATCH
не надо.
MATCH
в SQL управляет тем, как значения NULL
в соединенном (многократные столбцы) внешнем ключе обработаны, сравниваясь с
первичным ключом. InnoDB
по существу осуществляет семантику,
определенную MATCH SIMPLE
, которая разрешают внешнему ключу быть
всему или частично NULL
. В этом случае строке дочерней таблицы,
содержащей такой внешний ключ, разрешают быть вставленной и не
соответствовать строке в родительской таблице, на которую ссылаются.
Возможно осуществить другую семантику, используя триггеры.
Дополнительно, MySQL требует, чтобы столбцы, на которые ссылаются, были
индексированы для работы. Однако, InnoDB
не проводит в жизнь требования что столбцы, на которые ссылаются, должны
быть объявлены UNIQUE
или NOT NULL
.
Обработка ссылок внешнего ключа на групповые ключи или ключи, которые
содержат NULL
, не четко определены для таких операций, как
UPDATE
или DELETE CASCADE
. Вам советуют
использовать внешние ключи, которые ссылаются только на ключи, которые
являются UNIQUE
(или PRIMARY
) и
NOT NULL
сразу.
MySQL разбирает, но игнорирует inline
REFERENCES
specifications (как
определено в стандарте SQL), где ссылки определены как часть спецификации
столбца. MySQL принимает REFERENCES
только когда определено, как
часть отдельной специфиувции FOREIGN KEY
.
Разделенные таблицы, использующие
InnoDB
,
не поддерживают внешние ключи. См.
раздел 20.6.
Опция ENGINE
определяет механизм хранения для таблицы,
используя одно из имен, показанных в следующей таблице. Имя механизма может
быть взято в кавычки. Заключенное в кавычки имя 'DEFAULT'
признано, но проигнорировано.
Механизм хранения | Описание |
---|---|
InnoDB |
Транзакционно-безопасные таблицы с блокировкой строки и внешними ключами. Механизм хранения значения по умолчанию для новых таблиц. См. главу 16. |
MyISAM | Двоичной механизм хранения, который прежде всего используется для рабочих нагрузок, главным образом, чтения или только для чтения. См. раздел 17.2. |
MEMORY | Данные для этого механизма хранятся только в памяти. См. раздел 17.3. |
CSV | Таблицы, которые хранят строки в отделенном запятыми формате значений. См. раздел 17.4. |
ARCHIVE |
Механизм хранения архивирования. См. раздел 17.5. |
EXAMPLE |
Механизм в качестве примера. См. раздел 17.9. |
FEDERATED |
Механизм хранения, который получает доступ к удаленным таблицам. См. раздел 17.8. |
HEAP | Синоним для
MEMORY . |
MERGE | Набор таблиц
MyISAM , используемых в качестве одной таблицы. Также известен
как MRG_MyISAM . См.
раздел 17.7. |
По умолчанию, если определен механизм хранения, который не доступен,
запрос терпит неудачу с ошибкой. Вы можете переопределить это поведение,
удаляя режим SQL
NO_ENGINE_SUBSTITUTION
(см.
раздел 6.1.8), чтобы MySQL позволил замену
указанного механизма механизмом хранения по умолчанию вместо этого. Обычно в
таких случаях это InnoDB
, который является значением по
умолчанию для
default_storage_engine
. Когда NO_ENGINE_SUBSTITUTION
выключен, предупреждение происходит, если спецификация механизма
хранения не соблюдается.
Другие табличные опции используются, чтобы оптимизировать поведение
таблицы. В большинстве случаев Вы не должны определить ни одну из них. Эти
опции относятся ко всем механизмам хранения, если иное не обозначено. Опции,
которые не относятся к данному механизму хранения, могут быть приняты как
часть табличного определения. Такие опции тогда применяются, если Вы позже
используете ALTER TABLE
, чтобы
преобразовать таблицу, чтобы использовать различный механизм хранения.
AUTO_INCREMENT
Начальное AUTO_INCREMENT
значение для таблицы. В MySQL 8.0 это работает на таблицах
MyISAM
, MEMORY
, InnoDB
и
ARCHIVE
. Установить первое значение
для механизмов, которые не поддерживают AUTO_INCREMENT
,
вставьте строку со значением меньше, чем требуемое значение после составления
таблицы, и затем удалите фиктивную строку.
Для механизмов, которые поддерживают AUTO_INCREMENT
в CREATE TABLE
,
Вы можете также использовать ALTER TABLE
, чтобы сбрасывать tbl_name
AUTO_INCREMENT =
N
AUTO_INCREMENT
.
Значение не может в настоящее время устанавливаться ниже, чем
максимальное значение в столбце.
AVG_ROW_LENGTH
Приближение средней длины строки для Вашей таблицы. Вы должны установить это только для больших таблиц со строками переменного размера.
Когда Вы создаете MyISAM
, MySQL использует
MAX_ROWS
и AVG_ROW_LENGTH
, чтобы решить, насколько
большая будет таблица. Если Вы не определяете ни одну опцию, максимальный
размер для MyISAM
по умолчанию 256 TB.
Если Ваша операционная система не поддерживает большие файлы, табличные
размеры ограничены пределом размера файла. Если Вы хотите подавить размеры
указателя, чтобы сделать индексирование меньше и быстрее и Вы действительно
не нуждаетесь в больших файлах, Вы можете уменьшить размер указателя по
умолчанию, устанавливая
myisam_data_pointer_size
. См.
раздел 6.1.5.
Если Вы хотите, чтобы все Ваши таблицы были в состоянии вырасти выше значения
по умолчанию и готовы, что Ваши таблицы немного медленнее и больше, чем
необходимо, Вы можете увеличить размер указателя по умолчанию, устанавливая
эту переменную. Установка значения 7 увеличит размер таблицы до 65536 TB.
[DEFAULT] CHARACTER SET
Определите набор символов значения по умолчанию для таблицы.
CHARSET
синоним CHARACTER SET
.
Если имя набора символов DEFAULT
, набор символов
базы данных используется.
CHECKSUM
Установите это в 1, если Вы хотите, чтобы MySQL поддержал живую
контрольную сумму для всех строк (то есть, контрольная сумма, которую MySQL
обновляет автоматически, поскольку таблица изменяется).
Это делает таблицу немного медленнее, чтобы обновить, но также и облегчает
поиск поврежденных таблиц. Запрос
CHECKSUM TABLE
сообщает о контрольной сумме (только
MyISAM
).
[DEFAULT] COLLATE
Определите сопоставление по умолчанию для таблицы.
COMMENT
Комментарий для таблицы до 2048 символов.
Установка InnoDB MERGE_THRESHOLD с табличными комментариями.
MERGE_THRESHOLD
для индексных страниц может быть сконфигурирован для индексов таблицы
InnoDB
через параметр COMMENT
в
CREATE TABLE
:
CREATE TABLE t1 (id INT, KEY id_index (id)) COMMENT='MERGE_THRESHOLD=45';Если процент заполнения страницы для индексной страницы падает ниже
MERGE_THRESHOLD
, когда строка удалена или сокращена работой
обновления, InnoDB
пытается слить индексную страницу с соседней
индексной страницей. Значение по умолчанию 50.
MERGE_THRESHOLD
может также быть определен для индексов
таблиц InnoDB
через
ALTER TABLE
(опция
COMMENT
). MERGE_THRESHOLD
может быть определен для индивидуального индекса через использование
CREATE INDEX
или опции
COMMENT
в CREATE TABLE
или ALTER TABLE
.
См. раздел 16.6.11.
COMPRESSION
Алгоритм сжатия, используемый для сжатия уровня страницы таблиц
InnoDB
. Поддержанные значения включают
Zlib
, LZ4
и None
. Атрибут
COMPRESSION
был начат с прозрачной особенности сжатия страницы.
Сжатие страницы поддержано только с InnoDB
, которые находятся в
табличных пространствах
file-per-table и доступны только на Linux и Windows, которые поддерживают
редкие файлы и hole punching. См.
раздел 16.9.2.
CONNECTION
Строка подключения для таблицы FEDERATED
.
Более старые версии MySQL использовали опцию COMMENT
для строки подключения.
DATA DIRECTORY
, INDEX DIRECTORY
Для InnoDB
DATA DIRECTORY='
позволяет Вам создавать табличные пространства file-per-table
вне каталога данных MySQL. В пределах каталога, который Вы определяете, MySQL
создает подкаталог, соответствующий имени базы данных, а в его этого файл
directory
'.ibd
для таблицы. Опция
innodb_file_per_table
должна быть включена для работы DATA
DIRECTORY
с InnoDB
. Полный путь к каталогу должен быть
определен. См. раздел 16.7.5.
Создавая таблицы MyISAM
, Вы можете использовать
DATA DIRECTORY='
,
directory
'INDEX DIRECTORY='
или обе.
Они определяют, куда поместить файлы directory
'MyISAM
.
В отличие от таблицы InnoDB
, MySQL не создает
подкаталоги, которые соответствуют имени базы данных, создавая таблицу
MyISAM
с DATA DIRECTORY
или INDEX
DIRECTORY
. Файлы создаются в каталоге, который определен.
Опции табличного уровня DATA DIRECTORY
и
INDEX DIRECTORY
проигнорированы для разделенных таблиц (Bug
#32091).
Эти опции работают только, когда Вы не используете
--skip-symbolic-links
.
У Вашей операционной системы должен также быть безопасный для потоков
вызов realpath()
. См.
раздел 9.12.2.2.
Если MyISAM
составлена без DATA DIRECTORY
,
фпйл .MYD
создается в каталоге базы данных. По умолчанию, если
MyISAM
находит существующий файл .MYD
в этом случае, он перезаписывает его. То же самое относится к файлам
.MYI
для таблиц, составленных без INDEX DIRECTORY
.
Чтобы подавить это поведение, запустите сервер с
--keep_files_on_create
, тогда MyISAM
не будет
перезаписывать существующие файлы и возвращает ошибку вместо этого.
Если MyISAM
составлена с опцией
DATA DIRECTORY
или INDEX DIRECTORY
и существующий файл .MYD
или .MYI
найден, MyISAM
всегда возвращает ошибку. Это не будет перезаписывать
файл в указанном каталоге.
Вы не можете использовать пути, которые содержат каталог данных MySQL с
DATA DIRECTORY
или INDEX DIRECTORY
.
Это включает разделенные таблицы и отдельное табличное разделение (см. Bug
#32167).
DELAY_KEY_WRITE
Установите это в 1, если Вы хотите задержать ключевые обновления для
таблицы, пока таблица не закрыта. См. описание
delay_key_write
в разделе 6.1.5
(только MyISAM
).
ENCRYPTION
Установите опцию ENCRYPTION
в 'Y'
, чтобы
включить шифрованию данных на уровне страницы для таблиц InnoDB
в табличном пространстве
file-per-table. Значения опции не являются чувствительными к регистру.
ENCRYPTION
была введена с особенностью шифрования табличного
пространства InnoDB
, см.
раздел 16.7.10. Плагин
keyring_file
должен быть загружен для
использования опции ENCRYPTION
.
INSERT_METHOD
Если Вы хотите вставить данные в таблицу MERGE
,
Вы должны определить с INSERT_METHOD
таблицу, в которую должна быть вставлена строка. INSERT_METHOD
опция, полезная для таблиц MERGE
.
Используйте значение FIRST
или LAST
, чтобы
вставить в первую или последнюю таблицу, или значение NO
, чтобы
не вставлять вообще. См. раздел
17.7.
KEY_BLOCK_SIZE
Для MyISAM
KEY_BLOCK_SIZE
произвольно определяет размер в байтах, чтобы
использовать для индексных ключевых блоков. Значение обработано как
подсказка, иной размер может использоваться в случае необходимости.
KEY_BLOCK_SIZE
определенное для индивидуального индекса,
переопределяет значение на уровне таблицы.
Для InnoDB
KEY_BLOCK_SIZE
произвольно определяет размер
страницы
(в килобайтах), чтобы использовать для
сжатых таблиц. Значение
обработано как подсказка, иной размер может использоваться в случае
необходимости. KEY_BLOCK_SIZE
может быть только меньше или равно
innodb_page_size
. Значение 0 представляет сжатый размер страницы по умолчанию, который
является половиной
innodb_page_size
. В зависимости от
innodb_page_size
, возможные значения KEY_BLOCK_SIZE
включают 0, 1, 2, 4, 8 и
16. См. раздел 16.9.1.
Oracle рекомендует включить
innodb_strict_mode
, определяя KEY_BLOCK_SIZE
для InnoDB
. Когжда
innodb_strict_mode
включен, определение недопустимого KEY_BLOCK_SIZE
возвращает ошибку. Если
innodb_strict_mode
выключен, недопустимое значение
KEY_BLOCK_SIZE
вернет предупреждение, а опция
KEY_BLOCK_SIZE
проигнорирована.
InnoDB
поддерживает KEY_BLOCK_SIZE
только
на табличном уровне.
KEY_BLOCK_SIZE
не поддержан с 32k и 64k
innodb_page_size
. Табличное сжатие не поддерживает эти размеры страниц.
С MySQL 8.0.0 InnoDB
не поддерживает
KEY_BLOCK_SIZE
, составляя временные таблицы.
MAX_ROWS
Максимальное количество строк, которое Вы планируете сохранить в таблице. Это не жесткий предел, а скорее подсказка механизму хранения, что таблица должна быть в состоянии сохранить, по крайней мере, так много строк.
Максимум MAX_ROWS
4294967295,
большие значения являются усеченными к этому пределу.
MIN_ROWS
Минимальное число строк, которое Вы планируете сохранить в таблице.
Механизм хранения MEMORY
использует эту опцию в качестве подсказки
об использовании памяти.
PACK_KEYS
PACK_KEYS
вступает в силу только с MyISAM
.
Установите эту опцию в 1, если Вы хотите иметь меньший индекс.
Это обычно делает обновления медленнее и читает быстрее. Установка опции к 0
отключает всю упаковку ключей. Установка этого к DEFAULT
говорит механизму хранения упаковывать только большие столбцы
CHAR
,
VARCHAR
,
BINARY
или
VARBINARY
.
Если Вы не используете PACK_KEYS
, значение по умолчанию
должно упаковать строки, но не числа. Если Вы используете
PACK_KEYS=1
, числа упакованы также.
При упаковке двоичных числовых ключей MySQL использует сжатие префиксов:
Каждый ключ нуждается в одном дополнительном байте, чтобы указать, сколько байтов предыдущего ключа те же самые для следующего ключа.
Это означает, что, если у Вас есть много равных ключей на двух
последовательных строках, все последующие ключи обычно берут только два байта
(включая указатель на строку). Сравните это с обычным случаем, где следующие
ключи берут по storage_size_for_key + pointer_size
(где
размер указателя обычно 4). Наоборот, Вы извлекаете существенную пользу из
сжатия, только если у Вас есть много чисел, которые являются теми же самыми.
Если все ключи полностью отличаются, Вы используете один байт на ключ больше,
если ключ не может иметь NULL
. В этом случае упакованная длина
ключа сохранена в том же самом байте, который используется, чтобы отметить,
что ключ NULL
.
PASSWORD
Не используется.
ROW_FORMAT
Определяет физический формат, в котором сохранены строки. Выбор отличается в зависимости от механизма хранения, используемого для таблицы.
Для InnoDB
:
Формат строки по умолчанию определен
innodb_default_row_format
,
у которого есть настройка по умолчанию DYNAMIC
.
Формат строки по умолчанию используется, когда опция
ROW_FORMAT
не определена или когда используется
ROW_FORMAT=DEFAULT
.
Если ROW_FORMAT
не определена или
ROW_FORMAT=DEFAULT
, операции, которые пересоздают таблицу, также
тихо изменяют формат строки таблицы к значению по умолчанию, определенному
innodb_default_row_format
. См.
раздел 16.10.2.
BLOB
, лучше
DYNAMIC
. См.
раздел 16.10.3.InnoDB
, определите
ROW_FORMAT=COMPRESSED
. Опция ROW_FORMAT=COMPRESSED
не поддержана, составляя временные таблицы. См.
раздел 16.9.REDUNDANT
.ROW_FORMAT
не по умолчанию,
рассмотрите также включение
innodb_strict_mode
.ROW_FORMAT=FIXED
не поддержан. Если
ROW_FORMAT=FIXED
определен в то время, как
innodb_strict_mode
выключен, InnoDB
выпускает предупреждение и
предполагает ROW_FORMAT=COMPACT
. Если
ROW_FORMAT=FIXED
определен в то время, как
innodb_strict_mode
включен, InnoDB
возвращает ошибку.Для MyISAM
значение опции может быть
FIXED
или DYNAMIC
для формата строки статической или переменной длины.
myisampack
устанавливает тип в COMPRESSED
. См.
раздел 17.2.3.
Выполняя CREATE TABLE
,
если Вы определяете формат строки, который не поддержан механизмом хранения,
который используется для таблицы, таблица создается, используя формат строки
по умолчанию для механизма хранения. Информация в этом столбце ответа
SHOW TABLE STATUS
показывает фактический используемый формат строки. Это может отличаться от
значения в столбце Create_options
, поскольку оригинал
CREATE TABLE
определения сохранен во время создания.
STATS_AUTO_RECALC
Определяет, вычислить ли повторно автоматически
постоянную статистику
для InnoDB
. DEFAULT
заставляет постоянную установку статистики для таблицы быть определенной
опцией
innodb_stats_auto_recalc
. Значение 1
указывает, что
статистика повторно вычислена, когда 10% данных в таблице изменились.
Значение 0
предотвращает автоматический пересчет для этой
таблицы, с этой установкой используйте
ANALYZE TABLE
, чтобы повторно вычислить статистику после создания
существенных изменений таблицы. Для получения дополнительной информации о
постоянной статистике см. раздел
16.6.10.1.
STATS_PERSISTENT
Определяет, включить ли
постоянную статистику
для InnoDB
. DEFAULT
заставляет постоянную
статистику для таблицы быть определенной опцией
innodb_stats_persistent
. Значение 1
включает постоянную статистику для таблицы, в то время как значение
0
выключает. После включения постоянной статистике через
CREATE TABLE
или ALTER TABLE
скомандуйте
ANALYZE TABLE
, чтобы
вычислить статистику после загрузки представительных данных в таблицу. Для
получения дополнительной информации о постоянной статистике см.
раздел 16.6.10.1.
STATS_SAMPLE_PAGES
Число индексных страниц, оценивая количество элементов и другую статистику
для индексированного столбца, такую как вычисленная
ANALYZE TABLE
. См.
раздел 16.6.10.1.
TABLESPACE
TABLESPACE
может использоваться, чтобы составить таблицу в
существующем общем табличном пространстве, табличном пространстве
file-per-table или системном табличном пространстве.
CREATE TABLEСм. раздел 16.7.9.tbl_name
... TABLESPACE [=]tablespace_name
чувствительный к регистру идентификатор. Это может быть заключено в кавычки.
Символ наклонной черты вправо (/)
не разрешен. Имена, начинающиеся с innodb_
зарезервированы для специального использования.tablespace_name
TABLESPACE
может использоваться, чтобы назначить
табличное разделение или подразделение к
общему табличному
пространству, отдельному табличному пространству file-per-table
или системному табличному пространству. Все разделение должно принадлежать
тому же самому механизму хранения.
Табличное пространство, определенное на табличном уровне, становится
табличным пространством по умолчанию для нового разделения и подразделения.
Табличное пространство по умолчанию может быть переопределено, определяя
табличное пространство на уровне разделения или подразделения в
CREATE TABLE
или
ALTER TABLE
. Следующий пример
показывает табличные пространства, определенные на табличном
уровне и уровне разделения.
mysql> CREATE TABLE t1 (a INT NOT NULL, PRIMARY KEY (a)) -> ENGINE=InnoDB TABLESPACE ts1 -> PARTITION BY RANGE (a) PARTITIONS 3 ( -> PARTITION P1 VALUES LESS THAN (2), -> PARTITION P2 VALUES LESS THAN (4) TABLESPACE ts2, -> PARTITION P3 VALUES LESS THAN (6) TABLESPACE ts3);См. раздел 16.7.9.
Чтобы составить таблицу в системном табличном пространстве, определите
innodb_system
как имя табличного пространства.
CREATE TABLE tbl_name
... TABLESPACE [=] innodb_system
Используя TABLESPACE [=] innodb_system
,
Вы можете поместить таблицу любого несжатого формата строки в системном
табличном пространстве, независимо от
innodb_file_per_table
.
Например, Вы можете добавить таблицу с ROW_FORMAT=DYNAMIC
к системному табличному пространству, используя
TABLESPACE [=] innodb_system
.
Чтобы составить таблицу в табличном пространстве file-per-table,
определите innodb_file_per_table
как имя табличного пространства.
CREATE TABLE tbl_name
... TABLESPACE [=] innodb_file_per_table
Если включена
innodb_file_per_table
, Вы не должны определять
TABLESPACE=innodb_file_per_table
при создании
табличного пространства file-per-table. Таблицы InnoDB
составлены в табличных пространствах file-per-table по умолчанию, когда
включена опция
innodb_file_per_table
.
DATA DIRECTORY
допустим с CREATE TABLE ...
TABLESPACE=innodb_file_per_table
, но иное не поддержано для
использования в комбинации с опцией TABLESPACE
.
TABLESPACE
поддержана с
ALTER TABLE
и
ALTER TABLE ... REORGANIZE PARTITION
, которые могут использоваться, чтобы переместить таблицы и
разделение от одного табличного пространства в другое, соответственно. Для
получения дополнительной информации см.
раздел 16.7.9.
UNION
UNION
используется, когда Вы хотите получить доступ к набору идентичных таблиц
MyISAM
как к одной. Это работает только с MERGE
.
См. раздел 17.7.
Вы должны иметь привилегии
SELECT
, UPDATE
и DELETE
для таблиц, которые Вы отображаете на MERGE
.
Прежде, все используемые таблицы должны были быть в той же самой базе
данных, где MERGE
. Это ограничение больше не применяется.
partition_options
может использоваться, чтобы
управлять разделением таблицы, составленной с
CREATE TABLE
.
Не все варианты в синтаксисе для partition_options
в начале этого раздела доступны для всех типов разделения. Пожалуйста, см.
списки для следующих отдельных типов для информации, определенной для каждого
типа, и см. главу 20 для подробностей.
Если используется, partition_options
начинается с
PARTITION BY
. Этот пункт содержит функцию, которая используется,
чтобы определить разделение, функция возвращает целочисленное значение в
пределах от 1 до num
, где num
число разделов. Максимальное количество определяемых пользователем разделов,
которые может содержать таблица, 1024, число подразделов рассматривается
позже и включено в этот максимум. Выбор, который доступен для этой функции в
MySQL 8.0, показывают в следующем списке:
HASH(
:
Хеширует один или более столбцов, чтобы создать ключ для размещения и
расположения строк. expr
)expr
это выражение, использующее
один или более столбцов таблицы. Это может быть любым допустимым выражением
MySQL (включая функции MySQL), которое приводит к единственному
целочисленному значению. Например, эти два допустимы для
CREATE TABLE
PARTITION BY HASH
:
CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1); CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH (YEAR(col3));Вы не можете использовать также
VALUES LESS THAN
или
VALUES IN
с PARTITION BY HASH
.
PARTITION BY HASH
использует остаток от
expr
разделенный на число разделов (то есть, модуль).
Для примеров и дополнительной информации см.
раздел 20.2.4.
LINEAR
влечет за собой несколько различный алгоритм. В
этом случае номер раздела, в котором сохранена строка, вычислен как результат
одной или более логических операций
AND
. См. раздел
20.2.4.1.
KEY(column_list
)
:
Это подобно HASH
, за исключением того, что MySQL поставляет
хеширующую функцию, чтобы гарантировать даже распределение данных.
column_list
просто список из 1 или более столбцов
таблицы (максимум: 16). Этот пример показывает простую таблицу,
разделенную ключом, с 4 разделами:
CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3) PARTITIONS 4;Для таблиц, которые разделены ключом, Вы можете использовать линейное разделение при использовании
LINEAR
. Это имеет тот же самый
эффект, как с таблицами, которые разделены HASH
.
Таким образом, номер раздела найден, используя оператор
&
(см. разделы
20.2.4.1 и
20.2.5). Этот пример использует
линейное разделение ключом, чтобы распределить данные между 5 разделами:
CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY(col3) PARTITIONS 5;Опция
ALGORITHM={1|2}
поддержана с
[SUB]PARTITION BY [LINEAR] KEY
. ALGORITHM=1
заставляет сервер использовать те же самые хеширующие ключ функции, как в
5.1, ALGORITHM=2
значит, что сервер использует хеширующие ключ
функции, осуществленные и используемые по умолчанию для нового варианта
KEY
в MySQL 5.5 и позже.
Разделенные таблицы, составленные с хеширующими ключ функциями, используемыми
в MySQL 5.5 и позже, не могут использоваться MySQL 5.1.
Неопределение опции имеет тот же самый эффект, как использование
ALGORITHM=2
. Эта опция предназначена для использования в
основном, обновляя таблицы, разделенные [LINEAR] KEY
между MySQL 5.1 и более поздними версиями MySQL, или для того, чтобы
составить таблицы, разделенные KEY
или LINEAR KEY
в MySQL 5.5 или более позднем сервере, который может использоваться на MySQL
5.1. См. раздел
14.1.7.1.
mysqldump в MySQL 5.7 (и позже) пишет эту опцию в комментарии версии:
CREATE TABLE t1 (a INT)
/*!50100 PARTITION BY KEY */ /*!50611 ALGORITHM = 1 */ /*!50100 ()
PARTITIONS 3 */
Это заставляет MySQL 5.6.10 и более ранние серверы игнорировать опцию,
которая иначе вызвала бы синтаксическую ошибку в тех версиях. Если Вы
планируете загрузить дамп, сделанный на MySQL 5.7, где Вы используете
таблицы, которые разделены или подразделены KEY
в MySQL 5.6
до 5.6.11, см. Changes Affecting Upgrades to MySQL 5.6.
Информация, найденная там, также применяется, если Вы загружаете дамп,
содержащий разделенные или подразделенные KEY
таблицы, сделанные в MySQL 5.7-5.6.11 или позже в MySQL 5.5.30
или более ранний сервер.
В MySQL 5.6.11 и позже ALGORITHM=1
показан когда необходимо в выводе
SHOW CREATE TABLE
использование версионного комментария в той же самой манере, как в
mysqldump.
ALGORITHM=2
всегда опускается из вывода SHOW CREATE TABLE
, даже если эта опция была определена, составляя оригинальную таблицу.
Вы не можете использовать также VALUES LESS THAN
или
VALUES IN
с PARTITION BY KEY
.
RANGE(expr
)
: В этом случае
expr
показывает диапазон значений, используя ряд
операторов VALUES LESS THAN
. Используя разделение диапазона, Вы
должны определить по крайней мере одно использование разделения
VALUES LESS THAN
. Вы не можете использовать
VALUES IN
с разделением диапазона.
Для таблиц, разделенных RANGE
,
VALUES LESS THAN
должен использоваться или с целым числом
или с выражением, которое приводит к единственному целочисленному значению.
В MySQL 8.0 Вы можете преодолеть это ограничение в таблице, которая
определена, используя PARTITION BY RANGE COLUMNS
,
как описано позже в этом разделе.
Предположите, что у Вас есть таблица, которую Вы хотите разделить на столбце, содержащем значения года, согласно следующей схеме.
Номер раздела | Диапазон лет |
---|---|
0 | 1990 и раньше |
1 | 1991-1994 |
2 | 1995-1998 |
3 | 1999-2002 |
4 | 2003-2005 |
5 | 2006 и позже |
Таблица, осуществляющая такую схему разделения, может быть создана
CREATE TABLE
:
CREATE TABLE t1 (year_col INT, some_data INT) PARTITION BY RANGE (year_col) (PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999), PARTITION p3 VALUES LESS THAN (2002), PARTITION p4 VALUES LESS THAN (2006), PARTITION p5 VALUES LESS THAN MAXVALUE);
PARTITION ... VALUES LESS THAN ...
работают последовательным способом. VALUES LESS THAN MAXVALUE
,
чтобы определить левые
значения, которые больше, чем максимальное значение, определенное иначе.
VALUES LESS THAN
работают последовательно в манере, подобной
case
в switch ... case
блоке (как в языках
C, Java и PHP). Таким образом, пункты должны быть расположены таким способом,
которым верхний предел определил в каждом последовательном
VALUES LESS THAN
значение больше, чем из предыдущего, со ссылкой
MAXVALUE
на последнее из всех в списке.
RANGE COLUMNS(column_list
)
:
Эта разновидность RANGE
облегчает сокращение разделения для
запросов, используя условия диапазона на многих столбцах (то есть, имея такие
условия, как WHERE a = 1 AND b < 10
или
WHERE a = 1 AND b = 10 AND c < 10
).
Это позволяет Вам определить диапазоны значения при использовании списка
столбцов в COLUMNS
и ряд значений столбцов в каждом
PARTITION ... VALUES LESS THAN (value_list
)
. В самом простом случае этот набор состоит из единственного столбца.
Максимальное количество столбцов, на которые можно сослаться в
column_list
и value_list
16.
column_list
используемый в COLUMNS
может содержать только названия столбцов, каждый столбец в списке должен быть
одним из следующих типов данных MySQL: типы целого числа, строковые и типы
времени или даты. Использование столбцов
BLOB
, TEXT
, SET
, ENUM
,
BIT
или пространственных типов не разрешено, столбцы, которые
используют типы числа с плавающей запятой, также не разрешены. Вы также не
можете использовать функции или арифметические выражения в
COLUMNS
.
VALUES LESS THAN
, используемый в определении разделения,
должен определить литеральное значение для каждого столбца, который
появляется в COLUMNS()
,
то есть, список значений для каждого VALUES LESS THAN
должен содержать то же самое число значений, сколько есть столбцов,
перечисленных в COLUMNS
. Попытка использовать больше или меньше
значений в VALUES LESS THAN
, чем есть в COLUMNS
заставляет запрос терпеть неудачу с ошибкой Inconsistency
in usage of column lists for partitioning....
Вы не можете использовать NULL
для любого значения, появляющегося в VALUES LESS THAN
.
Возможно использовать MAXVALUE
не раз для любого столбца, кроме первого, как показано в этом примере:
CREATE TABLE rc (a INT NOT NULL, b INT NOT NULL) PARTITION BY RANGE COLUMNS(a,b) (PARTITION p0 VALUES LESS THAN (10,5), PARTITION p1 VALUES LESS THAN (20, 10), PARTITION p2 VALUES LESS THAN (MAXVALUE, 15), PARTITION p3 VALUES LESS THAN (MAXVALUE, MAXVALUE));Каждое значение в списке значения
VALUES LESS THAN
должно соответствовать типу соответствующего столбца точно: никакое
преобразование не сделано. Например, Вы не можете использовать строку
'1'
для значения, которое соответствует столбцу, который
использует тип целого числа (Вы должны использовать цифру 1
),
и при этом Вы не можете использовать цифру 1
для значения, которое соответствует столбцу, который использует строковый тип
(в таком случае, Вы должны использовать заключенную в кавычки строку
'1'
).LIST(expr
)
:
Это полезно, назначая разделение, основанное на столбце таблицы с
ограниченным набором возможных значений, например, статус или код страны.
В таком случае все строки, имеющие отношение к определенному статусу
или стране, могут быть назначены на единственный раздел
или раздел может быть сохранен для определенного набора статусов
или стран. Это подобно RANGE
, за исключением того, что только
VALUES IN
может использоваться, чтобы определить допустимые
значения для каждого раздела.
VALUES IN
используется со списком значений, которые будут
соответствующими. Например, Вы могли создать схему разделения,
такую как следующее:
CREATE TABLE client_firms (id INT, name VARCHAR(35)) PARTITION BY LIST (id) (PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24));Используя разделение списка, Вы должны определить по крайней мере одно использование
VALUES IN
. Вы не можете использовать
VALUES LESS THAN
с PARTITION BY LIST
.
Для таблиц, разделенных LIST
список значений, используемый с
VALUES IN
, должен состоять только из целочисленных значений. В
MySQL 8.0 Вы можете преодолеть это ограничение использованием LIST
COLUMNS
, который описан позже в этом разделе.
LIST COLUMNS(column_list
)
:
Это разновидность LIST
облегчает сокращение разделения для
запросов, используя условия сравнения на многих столбцах (то есть, имея
условия вроде WHERE a = 5 AND b = 5
или
WHERE a = 1 AND b = 10 AND c = 5
).
Это позволяет Вам определить значения во многих
столбцах при использовании списка столбцов в COLUMNS
и ряд значений столбцов в каждом PARTITION ... VALUES IN
(value_list
)
.
Правила относительно типов данных для списка столбца, используемого в
LIST COLUMNS(
и
списке значений в column_list
)VALUES IN(
те же самые, как для списка столбцов, используемого в value_list
)RANGE
COLUMNS(
и списке значений в
column_list
)VALUES LESS THAN(
,
соответственно, за исключением того, что в value_list
)VALUES IN
MAXVALUE
не разрешен, и Вы можете использовать NULL
.
Есть одно важное различие между списком значений, используемых для
VALUES IN
с PARTITION BY LIST COLUMNS
в противоположность тому, когда это используется с
PARTITION BY LIST
. В PARTITION BY LIST COLUMNS
каждый элемент в VALUES IN
должен быть рядом значений столбцов,
число значений в каждом наборе должно быть тем же самым, как число столбцов,
используемых в COLUMNS
, типы данных этих значений должны
соответствовать таковым из столбцов (и в том же самом порядке). В самом
простом случае набор состоит из единственного столбца. Максимальное
количество столбцов, которые могут использоваться в
column_list
и в элементах, составляющих
value_list
16.
Таблица определена следующим CREATE TABLE
обеспечивает пример табличного использования LIST COLUMNS
:
CREATE TABLE lc (a INT NULL, b INT NULL) PARTITION BY LIST COLUMNS(a,b) (PARTITION p0 VALUES IN((0,0), (NULL,NULL)), PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2)), PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1)), PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3)));
PARTITIONS num
, где
num
число разделов. Если этот пункт
и любой PARTITION
используются,
num
должно быть равным общему количеству разделов,
которое объявлено, используя PARTITION
.
Используете ли Вы PARTITIONS
в составлении таблицы, которая разделена RANGE
или
LIST
, Вы должны все еще включить по крайней мере один
PARTITION VALUES
в табличном определении (см. ниже).
SUBPARTITION BY
. Подраздел может быть сделан
HASH
или KEY
. Любой из них может быть
LINEAR
. Они работают таким же образом, как ранее описано для
эквивалентных типов разделов. Это не относится к подразделам
LIST
или RANGE
.
Число подразделов может быть обозначено, используя
SUBPARTITIONS
с целочисленным значением.
PARTITIONS
или
SUBPARTITIONS
применена, и это значение должно
придерживаться следующих правил:
Значение должно быть положительным целым числом, отличным от нуля.
PARTITIONS 0.2E+01
не разрешен, даже
при том, что 0.2E+01
это 2
(Bug #15890).
Выражение (expr
) в PARTITION BY
не может отнестись ни к каким столбцам не в составленной таблице, такие
ссылки определенно не разрешены и заставляют запрос терпеть
неудачу с ошибкой (Bug #29444).
Каждое разделение может быть индивидуально определено, используя
partition_definition
.
Отдельные части, составляющие этот пункт, следующие:
PARTITION
:
Это определяет логическое имя для разделения.partition_name
VALUES
: Для разделения диапазона каждое разделение должно
включать VALUES LESS THAN
, для разделения списка Вы должны
определить VALUES IN
для каждого раздела. Это используется,
чтобы определить, какие строки должны быть сохранены в этом разделе.
См. обсуждения разделения типов в главе 20.COMMENT
может использоваться, чтобы определить строку,
которая описывает раздел. Пример:
COMMENT = 'Data for the years previous to 1999'Максимальная длина для комментария 1024 символа.
DATA DIRECTORY
и INDEX DIRECTORY
может использоваться, чтобы указать на каталог, где данные и индекс для этого
раздела должны быть сохранены, соответственно. Оба
data_dir
и
index_dir
должны быть абсолютными системными путями. Пример:
CREATE TABLE th (id INT, name VARCHAR(30), adate DATE) PARTITION BY LIST(YEAR(adate)) (PARTITION p1999 VALUES IN (1995, 1999, 2003) DATA DIRECTORY = '/var/appdata/95/data
' INDEX DIRECTORY = '/var/appdata/95/idx
', PARTITION p2000 VALUES IN (1996, 2000, 2004) DATA DIRECTORY = '/var/appdata/96/data
' INDEX DIRECTORY = '/var/appdata/96/idx
', PARTITION p2001 VALUES IN (1997, 2001, 2005) DATA DIRECTORY = '/var/appdata/97/data
' INDEX DIRECTORY = '/var/appdata/97/idx
', PARTITION p2002 VALUES IN (1998, 2002, 2006) DATA DIRECTORY = '/var/appdata/98/data
' INDEX DIRECTORY = '/var/appdata/98/idx
');
DATA DIRECTORY
и INDEX DIRECTORY
ведут себя таким же образом, как в
CREATE TABLE
table_option
для таблиц MyISAM
.
Один каталог данных и индекса может быть определен на раздел. Если оставлено не указанным, данные и индекс сохранены по умолчанию в каталоге базы данных таблицы.
DATA DIRECTORY
и INDEX DIRECTORY
проигнорированы для того, чтобы составить разделенные таблицы, если
работает
NO_DIR_IN_CREATE
.
MAX_ROWS
и MIN_ROWS
может использоваться, чтобы определить, соответственно, максимальное и
минимальное число строк, которые будут сохранены в разделе. Значения для
max_number_of_rows
и
min_number_of_rows
должны быть положительные целые
числа. Как с опциями на уровне таблицы с теми же самыми именами, они
действуют только как подсказки
серверу и не являются жесткими пределами.TABLESPACE
может использоваться, чтобы назначить
табличное разделение или подразделение InnoDB
к
общему табличному
пространству, отдельному табличному пространству file-per-table
или системному табличному пространству. Все разделение должно принадлежать
тому же самому механизму хранения. Для получения дополнительной информации
см. раздел 16.7.9.[STORAGE] ENGINE
для
PARTITION
и SUBPARTITION
.
В настоящее время единственный путь, которым может использоваться эта опция,
состоит в том, чтобы установить все разделение или все подразделение к тому
же самому механизму хранения, попытка установить различные механизмы хранения
для разделения или подразделения в той же самой таблице даст ошибку
ERROR 1469 (HY000): The mix of handlers in the partitions is not
permitted in this version of MySQL.subpartition_definition
. Каждый из них состоит
минимум из SUBPARTITION name
, где
name
идентификатор для подразделения. За исключением
замены PARTITION
на SUBPARTITION
,
синтаксис для определения подразделения идентичен синтаксису
для определения разделения.
Подразделение должно быть сделано HASH
или
KEY
и может быть сделано только на
RANGE
или LIST
. См.
раздел 20.2.6.
Разделение произведенными столбцами разрешено. Например:
CREATE TABLE t1 (s1 INT, s2 INT AS (EXP(s1)) STORED) PARTITION BY LIST (s2) (PARTITION p1 VALUES IN (1));Разделение рассматривает произведенный столбец как регулярный столбец, который является обходным решениям для ограничений на функции, которые не разрешены для того, чтобы разделить (см. раздел 20.6.3). Предыдущий пример демонстрирует этот метод:
EXP()
не может использоваться непосредственно в
PARTITION BY
, но произведенный столбец определил использование
EXP()
.
яРазделение может быть изменено, слито, добавлено к таблицам и исключено из таблиц. Для основной информации о запросах MySQL, чтобы выполнить эти задачи, см. раздел 14.1.7. Подробности в разделе 20.3.
Оригинал CREATE TABLE
,
включая все технические требования и табличные опции сохранено MySQL, когда
таблица составлена. Это сделано, чтобы, если Вы изменяете сопоставления или
другие настройки, используя
ALTER TABLE
,
оригинальные табличные определенные опции были сохранены. Это позволяет Вам
изменять табличные типы даже при том, что форматы строки, поддержанные этими
двумя механизмами, могут отличаться.
Поскольку текст оригинального запроса сохранен, но из-за способа, которым
могут быть тихо реконфигурированы определенные значения и опции (хотя бы
ROW_FORMAT
), активное табличное определение (доступно через
DESCRIBE
или
SHOW TABLE STATUS
)
и табличная строка создания (доступна через
SHOW CREATE TABLE
)
сообщат различные значения.
CREATE TABLE ... LIKE
применяется, чтобы
составить пустую таблицу, основанную на определении другой таблицы, включая
любой столбец, префикс и индекс, определенные в оригинальной таблице:
CREATE TABLEКопия создается, используя ту же самую версию табличного формата хранения, как оригинальная таблица. Привилегияnew_tbl
LIKEorig_tbl
;
SELECT
требуется на оригинальной таблице.
LIKE
работает только для базовых таблиц,
не для представлений.
Вы не можете выполнить CREATE TABLE
или
CREATE TABLE ... LIKE
в то время, как есть запрос
LOCK TABLES
.
CREATE TABLE ... LIKE
осуществляет те же самые проверки, как
CREATE TABLE
.
Это означает, что, если текущий режим SQL отличается от режима в
действительности, когда оригинальная таблица была составлена, табличное
определение можно было бы считать недопустимым для нового режима, и
запрос потерпит неудачу.
Для CREATE TABLE ... LIKE
целевая таблица сохраняет произведенную информацию о столбце
от оригинальной таблицы.
CREATE TABLE ... LIKE
не сохраняет табличные опции
DATA DIRECTORY
или INDEX DIRECTORY
, которые были
определены для оригинальной таблицы, или любые определения внешнего ключа.
Если оригинальная таблица TEMPORARY
,
CREATE TABLE ... LIKE
не сохраняет TEMPORARY
.
Чтобы создать целевую таблицу TEMPORARY
, надо использовать
CREATE TEMPORARY TABLE ... LIKE
.
Вы можете составить одну таблицу от другой, добавляя
SELECT
в конец
the CREATE TABLE
:
CREATE TABLEMySQL создает новые столбцы для всех элементов вnew_tbl
[AS] SELECT * FROMorig_tbl
;
SELECT
:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT, -> PRIMARY KEY (a), KEY(b)) -> ENGINE=MyISAM SELECT b,c FROM test2;Это создает
MyISAM
с тремя столбцами, a
, b
и c
.
ENGINE
часть CREATE TABLE
и не должно использоваться после
SELECT
, это привело бы к
синтаксической ошибке. То же самое истина для других опций
CREATE TABLE
,
например, для CHARSET
.
Заметьте, что столбцы из
SELECT
добавлены
к правой стороне таблицы. Возьмите следующий пример:
mysql> SELECT * FROM foo; +---+ | n | +---+ | 1 | +---+ mysql> CREATE TABLE bar (m INT) SELECT n FROM foo; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM bar; +------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)Для каждой строки в таблице
foo
строка вставлена в
bar
со значениями из foo
и значениями по умолчанию для новых столбцов.
В таблице, следующей из CREATE TABLE
... SELECT
, столбцы, названные только в части
CREATE TABLE
на первом месте. Столбцы, названные в обеих частях или только в
SELECT
, прибывают после этого.
Тип данных столбцов SELECT
могут быть переопределены, также определяя столбец в части
CREATE TABLE
.
Если какие-либо ошибки происходят, копируя данные к таблице, таблица автоматически удалена и не создана.
Вы можете предшествовать SELECT
IGNORE
или REPLACE
,
чтобы указать, как обработать строки, которые дублируют уникальные значения
ключа. С IGNORE
отказываются от строк, которые дублируют
существующую строку на уникальном значении ключа. С
REPLACE
новые строки заменяют
строки, у которых есть то же самое уникальное значение ключа. Если
IGNORE
или REPLACE
не определен, будет ошибка дубликата уникального значения ключа.
Поскольку упорядочивание строк в основном
SELECT
не может всегда определяться, CREATE TABLE ... IGNORE SELECT
и CREATE TABLE ... REPLACE SELECT
отмечены как опасные для основанной на запросе репликации.
С этим изменением такие запросы производят предупреждение в журнале,
используя основанный на запросе режим и зарегистрированы, используя
основанный на строке формат, используя режим MIXED
.
См. раздел 19.2.1.1.
CREATE TABLE ... SELECT
автоматически не создает индекс. Это сделано преднамеренно, чтобы сделать
запрос настолько гибким насколько возможно. Если Вы хотите иметь индексы в
составленной таблице, Вы должны определить их перед
SELECT
:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;Для
CREATE TABLE ... SELECT
целевая таблица
не сохраняет информацию о том, являются ли столбцы, выбранные из исходной
таблицы, произведенными столбцами. Часть
SELECT
не может назначить значения на произведенные
столбцы в целевой таблице.
Некоторое преобразование типов данных могло бы произойти. Например,
AUTO_INCREMENT
не сохранен, и
VARCHAR
могут стать
CHAR
. Сохраняются признаки
NULL
(или NOT NULL
) для тех столбцов, у которых они
есть, CHARACTER SET
, COLLATION
,
COMMENT
и DEFAULT
.
Составляя таблицу с CREATE
TABLE ... SELECT
, удостоверьтесь в псевдонимах любых вызовов
функции или выражения в запросе. Если Вы не делаете этого,
CREATE
мог бы потерпеть неудачу или привести к
нежелательным именам столбцов.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;Вы можете также явно определить тип данных для столбца в составленной таблице:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;Для
CREATE TABLE
... SELECT
, если задано IF NOT EXISTS
и целевая таблица существует, ничто не вставлено в целевую таблицу, и
запрос не зарегистрирован.
Чтобы гарантировать, что двоичный журнал может использоваться, чтобы
обновить оригинальные таблицы, MySQL не разрешает параллельные вставки во
время CREATE TABLE ... SELECT
.
Вы не можете использовать FOR UPDATE
как часть
SELECT
в таком запросе, как
CREATE
TABLE
.
Если Вы пытаетесь сделать так, запрос терпит неудачу.new_table
SELECT ... FROM
old_table
...
MySQL поддерживает внешние ключи, которые позволяют Вам перекрестно
ссылаться на связанные данные через таблицы, и
ограничения внешнего
ключа, которые сохраняют эти данные распространения последовательными.
Существенный синтаксис для определения ограничения внешнего ключа в
CREATE TABLE
или
ALTER TABLE
похож на это:
[CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
, ...) REFERENCEStbl_name
(index_col_name
,...) [ON DELETEreference_option
] [ON UPDATEreference_option
]reference_option
: RESTRICT | CASCADE | SET NULL | NO ACTION
index_name
представляет ID внешнего ключа.
index_name
проигнорировано, если уже есть явно
определенный индекс на дочерней таблице, которая может поддержать внешний
ключ. Иначе MySQL неявно создает индекс внешнего ключа, который называют
согласно следующим правилам:
Если определено, CONSTRAINT
symbol
. Иначе FOREIGN KEY
index_name
.
CONSTRAINT
symbol
или
FOREIGN KEY
index_name
не определен, имя индекса внешнего ключа произведено, используя название
столбца внешнего ключа ссылки.Определения внешних ключей подвергаются следующим условиям:
Отношения внешнего ключа вовлекают
родительскую таблицу,
которая содержит центральные значения данных, и
дочернюю таблицу
с идентичными значениями, указывающими на родителя. FOREIGN KEY
определен в дочерней таблице. Родительские и дочерние таблицы должны
использовать тот же самый механизм хранения.
Они не должны быть TEMPORARY
.
В MySQL 8.0 создание ограничения внешнего ключа требует привилегию
REFERENCES
для родительской таблицы.
foreign_key_checks
, что является настройкой по умолчанию,
преобразование набора символов не разрешено на таблицах, которые включают
столбец строки символов, используемый в ограничение внешнего ключа. Обходное
решение описано в разделе 14.1.7.index_name
, если дано, используется
как описано ранее.InnoDB
разрешает внешнему ключу ссылаться на любой столбец
или группу столбцов. Однако, в таблице, на которую ссылаются, должен быть
индекс, где столбцы, на которые ссылаются, перечислены как
первые столбцы в том же самом порядке.BLOB
и
TEXT
не могут быть включены во внешний ключ, потому что индекс на тех столбцах,
должен всегда включать длину префикса.CONSTRAINT symbol
,
symbol
, если используется, должно быть уникальным в
базе данных. Дубликат symbol
приведет к ошибке:
ERROR 1022 (2300): Can't write;
duplicate key in table '#sql- 464_1'.
Если пункт не дан, или symbol
не включен после CONSTRAINT
,
название ограничения создается автоматически.InnoDB
в настоящее время не
поддерживает внешние ключи для таблиц с определяемым пользователем
разделением. Это включает родительские и дочерние таблицы.Этот раздел описывает, как ссылка внешних ключей гарантирует целостность.
Для механизмов хранения, поддерживающих внешние ключи, MySQL отклоняет
любой INSERT
или
UPDATE
, который
пытается создать значение внешнего ключа в дочерней таблице, если есть не
соответствующее значение ключа в родительской таблице.
Когда UPDATE
или
DELETE
затрагивает значение ключа в родительской таблице, у которой есть
соответствие строк в дочерней таблице, результат зависит от
действия, определенного, используя
ON UPDATE
и ON DELETE
в FOREIGN KEY
.
MySQL поддерживает пять опций относительно действия, перечисленных здесь:
CASCADE
: Удалит или обновит строку из родительской
таблицы и автоматически удалит или обновит соответствующие строки в дочерней
таблице. ON DELETE CASCADE
и ON UPDATE CASCADE
поддержаны. Между двумя таблицами не определяйте несколько
ON UPDATE CASCADE
, которые действуют на тот же самый столбец в
родительской или в дочерней таблице.
Каскадные действия внешнего ключа не активируют триггеры.
SET NULL
: Удалит или обновит строку из родительской таблицы и
установит столбец внешнего ключа или столбцы в дочерней таблице к
NULL
. ON DELETE SET NULL
и ON UPDATE
SET NULL
поддержаны.
Если Вы определяете SET NULL
,
удостоверьтесь, что Вы не объявили столбцы в дочерней таблице как
NOT NULL
.
RESTRICT
: Отклоняет работу удаления или обновления для
родительской таблицы. Определение RESTRICT
(или NO ACTION
) то же самое, как исключение ON DELETE
или ON UPDATE
.NO ACTION
: Ключевое слово от стандартного SQL. В MySQL
эквивалент RESTRICT
. MySQL Server отклоняет работу удаления или
обновления для родительской таблицы, если есть связанное значение внешнего
ключа в таблице, на которую ссылаются. Некоторые системы базы данных
задерживают проверки, и NO ACTION
это задержанная проверка. В
MySQL ограничения внешнего ключа немедленно проверены, таким образом,
NO ACTION
то же самое, как RESTRICT
.SET DEFAULT
: Это действие признано анализатором MySQL, но
InnoDB
отклоняет табличные определения, содержащие
ON DELETE SET DEFAULT
или ON UPDATE SET DEFAULT
.
Для ON DELETE
или ON UPDATE
действие значения по умолчанию всегда RESTRICT
.
MySQL поддерживает ссылки внешнего ключа между одним столбцом и другим в пределах таблицы. У столбца не может быть ссылки внешнего ключа на себя. В этих случаях дочерняя таблица действительно обращается к зависимым записям в пределах той же самой таблицы.
Ограничение внешнего ключа на произведенный сохраненный столбец не может
использовать ON UPDATE CASCADE
, ON DELETE SET NULL
,
ON UPDATE SET NULL
, ON DELETE SET DEFAULT
или
ON UPDATE SET DEFAULT
.
Ограничение внешнего ключа не может сослаться на произведенный виртуальный столбец.
Для InnoDB
ограничения, связанные с внешними ключами и
произведенными столбцами, см. в
разделе 16.8.6.
Вот простой пример, который имеет отношение таблиц parent
и child
через внешний ключ единственного столбца:
CREATE TABLE parent (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE child (id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE) ENGINE=INNODB;Более сложный пример, в котором у таблицы
product_order
есть внешние ключи для двух других таблиц. Один внешний ключ ссылается на
индекс из двух столбцов в таблице product
.
Второй ссылается на индекс из единственного столбца в customer
:
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, product_category INT NOT NULL, product_id INT NOT NULL, customer_id INT NOT NULL, PRIMARY KEY(no), INDEX (product_category, product_id), INDEX (customer_id), FOREIGN KEY (product_category, product_id) REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, FOREIGN KEY (customer_id) REFERENCES customer(id)) ENGINE=INNODB;
Вы можете добавить новое ограничение внешнего ключа к существующей таблице
при использовании ALTER TABLE
.
Синтаксис, касающийся внешних ключей для этого запроса:
ALTER TABLEВнешний ключ может быть сам ссылочным (обращающийся к той же самой таблице). Когда Вы добавляете ограничение внешнего ключа к таблице черезtbl_name
ADD [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
, ...) REFERENCEStbl_name
(index_col_name
,...) [ON DELETEreference_option
] [ON UPDATEreference_option
]
ALTER TABLE
,
не забудьте создать необходимый индекс сначала.
Вы можете также использовать ALTER
TABLE
, чтобы удалить внешние ключи, используя
синтаксис, показанный здесь:
ALTER TABLEЕслиtbl_name
DROP FOREIGN KEYfk_symbol
;
FOREIGN KEY
включал имя CONSTRAINT
,
когда Вы создали внешний ключ, Вы можете обратиться к тому имени, чтобы
удалить внешний ключ. Иначе значение fk_symbol
произведено внутренне, когда внешний ключ создается. Чтобы узнать символьное
значение, когда Вы хотите удалить внешний ключ, используйте
SHOW CREATE TABLE
:
mysql> SHOW CREATE TABLE ibtest11c\G *************************** 1. row *************************** Table: ibtest11c Create Table: CREATE TABLE `ibtest11c` ( `A` int(11) NOT NULL auto_increment, `D` int(11) NOT NULL default '0', `B` varchar(200) NOT NULL default '', `C` varchar(175) default NULL, PRIMARY KEY (`A`,`D`,`B`), KEY `B` (`B`,`C`), KEY `C` (`C`), CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`) REFERENCES `ibtest11a` (`A`, `D`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`) REFERENCES `ibtest11a` (`B`, `C`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=INNODB CHARSET=latin1 1 row in set (0.01 sec) mysql> ALTER TABLE ibtest11c DROP FOREIGN KEY `0_38775`;Добавление и удаление внешнего ключа в том же самом
ALTER TABLE
поддержано для
ALTER TABLE ... ALGORITHM=INPLACE
, но не поддержано для
ALTER TABLE ... ALGORITHM=COPY
.
В MySQL 8.0 сервер запрещает изменения столбцов внешнего ключа с
потенциалом потери справочной целостности. Обходное решение должно
использовать ALTER TABLE ... DROP FOREIGN
KEY
прежде, чем изменить определение столбца и
ALTER TABLE ... ADD
FOREIGN KEY
позже.
Таблица и идентификаторы столбца в FOREIGN KEY ...
REFERENCES ...
могут быть заключены в кавычки в пределах обратных
кавычек (`
). Альтернативно, двойные кавычки ("
)
может использоваться, если включен режим SQL
ANSI_QUOTES
.
Установка
lower_case_table_names
также принята во внимание.
Вы можете рассмотреть определения внешнего ключа дочерней таблицы как
часть вывода SHOW CREATE TABLE
:
SHOW CREATE TABLE tbl_name
;
Вы можете также получить информацию о внешних ключах, запрашивая таблицу
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
.
Вы можете считать информацию о внешних ключах, используемую таблицами
InnoDB
в
INNODB_SYS_FOREIGN
и
INNODB_SYS_FOREIGN_COLS
в базе
данных INFORMATION_SCHEMA
.
mysqldump производит правильные определения таблиц в файле дампа, включая внешние ключи для дочерних таблиц.
Чтобы облегчить перезагрузку файла дампа для таблиц, у которых есть
отношения внешнего ключа,
mysqldump автоматически, включает запрос в вывод дампа,
чтобы установить
foreign_key_checks
в 0. Это избегает проблем с таблицами, имеющими
необходимость быть перезагруженными в особом порядке, когда дамп
перезагружен. Также возможно установить эту переменную вручную:
mysql> SET foreign_key_checks = 0;
mysql> SOURCE dump_file_name
;
mysql> SET foreign_key_checks = 1;
Это позволяет Вам импортировать таблицы в любом порядке, если файл дампа
содержит таблицы, которые правильно не упорядочены для внешних ключей.
Это также ускоряет работу импорта. Установка
foreign_key_checks
в 0 может также быть полезна для игнорирования ограничений
внешнего ключа во время LOAD DATA
и ALTER TABLE
.
Однако, даже если
foreign_key_checks = 0
, MySQL не разрешает создание ограничения
внешнего ключа, где столбец ссылается на несоответствующий тип столбца. Кроме
того, если у таблицы есть ограничения внешнего ключа,
ALTER TABLE
не может использоваться, чтобы изменить таблицу, чтобы использовать другой
механизм хранения. Чтобы изменить механизм хранения, Вы должны сначала
удалить любые ограничения внешнего ключа.
Вы не можете использовать DROP TABLE
для таблицы, на которую ссылается ограничение FOREIGN KEY
, если Вы не делаете SET foreign_key_checks = 0
.
Когда Вы удаляете таблицу, любые ограничения, которые были определены в
запросе, используемом, чтобы составить эту таблицу, также удалены.
Если Вы обновляете таблицу, которая была удалена, у нее
должно быть определение, которое соответствует ограничениям внешнего ключа,
ссылающимся на нее. У этого должны быть правильные имена столбцов и типы, и
таблица должна иметь индекс на ключах, на которые ссылаются, как заявлено
ранее. Если эти условия не удовлетворены, MySQL возвращает Error 1005 и
Error 150 в сообщении об ошибке, что означает, что ограничение внешнего ключа
не было правильно сформировано. Точно так же, если
ALTER TABLE
терпит неудачу из-за Error 150, это означает, что определение внешнего ключа
было неправильно сформировано для измененной таблицы.
Для таблиц InnoDB
Вы можете получить подробное объяснение
ошибки внешнего ключа в MySQL Server, просмотрев вывод
SHOW ENGINE INNODB STATUS
.
Для пользователей, знакомых с ANSI/ISO SQL Standard,
отметьте, что никакой механизм хранения, включая InnoDB
,
не признает или проводит в жизнь MATCH
в определениях ограничения справочной целостности. Использование явного
MATCH
не будет иметь указанного эффекта, и также вызывает
ON DELETE
и ON UPDATE
, которые будут
проигнорированы. По этим причинам определть MATCH
не надо.
MATCH
в стандарте SQL управляет, как
NULL
обработаны в сложном (из нескольких столбцов) внешнем
ключе, сравниваясь с первичным ключом. MySQL по существу осуществляет
семантику, определенную MATCH SIMPLE
, которые разрешают внешнему
ключу быть всему или частично NULL
. В этом случае (дочерняя
таблица) строке, содержащей такой внешний ключ, разрешают быть вставленной
и не соответствовать строке в (родительской) таблице, на которую ссылаются.
Возможно осуществить другую семантику, используя триггеры.
Дополнительно, MySQL требует, чтобы столбцы, на которые ссылаются,
были индексированы по исполнительным причинам. Однако, система не проводит в
жизнь требование, что столбцы, на которые ссылаются, UNIQUE
или объявлены NOT NULL
. Обработка ссылок внешнего ключа на
групповые ключи или ключи, которые содержат NULL
не четко
определены для таких операций, как
UPDATE
или DELETE CASCADE
. Вам советуют использовать внешние ключи, которые ссылаются только на
UNIQUE
(включая PRIMARY
) и
ключи NOT NULL
.
Кроме того, MySQL разбирает, но игнорирует inline
REFERENCES
(как определено в SQL),
где ссылки определены как часть спецификации столбца. MySQL принимает
REFERENCES
только когда определено как часть отдельного
FOREIGN KEY
. Для механизмов хранения, которые не поддерживают
внешние ключи (MyISAM
, например), MySQL Server
разбирает и игнорирует технические требования внешнего ключа.
CREATE TABLE
или
ALTER TABLE
.
Они могли бы быть изменениями типа данных, признаков, связанных с типом
данных или спецификации индекса.
Все изменения подвергаются внутреннему пределу размера строки 65535 байтов, которые могут заставить некоторые попытки изменений типа данных терпеть неудачу. См. раздел C.10.4 .
Столбцы, которые являются частью PRIMARY KEY
сделаны NOT NULL
, даже если так не объявлены.
ENUM
и
SET
, когда таблица составлена.USING
, чтобы определить тип индекса,
который не разрешен для данного механизма хранения, но есть другой доступный
тип индекса, который механизм может использовать, не затрагивая результаты
запроса, механизм использует доступный тип.VARCHAR
со спецификацией длины больше 65535 преобразован в
TEXT
, а
VARBINARY
со спецификацией длины больше 65535 преобразован в
BLOB
.
Иначе ошибка происходит в любом из этих случаев.CHARACTER SET binary
для символьного типа данных заставляет столбец создаваться как
соответствующий тип двоичных данных:
CHAR
станет
BINARY
,
VARCHAR
станет
VARBINARY
,
TEXT
станет
BLOB
.
ENUM
и
SET
это не происходит: они создаются
как объявлено. Предположите, что Вы определяете таблицу,
используя это определение:
CREATE TABLE t (c1 VARCHAR(10) CHARACTER SET binary, c2 TEXT CHARACTER SET binary, c3 ENUM('a','b','c') CHARACTER SET binary);У получающейся таблицы есть это определение:
CREATE TABLE t (c1 VARBINARY(10), c2 BLOB, c3 ENUM('a','b','c') CHARACTER SET binary);
Чтобы видеть, использовал ли MySQL тип данных кроме того, который Вы
определили, используйте DESCRIBE
или SHOW CREATE TABLE
после создания или изменения таблицы.
Определенные другие изменения типа данных могут произойти, если Вы сжимаете таблицу, используя myisampack. См. раздел 17.2.3.3.
CREATE TABLE
поддерживает спецификацию произведенных столбцов. Значения произведенного
столбца вычислены от выражения, включенного в определение столбца.
Следующий простой пример показывает таблицу, которая хранит длины сторон
прямоугольных треугольников в столбцах sidea
и sideb
и вычисляет длину гипотенузы в sidec
(квадратный корень сумм квадратов других сторон):
CREATE TABLE triangle (sidea DOUBLE, sideb DOUBLE, sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb))); INSERT INTO triangle (sidea, sideb) VALUES(1,1),(3,4),(6,8);Выбор из таблицы приводит к этому результату:
mysql> SELECT * FROM triangle; +-------+-------+--------------------+ | sidea | sideb | sidec | +-------+-------+--------------------+ | 1 | 1 | 1.4142135623730951 | | 3 | 4 | 5 | | 6 | 8 | 10 | +-------+-------+--------------------+Любое приложение, которое использует таблицу
triangle
имеет
доступ к значениям гипотенузы, не имея необходимость определять выражение,
которое вычисляет их.
У произведенных определений столбца есть этот синтаксис:
col_name
data_type
[GENERATED ALWAYS] AS (expression
) [VIRTUAL | STORED] [UNIQUE [KEY]] [COMMENTcomment
] [[NOT] NULL] [[PRIMARY] KEY]
AS (expression
)
указывает, что столбец произведен и определяет выражение, используемое, чтобы
вычислить значения столбцов. AS
можно предшествовать
GENERATED ALWAYS
, чтобы сделать произведенную природу столбца
более явной. Конструкции, которые разрешены или запрещены в
выражении, обсуждены позже.
VIRTUAL
или STORED
указывает, как сохранены значения столбцов, у которого есть значения
для использования столбца:
VIRTUAL
: Значения столбцов не сохранены, но оценены,
когда строки считаны, немедленно после любого триггера BEFORE
.
Виртуальный столбец не занимает места в памяти.
InnoDB
допускает вторичные индексы на
на виртуальных столбцах. См.
раздел 14.1.15.6.
STORED
: Значения столбцов оценены и сохранены, когда строки
вставлены или обновлены. Сохраненный столбец действительно требует места для
хранения и может быть индексирован.Значение по умолчанию VIRTUAL
,
если никакое ключевое слово не определено.
Разрешено смешивать столбцы VIRTUAL
и
STORED
в пределах таблицы.
Другие признаки могут быть даны, чтобы указать, индексирован ли столбец
или может быть NULL
. Отметьте, что порядок этих признаков
отличается от их порядка в непроизведенных определениях столбца.
Произведенные выражения столбца должны придерживаться следующих правил. Ошибка происходит, если выражение содержит отвергнутые конструкции.
Литералы, детерминированные встроенные функции и операторы
разрешены. Функция детерминирована, если, учитывая те же самые данные в
таблицах, многократные вызовы приводят к тому же самому результату,
независимо от соединенного пользователя. Примеры функций, которые подходят
под это определение:
CONNECTION_ID()
,
CURRENT_USER()
,
NOW()
.
AUTO_INCREMENT
не может использоваться в
произведенном определении столбца.AUTO_INCREMENT
не может использоваться в качестве основного
в произведенном определении столбца.CREATE TABLE
заканчивается с ошибкой, и работа DDL отклонена.Если выражение оценивается к типу данных, который отличается от заявленного типа столбца, принуждение к заявленному типу происходит согласно обычным правилам преобразования типа MySQL. См. раздел 13.2.
Если какой-либо компонент выражения зависит от режима SQL, различные результаты могут произойти для различного использования таблицы, если режим SQL не тот же самый во время всего использования.
Для CREATE TABLE ... LIKE
целевая таблица сохраняет произведенную информацию о столбце
от оригинальной таблицы.
Для CREATE
TABLE ... SELECT
целевая таблица не сохраняет информацию о том,
являются ли столбцы в выборке произведенными столбцами. Часть
SELECT
может назначить значения на
произведенные столбцы в целевой таблице.
Разделение произведенными столбцами разрешено.
Ограничение внешнего ключа на произведенный сохраненный столбец не может
использовать ON UPDATE CASCADE
, ON DELETE SET NULL
,
ON UPDATE SET NULL
, ON DELETE SET DEFAULT
или
ON UPDATE SET DEFAULT
.
Ограничение внешнего ключа не может сослаться на произведенный виртуальный столбец.
Для InnoDB
ограничения, связанные с внешними ключами и
произведенными столбцами, см. в
разделе 16.8.6.
Триггеры не могут использовать
NEW.
или
col_name
OLD.
, чтобы
обратиться к произведенным столбцам.col_name
Для INSERT
,
REPLACE
и
UPDATE
,
если произведенный столбец вставлен, заменил или обновил явно, единственное
разрешенное значение DEFAULT
.
Произведенный столбец в представлении считают обновляемым, потому что
возможно назначить ему значение. Однако, если такой столбец обновлен явно,
единственное разрешенное значение DEFAULT
.
У произведенных столбцов есть несколько случаев использования:
Виртуальные произведенные столбцы могут использоваться в качестве способа упростить и объединить запросы. Сложное условие может быть определено как произведенный столбец и упомянуто из многих запросов на таблице, чтобы гарантировать, что все они используют точно то же самое условие.
JSON
, см.
раздел 14.1.15.6.
Недостаток такого подхода: значения сохранены дважды, однажды как значение произведенного столбца и однажды в индексировании.
Предположите, что таблица t1
содержит столбцы
first_name
и last_name
,
и приложения часто создает полное имя, используя выражение:
SELECT CONCAT(first_name,' ',last_name) AS full_name FROM t1;Один способ избежать выписывать выражение состоит в том, чтобы создать представление
v1
на t1
, которое упрощает
приложения, позволяя им выбрать full_name
непосредственно,
не используя выражение:
CREATE VIEW v1 AS SELECT *, CONCAT(first_name,' ',last_name) AS full_name FROM t1; SELECT full_name FROM v1;Произведенный столбец также позволяет приложениям выбрать
full_name
непосредственно, без
потребности определить представление:
CREATE TABLE t1 (first_name VARCHAR(10), last_name VARCHAR(10), full_name VARCHAR(255) AS (CONCAT(first_name, ' ', last_name))); SELECT full_name FROM t1;
InnoDB
поддерживает вторичный индекс
на виртуальных произведенных столбцах. Другой тип индекса не поддержан.
Вторичный индекс может быть создан на одном или более виртуальных столбцах
или на комбинации виртуальных столбцов и непроизведенных виртуальных
столбцов. Вторичный индекс на виртуальных столбцах может быть
определен как UNIQUE
.
Когда вторичный индекс создается на произведенном виртуальном столбце, произведенные значения столбцов осуществлены в записях индекса. Если индексирование является покрывающим (который включает все столбцы, полученные запросом), произведенные значения столбцов получены от осуществленных значений в индексе вместо вычисленного на лету.
Если вторичный индекс не определен на виртуальном столбце, есть дополнительные затраты для чтений, поскольку виртуальные значения столбцов должны быть вычислены каждый раз, когда строка столбца исследована.
Значения индексированного виртуального столбца MVCC-зарегистрированы,
чтобы избежать ненужного перевычисления произведенных значений столбцов во
время отката или во время работы чистки. Длина данных зарегистрированных
значений ограничена ключевым пределом 767 байтов для
COMPACT
и REDUNDANT
или 3072 байтами для
DYNAMIC
и COMPRESSED
.
Добавление или удаление вторичного индекса на виртуальном столбце это оперативная работа.
До MySQL 8.0.1 ограничение внешнего ключа не может сослаться на вторичный индекс, определенный на произведенном виртуальном столбце.
Как отмечено выше, JSON
не могут быть индексированы непосредственно. Чтобы создать
индексирование, которое ссылается на такой столбец косвенно,
Вы можете определить произведенный столбец, который извлекает информацию,
которая должна быть индексирована, затем создать индексирование на
произведенном столбце, как показано в этом примере:
mysql> CREATE TABLE jemp (c JSON, -> g INT GENERATED ALWAYS AS (JSON_EXTRACT(c, '$.id')), -> INDEX i (g)); Query OK, 0 rows affected (0.28 sec) mysql> INSERT INTO jemp (c) VALUES > ('{"id":"1","name": "Fred"}'), ('{"id": "2","name": "Wilma"}'), > ('{"id":"3","name": "Barney"}'), ('{"id": "4","name": "Betty"}'); Query OK, 4 rows affected (0.04 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> SELECT JSON_UNQUOTE(JSON_EXTRACT(c, '$.name')) AS name > FROM jemp WHERE g > 2; +--------+ | name | +--------+ | Barney | | Betty | +--------+ 2 rows in set (0.00 sec) mysql> EXPLAIN SELECT JSON_UNQUOTE(JSON_EXTRACT(c, '$.name')) AS name > FROM jemp WHERE g > 2\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: jemp partitions: NULL type: range possible_keys: i key: i key_len: 5 ref: NULL rows: 2 filtered: 100.00 Extra: Using where 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Note Code: 1003 Message: /* select#1 */ select json_unquote(json_extract(`test`.`jemp`.`c`,'$.name')) AS `name` from `test`.`jemp` where (`test`.`jemp`.`g` > 2) 1 row in set (0.00 sec)
MySQL 8.0 поддерживает две формы для того, чтобы получить доступ к
значению путем JSON
:
->
эквивалентно
JSON_EXTRACT()
.
->>
эквивалентно запросу
JSON_UNQUOTE()
на результате JSON_EXTRACT()
.
Таким образом, запрос SELECT JSON_UNQUOTE(JSON_EXTRACT(c, '$.name'))
FROM jemp
может быть переписан в более короткой форме как SELECT
JSON_UNQUOTE(c->'$.name') FROM jemp
или еще более сжато как
SELECT c->>'$.name' FROM jemp
.
Когда Вы используете EXPLAIN
для SELECT
или другого запроса SQL, содержащего одно или более выражений, которые
используют ->
или ->>
,
эти выражения преобразованы в их эквивалент с JSON_EXTRACT()
и
(если нужно) JSON_UNQUOTE()
, как показано в выводе
SHOW WARNINGS
немедленно после EXPLAIN
:
mysql> EXPLAIN SELECT c->"$.name" > FROM jemp WHERE g > 2\G ORDER BY c->"$.name" *************************** 1. row *************************** id: 1 select_type: SIMPLE table: jemp partitions: NULL type: range possible_keys: i key: i key_len: 5 ref: NULL rows: 2 filtered: 100.00 Extra: Using where; Using filesort 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Note Code: 1003 Message: /* select#1 */ select json_extract(`test`.`jemp`.`c`,'$.name') AS `c->"$.name"` from `test`.`jemp` where (`test`.`jemp`.`g` > 2) order by json_extract(`test`.`jemp`.`c`,'$.name') 1 row in set (0.00 sec)
Этот метод также может использоваться, чтобы обеспечить косвенный индекс
столбцов других типов, которые не могут быть индексированы непосредственно,
например, для GEOMETRY
.
CREATE TABLESPACEЭтот запрос используется, чтобы создать табличное пространствоtablespace_name
ADD DATAFILE 'file_name
' [FILE_BLOCK_SIZE = value] [ENGINE [=]engine_name
]
InnoDB
. Оно упоминается как
общее табличное пространство.
Общее табличное пространство это совместно используемое табличное пространство, подобное системному табличному пространству. Это может содержать многократные таблицы и поддерживает все форматы строки таблицы. Общие табличные пространства могут также быть созданы в местоположении относительно или независимо от каталога данных MySQL.
После создания общего табличного пространства, Вы можете использовать
CREATE TABLE
или
tbl_name
... TABLESPACE [=] tablespace_name
ALTER TABLE
, чтобы
добавить таблицы к табличному пространству.tbl_name
TABLESPACE [=]
tablespace_name
См. раздел 16.7.9.
CREATE TABLESPACE
поддержан с InnoDB
с MySQL
5.7.6. В более ранних выпусках CREATE TABLESPACE
поддержан
только NDB
, который является механизмом
хранения MySQL Cluster.
ADD DATAFILE
: Определяет название файла с данными
табличного пространства. Файл с данными должен быть определен
CREATE TABLESPACE
, имя должно иметь расширение
.ibd
. Общее табличное пространство поддерживает только
единственный файл с данными.
Поместить файл с данными в местоположение за пределами каталога данных
MySQL (DATADIR
) можно,
включив абсолютный путь к каталогу или путь относительно каталога данных
MySQL. Если Вы не определяете путь, общее табличное пространство создается в
каталоге данных MySQL.
Чтобы избежать конфликтов с неявно создаваемыми табличными пространствами file-per-table, создание общего табличного пространства в подкаталоге в соответствии с каталогом данных MySQL не поддержано. Кроме того, создавая общее табличное пространство за пределами каталога данных MySQL, каталог должен существовать до создания табличного пространства.
,
включая (дополнительный) путь, должен быть заключен в кавычки.
Имена файла (без расширения .ibd)
и имена каталогов должны составить по крайней мере один байт в длину.
Нулевые имена файлов и каталогов не поддержаны.file_name
FILE_BLOCK_SIZE
: Определяет размер блока файла с данными
табличного пространства. Если Вы не определяете эту опцию,
FILE_BLOCK_SIZE
по умолчанию
innodb_page_size
. FILE_BLOCK_SIZE
требуется только, если Вы будете
использовать табличное пространство, чтобы сохранить сжатые таблицы
InnoDB
(ROW_FORMAT=COMPRESSED
).
В этом случае Вы должны определить FILE_BLOCK_SIZE
,
создавая табличное пространство.
Если FILE_BLOCK_SIZE
=
innodb_page_size
, табличное пространство может содержать только таблицы с несжатым
форматом строки (COMPACT
, REDUNDANT
и
DYNAMIC
). Таблицы с форматом COMPRESSED
имеют
иной физический размер страницы, чем несжатые таблицы. Поэтому сжатые таблицы
не могут сосуществовать в том же самом табличном пространстве,
где несжатые таблицы.
Для общего табличного пространства, чтобы содержать сжатые таблицы
должен быть определен FILE_BLOCK_SIZE
и оно
должно быть допустимым сжатым размером страницы относительно
innodb_page_size
. Кроме того, физический размер страницы сжатой таблицы
(KEY_BLOCK_SIZE
) должно быть равным
FILE_BLOCK_SIZE/1024
. Например, если
innodb_page_size=16K
, FILE_BLOCK_SIZE=8K
, KEY_BLOCK_SIZE
должен быть 8. См. раздел 16.7.9
.
ENGINE
: Определяет механизм хранения, который использует
табличное пространство, где engine_name
задает
название механизма хранения. В настоящее время поддержан только
механизм хранения InnoDB
. ENGINE = InnoDB
должен быть определен как часть
CREATE TABLESPACE
или InnoDB
должен быть определен как механизм хранения по умолчанию
(
default_storage_engine=InnoDB
).
чувствительный к регистру идентификатор для табличного
пространства. Это может быть заключено в кавычки. Символ наклонной черты
вправо (/) не разрешен. Имена, начинающиеся с
tablespace_name
innodb_
не разрешены или сохранены
для специального использования.
TABLESPACE
может использоваться с
CREATE TABLE
или
ALTER TABLE
, чтобы
назначать табличное разделение или подразделение к
a общему табличному
пространству, отдельному табличному пространству file-per-table или
системному табличному пространству. Все разделение должно принадлежать тому
же самому механизму хранения. Для получения дополнительной информации см.
раздел 16.7.9.CREATE TABLE ...
TABLESPACE
.
innodb_file_per_table
не должен быть включен.innodb_strict_mode
не применимо к общим табличным пространствам. Управленческие
правила табличного пространства строго проведены в жизнь, независимо от
innodb_strict_mode
. Если параметры CREATE TABLESPACE
являются неправильными или несовместимыми, работа терпит неудачу независимо
от innodb_strict_mode
. Когда таблица добавлена к общему табличному пространству
через CREATE TABLE ... TABLESPACE
или ALTER TABLE ... TABLESPACE
,
innodb_strict_mode
проигнорирован, но запрос оценен как будто
innodb_strict_mode
включен.DROP TABLESPACE
удаляет общее табличное пространство. Все
таблицы должны быть исключены из общего табличного пространства через
DROP TABLE
до удаления табличного пространства.BLOB
.InnoDB
.
Пространство не освобождено назад к операционной системе, как это
происходит для табличных пространств file-per-table.ALTER TABLE ...
DISCARD TABLESPACE
и
ALTER TABLE ...IMPORT TABLESPACE
не поддержаны для таблиц, которые принадлежат
общему табличному пространству.Этот пример демонстрирует создание общего табличного пространства и добавление трех несжатых таблиц различных форматов строки.
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=REDUNDANT; Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=COMPACT; Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE t3 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=DYNAMIC; Query OK, 0 rows affected (0.00 sec)Этот пример демонстрирует создание общего табличного пространства и добавление сжатой таблицы. Пример принимает значение по умолчанию
innodb_page_size
16K. FILE_BLOCK_SIZE
= 8192
требует, чтобы у сжатой таблицы был KEY_BLOCK_SIZE
= 8.
mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; Query OK, 0 rows affected (0.00 sec)
CREATE [DEFINER = {Этот запрос создает новый триггер. Это объект базы данных, который связан с таблицей и активируется, когда особое событие имеет место для таблицы. Триггер становится связанным с таблицей, названнойuser
| CURRENT_USER }] TRIGGERtrigger_name
trigger_time
trigger_event
ONtbl_name
FOR EACH ROW [trigger_order
]trigger_body
trigger_time
: { BEFORE | AFTER }trigger_event
: { INSERT | UPDATE | DELETE }trigger_order
: { FOLLOWS | PRECEDES }other_trigger_name
tbl_name
, которая должна быть постоянной.
Вы не можете связать триггер с таблицей
TEMPORARY
или представлением.
Более аккуратные имена существуют в пространстве имен схемы, означая, что у всех триггеров должны быть уникальные имена в пределах схемы. У триггеров в различных схемах может быть то же самое имя.
Этот раздел описывает CREATE
TRIGGER
. Подробности в
разделе 21.3.1.
CREATE TRIGGER
требует привилегию TRIGGER
для таблицы связаланной с триггером. Запрос может также потребовать
привилегию SUPER
в зависимости от значения DEFINER
.
Если двоичное журналирование включено,
CREATE TRIGGER
мог бы потребовать привилегию
SUPER
, см.
раздел 21.7.
DEFINER
определяет контекст безопасности, который
будет использоваться, проверяя привилегии доступа во
время активации, как описано позже в этом разделе.
trigger_time
время срабатывания. Это может быть
BEFORE
или AFTER
, чтобы
указать, что триггер активируется прежде или после каждой строки,
которая будет изменена.
trigger_event
указывает на вид работы, которая активирует триггер.
Допустимые значения trigger_event
:
INSERT
:
триггер активируется всякий раз, когда новая строка вставлена в таблицу,
например, через INSERT
,
LOAD DATA
и
REPLACE
.
UPDATE
:
триггер активируется всякий раз, когда строка изменена, например, через
UPDATE
.DELETE
:
триггер активируется всякий раз, когда строка удалена из таблицы,
например, через DELETE
и
REPLACE
.
DROP TABLE
и
TRUNCATE TABLE
не активируют этот триггер, потому что они не
используют DELETE
.
Удаление разделения не активирует DELETE
, а зачит и триггер.trigger_event
не представляет буквальный тип
запроса SQL, который активирует триггер, поскольку это представляет тип
табличной работы. Например, триггер
INSERT
активируется не только для
INSERT
, но и для
LOAD DATA
, потому что оба
запроса вставляют строки в таблицу.
Потенциально запутывающий пример этого INSERT INTO ... ON DUPLICATE
KEY UPDATE ...
: триггер BEFORE INSERT
активируется для каждой строки, сопровождаемой любым триггером
AFTER INSERT
или триггерами BEFORE UPDATE
и
AFTER UPDATE
в зависимости от того, было ли дублирование
ключа для строки.
Каскадные действия внешнего ключа не активируют триггеры.
Возможно определить многократные триггеры для данной таблицы, у которых
есть тот же самый случай и время действия. Например, Вы можете иметь два
триггера BEFORE UPDATE
.
По умолчанию, триггеры, у которых есть тот же самый
случай и время действия, активируются в порядке, в котором они создавались.
Чтобы затронуть порядок, определите trigger_order
,
который указывает FOLLOWS
или PRECEDES
и название существующего триггера, у которого также есть тот же самый
случай и время действия. С FOLLOWS
новый триггер активируется после существующего, с PRECEDES
перед существующим триггером.
trigger_body
запрос, чтобы выполнить, когда триггер
активируется. Чтобы выполнить много запросов, используйте
BEGIN ... END
.
Это также позволяет Вам использовать те же самые запросы, которые разрешены в
пределах сохраненных подпрограмм. См. раздел
14.6.1. Некоторые запросы не разрешены в триггерах, см.
раздел C.1.
В пределах тела триггера Вы можете обратиться к столбцам в подчиненной
таблице (таблица, связанная с триггером) при использовании псевдонимов
OLD
и NEW
. OLD.
обращается к столбцу существующей строки прежде, чем это будет
обновлено или удалено. col_name
NEW.
обращается к столбцу новой строки, которая будет вставлена или существующей
строки после того, как столбец обновлен.col_name
Триггеры не могут использовать
NEW.
или
col_name
OLD.
, чтобы обратиться к
произведенным столбцам. Для информации о произведенных столбцах см.
раздел 14.1.15.5.col_name
MySQL хранит sql_mode
когда триггер создается, и всегда выполняет триггер с этой установкой,
независимо от текущего режима SQL, когда триггер выполняется
.
DEFINER
определяет учетную запись MySQL, которая будет
использоваться, проверяя привилегии доступа во время активации. Если
user
задано, это должна быть учетная запись MySQL,
определенная как '
,
user_name
'@'
host_name
'CURRENT_USER
или
CURRENT_USER()
.
Значение по умолчанию DEFINER
: пользователь, который выполняет
CREATE TRIGGER
.
Это то же самое, как определение DEFINER = CURRENT_USER
.
Если Вы определяете DEFINER
,
эти правила определяют допустимое значение DEFINER
:
Если Вы не имеете привилегии
SUPER
,
разрешено единственное значение user
: Ваша собственная
учетная запись, определенная буквально или при использовании
CURRENT_USER
.
Вы не можете установить значение в некоторую другую учетную запись.
SUPER
, Вы можете определить любое синтаксически допустимое имя
учетной записи. Если учетная запись не существует, предупреждение произведено.
DEFINER
, это не хорошая идея для таких триггеров, которые будут
активированы, пока учетная запись фактически не существует. Иначе поведение
относительно проверки привилегии неопределено.MySQL берет во внимание DEFINER
, проверяя
привилегии следующим образом:
В ходе CREATE TRIGGER
пользователь, который делает запрос, должен иметь привилегию
TRIGGER
.
DEFINER
.
У этого пользователя должны быть эти привилегии:
TRIGGER
для подчиненной таблицы.
SELECT
для подчиненной таблицы, если ссылки на столбцы таблицы происходят, используя
OLD.col_name
или
NEW.col_name
в триггере.UPDATE
для подчиненной таблицы, если столбцы таблицы это цели
SET NEW.col_name
=
value
в триггере.См. раздел 21.6.
В пределах тела триггера
CURRENT_USER()
возвращает учетную запись для проверки
привилегии во время активации. Это DEFINER
, но
не пользователь, действия которого заставили триггер быть активированным. Для
информации о пользователе в пределах триггеров см.
раздел 7.3.12.
Если Вы используете LOCK TABLES
, чтобы заблокировать таблицу, у которой есть триггеры, таблицы,
используемые в пределах триггера, также заблокированы, как описано в
разделе 14.3.5.2.
См. раздел 21.3.1.
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = {user
| CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER }] VIEWview_name
[(column_list
)] ASselect_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
CREATE VIEW
создает новое представление или заменяет существующее представление, если
указано OR REPLACE
. Если представление не существует,
CREATE OR REPLACE VIEW
то же самое, как CREATE VIEW
.
Если представление действительно существует,
CREATE OR REPLACE VIEW
то же
самое, как ALTER VIEW
.
См. раздел C.5.
select_statement
это
SELECT
, который обеспечивает
определение представления. Выбирая из представления, выбираете в
действительности, используя именно этот
SELECT
.
select_statement
может выбрать из базовых таблиц или других представлений.
Определение представления заморожено
во время создания и не затронуто последующими изменениями определений
основных таблиц. Например, если представление определено как
SELECT *
на таблице новые столбцы, добавленные к таблице позже,
не становятся частью представления, а столбцы, исключенные из таблицы,
приведут к ошибке, выбирая из представления.
ALGORITHM
затрагивает, как MySQL обрабатывает представление.
DEFINER
и SQL SECURITY
определяют контекст
безопасности, который будет использоваться, проверяя привилегии доступа во
время запроса представления. WITH CHECK OPTION
может быть дан, чтобы ограничить вставки или обновления строк в таблицах, на
которые ссылается представление. Эти пункты описаны позже в этом разделе.
CREATE VIEW
требует
привилегии CREATE VIEW
для представления, и некоторую привилегию для каждого столбца,
выбранного SELECT
.
Для столбцов, используемых в другом месте в
SELECT
, Вы должны иметь привилегию
SELECT
. Если указано
OR REPLACE
, Вы должны также иметь привилегию
DROP
для представления.
CREATE VIEW
мог бы также потребовать привилегию
SUPER
в зависимости от значения DEFINER
, как описано
позже в этом разделе.
Когда на представление ссылаются, проверка привилегии происходит как описано позже в этом разделе.
Представление принадлежит базе данных. По умолчанию, новое представление
создается в базе данных по умолчанию. Чтобы создать представление явно в
данной базе данных, надо использовать db_name.view_name
, чтобы квалифицировать имя представления с именем базы данных:
CREATE VIEW test.v AS SELECT * FROM t;Неквалифицированное имя таблицы или представления в
SELECT
также интерпретируется
относительно базы данных значения по умолчанию. Представление может
обратиться к таблицам или представлениям в других базах данных, квалифицируя
таблицу или рассмотреть имя с соответствующим именем базы данных.
В пределах базы данных базовые таблицы и представления совместно используют то же самое пространство имен, таким образом, у базовой таблицы и представления не может быть того же самого имени.
Столбцы, полученные SELECT
,
могует быть простыми ссылками на столбцы таблицы или выражениями, которые
используют функции, постоянные величины, операторы и т.д.
У представления должны быть уникальные имена столбцов без дубликатов,
точно так же, как у базовой таблицы. По умолчанию названия столбцов,
полученных SELECT
,
используются для имен столбцов представления. Чтобы определить явные названия
столбцов представления, определите дополнительно
column_list
как список отделенных запятыми
идентификаторов. Число имен в column_list
должно быть то же самое, как число столбцов, полученных
SELECT
.
Представление может быть создано из многих видов
SELECT
.
Это может сослаться на базовые таблицы или другие представления.
Это может использовать соединения,
UNION
и подзапросы.
SELECT
даже не обязан
обращаться к таблицам вообще:
CREATE VIEW v_today (today) AS SELECT CURRENT_DATE;Следующий пример определяет представление, которое выбирает два столбца из другой таблицы, так же как выражение, вычисленное от тех столбцов:
mysql> CREATE TABLE t (qty INT, price INT); mysql> INSERT INTO t VALUES(3, 50); mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t; mysql> SELECT * FROM v; +-----+-------+-------+ | qty | price | value | +-----+-------+-------+ | 3 | 50 | 150 | +-----+-------+-------+Определение представления подвергается следующим ограничениям:
SELECT
не может
отнестись к системным или определяемым пользователем переменным.
SELECT
не может отнестись к параметрам программы или местным переменным.SELECT
не может отнестись к готовым параметрам запроса.CHECK TABLE
.TEMPORARY
,
Вы не можете создать представление TEMPORARY
.SELECT
проверены по максимальной длине столбца 64 символов (не максимальной
длине псевдонима 256 символов).ORDER BY
разрешен в определении представления, но это
проигнорировано, если Вы выбираете из представления, используя запрос, у
которого есть его собственный ORDER BY
.
Для других опций или пунктов в определении эффект не определен. Например,
если определение представления включает LIMIT
,
и Вы выбираете из представления, используя запрос, у которого есть его
собственный LIMIT
, не определено, какой предел применяется. Этот
же самый принцип относится к таким опциям, как
ALL
, DISTINCT
или SQL_SMALL_RESULT
,
INTO
, FOR UPDATE
,
LOCK IN SHARE MODE
и PROCEDURE
.
Результаты, полученные из представления, могут быть затронуты, если Вы изменяете окружающую среду обработки запроса, меняя переменные системы:
mysql> CREATE VIEW v (mycol) AS SELECT 'abc'; Query OK, 0 rows affected (0.01 sec) mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> SELECT "mycol" FROM v; +-------+ | mycol | +-------+ | mycol | +-------+ 1 row in set (0.01 sec) mysql> SET sql_mode = 'ANSI_QUOTES'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT "mycol" FROM v; +-------+ | mycol | +-------+ | abc | +-------+ 1 row in set (0.00 sec)
DEFINER
и SQL SECURITY
определяют, который пользователь MySQL
использовать, проверяя привилегии доступа на представлении, когда запрос
выполнен. Допустимые SQL SECURITY
:
DEFINER
(значение по умолчанию) и INVOKER
.
Они указывают, что необходимые привилегии должны быть проведены
пользователем, который определил или вызвал представление, соответственно.
Если user
задано для DEFINER
,
это должна быть учетная запись MySQL, определенная как
'
,
user_name
'@'host_name
'
CURRENT_USER
или
CURRENT_USER()
.
Значение по умолчанию DEFINER
это пользователь, который
выполняет CREATE VIEW
.
Это то же самое, как определение DEFINER = CURRENT_USER
.
Если DEFINER
задан, эти правила определяют
допустимое значение DEFINER
:
Если Вы не имеете привилегии
SUPER
, единственное допустимое значение
user
это Ваша собственная учетная запись, определенная
буквально или при использовании
CURRENT_USER
.
Вы не можете установить definer в некоторую другую учетную запись.
SUPER
, Вы можете определить любое синтаксически допустимое имя учетной
записи. Если учетная запись не существует, предупреждение произведено.DEFINER
, ошибка происходит, когда на представление ссылаются,
если SQL SECURITY
= DEFINER
, но definer нет.
См. раздел 21.6.
В пределах определения представления
CURRENT_USER
возвращает значение по умолчанию DEFINER
.
Для представлений, определенных с SQL SECURITY INVOKER
,
CURRENT_USER
возвращает учетку вызывающего представление. См.
раздел 7.3.12.
В пределах сохраненной подпрограммы, которая определена с SQL
SECURITY DEFINER
,
CURRENT_USER
возвращает DEFINER
подпрограммы.
Это также затрагивает представление, определенное в пределах такой
подпрограммы, если определение представления содержит DEFINER
CURRENT_USER
.
MySQL проверяет привилегии представления:
Во время определения представления создателю представления нужны
были привилегии, чтобы использовать высокоуровневые объекты, к которым
получает доступ представление. Например, если определение представления
ссылается на столбцы таблицы, у создателя должна быть некоторая привилегия
для каждого столбца в избранном списке определения и привилегия
SELECT
для каждого столбца, используемого в другом месте в определении. Если
определение относится к сохраненной функции, только привилегии нужные для
вызова функцию, могут быть проверены. Привилегии, требуемые в функции,
могут быть проверены только когда она выполняется: для различных вызовов
могли быть взяты различные пути выполнения в пределах функции.
SELECT
,
INSERT
и т.д.).DEFINER
представления для создателя или обращающегося,
смотря по значению SQL SECURITY
(DEFINER
или INVOKER
).SQL SECURITY
функции. Если характеристика безопасности
DEFINER
, функция работает с привилегиями учетки
DEFINER
. Если характеристика безопасности
INVOKER
, функция работает с привилегиями, определенными
SQL SECURITY
представления.Пример: представление могло бы зависеть от сохраненной функции, а функция
могла бы вызвать другие сохраненные подпрограммы. Например, следующее
представление вызывает сохраненную функцию f()
:
CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);Предположите, что
f()
содержит запрос:
IF name IS NULL then CALL p1(); ELSE CALL p2(); END IF;Привилегии, требуемые для того, чтобы выполнить запрос в пределах
f()
, будут проверены, когда выполняется f()
.
Это могло бы означать, что привилегии необходимы для p1()
или
p2()
, в зависимости от пути выполнения в пределах
f()
. Те привилегии должны быть проверены во время выполнения, и
пользователь, который должен обладать привилегиями, определен SQL
SECURITY
представления v
и функции f()
.
DEFINER
и SQL SECURITY
для представлений это
расширения к стандартному SQL. В стандартном SQL представления обработаны,
используя правила для SQL SECURITY DEFINER
.
Стандарт говорит, что definer представления, который является тем же самым,
как владельцем схемы представления, получает применимые права на
представлении (например, SELECT
) и может предоставить их. У MySQL нет никакого понятия
владельца схемы, таким образом, MySQL добавляет
пункт, чтобы идентифицировать definer. DEFINER
расширение, где намерение состоит в том, чтобы иметь то, что имеет стандарт,
то есть, постоянный отчет о том, кто определил представление.
Это то, почему значение по умолчанию DEFINER
учетная запись создателя представления.
ALGORITHM
тоже расширение MySQL.
Это затрагивает, как MySQL обрабатывает представление.
ALGORITHM
берет три значения:
MERGE
, TEMPTABLE
или UNDEFINED
.
См. разделы 21.5.2 и
9.2.1.18.3.
Некоторые представления обновляемые. Таким образом, Вы можете использовать
их в запросах UPDATE
,
DELETE
или
INSERT
, чтобы
обновить содержание основной таблицы. Для представления, чтобы быть
обновляемым, должны быть непосредственные отношения между строками в
представлении и строками в основной таблице. Есть также определенные другие
конструкции, которые делают представление необновляемым.
Произведенный столбец в представлении считают обновляемым, потому что
возможно назначить на него значение. Однако, если такой столбец обновлен
явно, единственное разрешенное значение DEFAULT
. См.
раздел 14.1.15.5.
WITH CHECK OPTION
может быть дан для обновляемого
представления, чтобы предотвратить вставки или обновления к строкам кроме
тех, для которых WHERE
в
select_statement
истина.
В WITH CHECK OPTION
для обновляемого представления
ключевые слова LOCAL
и CASCADED
определяют контекст проверки, когда представление определено с точки зрения
другого представления. LOCAL
ограничивает
CHECK OPTION
только к определяемому представлению.
CASCADED
вызывает проверку на то, чтобы лежать в основе
представлений, которые будут оценены также. Когда никакое ключевое слово не
дано, значение по умолчанию CASCADED
.
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
DROP DATABASE
удаляет
все таблицы в базе данных и базу данных. Будьте
очень осторожны с этим запросом! Чтобы использовать
DROP DATABASE
, нужна
привилегия DROP
на базе данных. DROP SCHEMA
синоним для DROP DATABASE
.
Когда база данных удалена, пользовательские привилегии на базе данных не удалены автоматически. см. раздел 14.7.1.6.
IF EXISTS
используется, чтобы препятствовать ошибке,
если база данных не существует.
Если база данных по умолчанию удалена, она сброшена
(DATABASE()
вернет NULL
).
Если Вы используете DROP DATABASE
на символически соединенной базе данных, удалены ссылка и
оригинальная база данных.
DROP DATABASE
возвращает число таблиц, которые были удалены.
DROP DATABASE
удаляет из данного каталога базы данных те файлы и каталоги, которые сам
MySQL может создать во время нормального функционирования. Это включает все
файлы с расширениями, показанными в следующей таблице.
.BAK | .DAT |
.HSH | .MRG |
.MYD | .MYI |
.cfg | .db |
.ibd | .ndb |
Если другие файлы или каталоги остаются в каталоге базы данных после того,
как MySQL удаляет только перечисленных, каталог базы данных не может быть
удален. В этом случае, Вы должны удалить любые остающиеся файлы или каталоги
вручную и снова использовать DROP
DATABASE
.
Удаление базы данных не удаляет таблицы TEMPORARY
, которые
были составлены в той базе данных. Таблицы TEMPORARY
автоматически удалены, когда сеанс, который создал их, заканчивается.
Вы можете также удалить базы данных с помощью mysqladmin . см. раздел 5.5.2.
DROP EVENT [IF EXISTS] event_name
Этот запрос удаляет событие event_name
.
Оно немедленно прекращает быть активным и удалено полностью из сервера.
Если событие не существует, будет ошибка ERROR 1517
(HY000): Unknown event 'event_name
'.
Вы можете переопределить это и заставить запрос вместо этого производить
предупреждение для несуществующих событий, используя IF EXISTS
.
Это запрос требует привилегии
EVENT
для схемы, к которой принадлежит удаляемое событие.
DROP FUNCTION
используется, чтобы удалить сохраненные функции и определяемые
пользователем функции (UDF):
См. раздел 14.1.23.
DROP INDEXindex_name
ONtbl_name
[algorithm_option
|lock_option
] ...algorithm_option
: ALGORITHM [=] {DEFAULT|INPLACE|COPY}lock_option
: LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
DROP INDEX
удаляет индекс index_name
из таблицы
tbl_name
. Отображен на
ALTER TABLE
, чтобы удалить
индекс. См. раздел 14.1.7.
Чтобы удалить первичный ключ, имя индекса всегда
PRIMARY
, которое должно быть определено как заключенный в
кавычки идентификатор, потому что PRIMARY
спецслово:
DROP INDEX `PRIMARY` ON t;
ALGORITHM
и LOCK
могут быть указаны.
Они влияют на табличный метод копирования и уровень параллелизма для чтения и
записи таблицы в то время, как индекс изменяется. У них есть то же самое
значение, что ALTER TABLE
.
См. раздел 14.1.7.
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
Этот запрос используется, чтобы удалить хранимую процедуру или функцию. Таким
образом, указанная подпрограмма удалена из сервера. Вы должны иметь
привилегию ALTER ROUTINE
для подпрограммы. Если включена automatic_sp_privileges
, эта привилегия и EXECUTE
предоставлены автоматически создателю, когда подпрограмма создана
и удалены у создателя, когда подпрограмма удалена. См.
раздел 21.2.2.
IF EXISTS
расширение MySQL. Это препятствует ошибке, если
процедура или функция не существуют. Предупреждение произведено, которое
может быть рассмотрено с SHOW WARNINGS
.
DROP FUNCTION
также используется, чтобы удалить определяемые пользователем функции (см.
раздел 14.7.3.2).
DROP SERVER [ IF EXISTS ] server_name
Удаляет определение сервера для названного сервера
server_name
. The
Соответствующая строка в mysql.servers
удалена. Это запрос
требует привилегию SUPER
.
Удаление сервера для таблицы не затрагивает таблицы
FEDERATED
, которые использовали эту информацию о соединении,
когда они создавались. См. раздел 14.1.14
.
DROP SERVER
не закрывает транзакцию.
DROP SERVER
не записан в двоичный журнал, независимо от
формата журналирования, который используется.
DROP [TEMPORARY] TABLE [IF EXISTS]tbl_name
[,tbl_name
] ... [RESTRICT | CASCADE]
DROP TABLE
удаляет одну или более таблиц. Вы должны иметь привилегию
DROP
для каждой таблицы. Все табличные данные и табличное определение
удалены, так что будьте осторожны
! Если какая-либо из таблиц, названных в списке параметров, не
существует, MySQL возвращает ошибку, указывая по имени, какие несуществующие
таблицы не удалось удалить, но удаляет все таблицы в списке,
которые действительно существуют.
Когда таблица удалена, пользовательские привилегии на таблице не удалены автоматически. См. раздел 14.7.1.6.
Для разделенной таблицы DROP TABLE
удаляет табличное определение, все его разделение и все данные,
которые хранились в разделении. Это также удаляет определения разделения,
связанные с удаленной таблицей.
IF EXISTS
препятствует ошибке
для таблиц, которые не существуют. NOTE
произведен для каждой несуществующей таблицы, используя
IF EXISTS
. См. раздел 14.7.5.40
.
RESTRICT
и CASCADE
разрешены, чтобы сделать
проще портирование. В MySQL 8.0 ничего они не делают.
DROP TABLE
автоматически
закрывает текущую активную транзакцию, если Вы
не используете TEMPORARY
.
TEMPORARY
имеет следующие эффекты:
Запрос удаляется только таблицы TEMPORARY
.
TEMPORARY
видима только сеансу, который создал ее, таким образом, никакая
проверка не нужна).Применение TEMPORARY
хороший способ гарантировать, что Вы
случайно не удаляете не-TEMPORARY
таблицу.
DROP TABLESPACEЭтот запрос используется, чтобы удалить общее табличное пространствоtablespace_name
[ENGINE [=]engine_name
]
InnoDB
, которое создавалось, используя
CREATE TABLESPACE
(см.
раздел 14.1.16).
Все таблицы должны быть исключены из табличного пространства до
DROP TABLESPACE
. Если табличное пространство не пусто,
DROP TABLESPACE
возвращает ошибку.
чувствительный к регистру идентификатор в MySQL.tablespace_name
ENGINE
: Определяет механизм хранения, который использует
табличное пространство, где engine_name
название механизма хранения. В настоящее время только InnoDB
поддержан. Вы не должны определить ENGINE = InnoDB
, если
InnoDB
определен как механизм хранения по умолчанию
(
default_storage_engine=InnoDB
).
DROP TABLESPACE
поддержан с InnoDB
с MySQL
5.7.6. В более ранних выпусках DROP TABLESPACE
поддерживает
NDB
, MySQL Cluster.
DROP TABLESPACE
поддерживает
NDB
в MySQL 5.7 когда MySQL Cluster
переходит кодовой базы MySQL 5.7. Последняя версия MySQL Cluster
основана на MySQL 5.6.
Табличное пространство не удалено автоматически, когда последняя
таблица в табличном пространстве удалена. Табличное пространство должно быть
удалено явно, используя DROP TABLESPACE
.tablespace_name
DROP DATABASE
может удалить таблицы, которые принадлежат общему табличному пространству, но
она не может удалить табличное пространство, даже если удаляет все таблицы,
которые принадлежат табличному пространству. Табличное пространство должно
быть удалено явно, используя DROP TABLESPACE
tablespace_name
.InnoDB
.Этот пример демонстрирует, как удалить общее табличное пространство
InnoDB
. Общее табличное пространство ts1
создается с единственной таблицей. Прежде чем удалить табличное пространство,
таблица должна быть удалена.
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts10 Engine=InnoDB; Query OK, 0 rows affected (0.02 sec) mysql> DROP TABLE t1; Query OK, 0 rows affected (0.01 sec) mysql> DROP TABLESPACE ts1; Query OK, 0 rows affected (0.01 sec)
DROP TRIGGER [IF EXISTS] [Этот запрос удаляет триггер. Имя хемы (базы данных) является дополнительным. Если схема опущена, триггер исключен из схемы по умолчанию.schema_name
.]trigger_name
DROP TRIGGER
требует
привилегию TRIGGER
для таблицы с триггером.
IF EXISTS
препятствовует ошибке
для триггера, который не существует. См.
раздел 14.7.5.40.
Триггеры для таблицы также удалены, если Вы удаляете таблицу.
DROP VIEW [IF EXISTS]view_name
[,view_name
] ... [RESTRICT | CASCADE]
DROP VIEW
удаляет одно или более представлений. Вы должны иметь
привилегию DROP
для каждого представления. Если какое-либо из представлений, названных в
списке параметров, не существует, MySQL возвращает ошибку, указывая по имени,
какие несуществующие представления это было неспособно удалить, но удаляет
все представления в списке, которые действительно существуют.
IF EXISTS
препятствует ошибке
для представлений, которые не существуют. См.
раздел 14.7.5.40.
RESTRICT
и CASCADE
,
если дано, разобраны и проигнорированы.
RENAME TABLEЭто запрос переименовывает одну или более таблиц. Работа сделана атомарно, что означает, что никакой другой сеанс не может получить доступ ни к одной из таблиц в то время, как переименование работает.tbl_name
TOnew_tbl_name
[,tbl_name2
TOnew_tbl_name2
] ...
Например, таблица old_table
может быть
переименована new_table
:
RENAME TABLE old_table TO new_table;Этот запрос эквивалентен
ALTER TABLE
:
ALTER TABLE old_table RENAME new_table;Если запрос переименовывает больше, чем одну таблицу, операции сделаны слева направо. Если Вы хотите поменять два имени таблиц, Вы можете сделать так (
tmp_table
пока нет):
RENAME TABLE old_table TO tmp_table, new_table TO old_table, tmp_table TO new_table;MySQL проверяет целевое имя таблицы прежде, чем проверить, существует ли исходная таблица. Например, если
new_table
уже есть, а
old_table
пока нет, следующий запрос терпит неудачу,
как показано здесь:
mysql> SHOW TABLES; +----------------+ | Tables_in_mydb | +----------------+ | table_a | +----------------+ 1 row in set (0.00 sec) mysql> RENAME TABLE table_b TO table_a; ERROR 1050 (42S01): Table 'table_a' already existsЕсли две базы данных находятся на той же самой файловой системе, Вы можете использовать
RENAME TABLE
,
чтобы перемещать таблицу от одной базы данных в другую:
RENAME TABLEВы можете использовать этот метод, чтобы переместить все таблицы от одной базы данных в другую, в действительности переименовывая базу данных. У MySQL нет никакого спецзапроса, чтобы выполнить эту задачу.current_db.tbl_name
TOother_db.tbl_name;
Если есть какие-либо триггеры, связанные с таблицей, которая перемещена в иную базу данных, запрос терпит неудачу с ошибкой Trigger in wrong schema.
Внешние ключи, которые указывают на переименованную таблицу, автоматически не обновлены. В таких случаях Вы должны удалить и обновить внешние ключи, чтобы функционировать должным образом.
RENAME TABLE
также работает для представлений, пока Вы не
пытаетесь переименовать представление в иную базу данных.
Любые привилегии, предоставленные определенно для переименованной таблицы или представления, не мигрируют к новому имени. Они должны быть изменены вручную.
Когда Вы выполняете RENAME TABLE
, у Вас не может быть никаких
заблокированных таблиц или активных транзакций. Вы должны также иметь
привилегии ALTER
и
DROP
на оригинальной таблице, CREATE
и INSERT
на новой таблице.
Если MySQL сталкивается с проблемами, когда переименовывает много таблиц, он делает всех действий, чтобы возвратить все к исходному состоянию.
Вы не можете использовать RENAME TABLE
, чтобы
переименовать таблицу TEMPORARY
. Однако, Вы можете использовать
ALTER TABLE
.
Подобно RENAME TABLE
, ALTER TABLE ... RENAME
может также использоваться, чтобы переместить таблицу в иную базу данных.
Независимо от запроса, используемого, чтобы выполнить переименовывание, если
работа переместила бы таблицу в базу данных, расположенную в иной файловой
системе, успех результата определен платформой и зависит от основных
требований операционной системы, используемых, чтобы
переместить табличные файлы.
TRUNCATE [TABLE] tbl_name
TRUNCATE TABLE
освобождает таблицу полностью. Это требует привилегии
DROP
. Логически
TRUNCATE TABLE
это
DELETE
, который удаляет все строки,
или последовательность DROP TABLE
и CREATE TABLE
.
В MySQL 8.0 TRUNCATE TABLE
отображен на DROP TABLE
и
CREATE TABLE
.
В результате этого изменения TRUNCATE
TABLE
является временно не атомным. Сьой сервера во время
TRUNCATE TABLE
может привести к удаленной таблице и ограничениям внешнего ключа в
системных таблицах InnoDB
SYS_FOREIGN
и
SYS_FOREIGN_COLS
.
Чтобы достигнуть высокой производительности,
TRUNCATE TABLE
обходит метод DML удаления данных. Таким образом, это не может быть откачено,
это не вызывает триггеры ON DELETE
и это не может быть выполнено
для таблиц InnoDB
с родительско-дочерними
отношениями внешнего ключа.
Хотя TRUNCATE TABLE
подобно DELETE
,
это классифицировано как запрос DDL, а не запрос DML. Это отличается от
DELETE
:
Усеченные операции удаляют и обновляют таблицу намного быстрее, чем удаление строк, особенно для больших таблиц.
TRUNCATE TABLE
терпит неудачу для таблицы InnoDB
или
NDB
,
если есть ограничения FOREIGN KEY
от других таблиц. Ограничения
внешнего ключа между столбцами той же самой таблицы разрешены.TRUNCATE TABLE
, даже если файлы с данными или индексные файлы стали поврежденными.AUTO_INCREMENT
сброшено к его стартовому
значению. Это истина даже для MyISAM
и InnoDB
,
которые обычно не используют значения последовательности снова.TRUNCATE TABLE
сохраняет разделение, то есть, файлы с данными и индексные файлы удалены и
обновлены в то время, как определения разделения не затронуты.TRUNCATE TABLE
не вызывает триггеры ON DELETE
triggers.TRUNCATE TABLE
закрывает все обработчики для таблицы, которые были открыты с
HANDLER OPEN
.
TRUNCATE TABLE
пишется в репликацию как DROP TABLE
и CREATE TABLE
, то есть
DDL вместо DML. Это вследствие того, что, используя
InnoDB
и другие транзакционные
механизмы хранения, где операционный уровень изоляции не разрешает основанное
на запросе журналирование (
READ COMMITTED
или
READ
UNCOMMITTED
), запрос не был зарегистрирован и копировался,
используя режим STATEMENT
или MIXED
(Bug #36763).
В MySQL 5.7 и ранее на системе с большим буферным пулом и включенным
innodb_adaptive_hash_index
TRUNCATE TABLE
может вызвать временное падение системной работы из-за просмотра LRU, который
произошел, когда удаление индекса адаптивного хеша таблицы записано
(Bug #68184). Переотображение TRUNCATE
TABLE
на DROP TABLE
и CREATE TABLE
в MySQL 8.0
избегает проблематичного просмотра LRU.
TRUNCATE TABLE
может использоваться с Performance Schema, но эффект состоит в том, чтобы
сбросить сводные столбцы к 0 или NULL
, а не удалению строк. См.
раздел 23.9.15.
CALLsp_name
([parameter
[,...]]) CALLsp_name
[()]
CALL
вызывает хранимую процедуру, которая была определена ранее с
CREATE PROCEDURE
.
Хранимые процедуры, которые не берут параметров, могут быть вызваны без
круглых скобок. Таким образом,
CALL p()
и CALL p
аналогичны.
CALL
может передать назад
значения, используя параметры, которые объявлены как
OUT
или INOUT
.
Когда процедура возвращается, программа клиента может также получить число
строк, затронутых для заключительного запроса, выполненного в пределах
подпрограммы: на уровне SQL вызовите
ROW_COUNT()
, из
C API вызовите
mysql_affected_rows()
.
Чтобы возвращать значение из процедуры, используя параметр
OUT
или INOUT
, передайте параметр посредством
пользовательской переменной, а затем проверьте значение переменной после
возвращений процедуры. Если Вы вызываете процедуру изнутри другой хранимой
процедуры или функции, Вы можете также передать обычный параметр или местную
переменную как параметр IN
или INOUT
.
Для INOUT
инициализируйте его значение прежде, чем передать к
процедуре. Следующая процедура имеет параметры OUT
,
которые процедура устанавливает к текущей версии сервера, и значение
INOUT
, которое процедура постепенно увеличивает:
CREATE PROCEDURE p (OUT ver_param VARCHAR(25), INOUT incr_param INT) BEGIN # Set value of OUT parameter SELECT VERSION() INTO ver_param; # Increment value of INOUT parameter SET incr_param = incr_param + 1; END;Прежде, чем вызвать процедуру, инициализируйте переменную, которую передадут как
INOUT
. После запроса процедуры значения этих двух переменных
будут установлены или изменены:
mysql> SET @increment = 10; mysql> CALL p(@version, @increment); mysql> SELECT @version, @increment; +--------------+------------+ | @version | @increment | +--------------+------------+ | 5.5.3-m3-log | 11 | +--------------+------------+В готовом запросе
CALL
,
используемом с PREPARE
и
EXECUTE
,
заполнители могут использоваться для параметров
IN
, OUT
и INOUT
.
Эти типы параметров могут использоваться следующим образом:
mysql> SET @increment = 10; mysql> PREPARE s FROM 'CALL p(?, ?)'; mysql> EXECUTE s USING @version, @increment; mysql> SELECT @version, @increment; +--------------+------------+ | @version | @increment | +--------------+------------+ | 5.5.3-m3-log | 11 | +--------------+------------+Чтобы написать программу на C, которая использует
CALL
, чтобы выполнить хранимые
процедуры, которые производят наборы результатов, флаг
CLIENT_MULTI_RESULTS
должен быть включен. Это потому, что
каждый вызов CALL
возвращает
результат, чтобы указать на состояние запроса, в дополнение к любым наборам
результатов, которые могли бы быть возвращены запросами, выполненными в
пределах процедуры. CLIENT_MULTI_RESULTS
должен также быть включен, если CALL
используется, чтобы выполнить любую хранимую процедуру, которая содержит
готовые запросы. Не может быть определено, когда такая процедура загружена,
произведут ли те запросы наборы результатов, таким образом, будет необходимо
предположить, что они будут.
CLIENT_MULTI_RESULTS
может быть включен, когда Вы вызываете
mysql_real_connect()
, явно, передавая CLIENT_MULTI_RESULTS
непосредственно, или неявно, передавая CLIENT_MULTI_STATEMENTS
(который также включает CLIENT_MULTI_RESULTS
). В MySQL 8.0
CLIENT_MULTI_RESULTS
включен по умолчанию.
Чтобы обработать результат CALL
,
используя mysql_query()
или mysql_real_query()
, используйте цикл, который вызывает
mysql_next_result()
,
чтобы определить, есть ли больше результатов. Для примера см.
раздел 25.8.17.
В MySQL 8.0 программы на C могут использовать интерфейс готового запроса,
чтобы выполнить CALL
и обратиться
к параметрам OUT
и INOUT
.
Это сделано, обрабатывая результат CALL
, используя цикл, который вызывает
mysql_stmt_next_result()
, чтобы определить, есть ли больше результатов. Для примера см.
раздел 25.8.20.
Языки, которые обеспечивают интерфейс MySQL, могут использовать
подготовленный CALL
, чтобы
непосредственно получить параметры процедуры
OUT
и INOUT
.
В MySQL 8.0 метаданные, измененные объектами, упомянутыми сохраненными программами, обнаружены и вызывают автоматический перепарсинг затронутых запросов, когда программа затем выполнена. Для получения дополнительной информации см. раздел 9.10.4.
DELETE
это запрос DML, который удаляет строки из таблицы.
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[PARTITION (partition_name
,...)] [WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
DELETE
удаляет строки из tbl_name
и возвращает число удаленных строк. Чтобы проверить число удаленных строк,
вызовите ROW_COUNT()
,
см. раздел 13.14.
Условия в дополнительном WHERE
идентифицирует, которые строки
удалить. Без WHERE
все строки удалены.
where_condition
выражение, которое оценивается к
истине для каждой строки, которая будет удалена. Это определено как описано в
разделе 14.2.9.
Если указан ORDER BY
, строки удалены в порядке, который
определен. LIMIT
устанавливает границу числа строк, которые
могут быть удалены. Эти пункты относятся к единственной таблице, но не к
удалению из нескольких таблиц.
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]Или:tbl_name
[.*] [,tbl_name
[.*]] ... FROMtable_references
[WHEREwhere_condition
]
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[.*] [,tbl_name
[.*]] ... USINGtable_references
[WHEREwhere_condition
]
Вы нуждаетесь в привилегии
DELETE
на таблице, чтобы удалить строки из нее. Вы нуждаетесь
только в привилегии SELECT
для любых столбцов, которые только считаны, такие
как названные в WHERE
.
Когда Вы не должны знать число удаленных строк,
TRUNCATE TABLE
более быстрый способ освободить таблицу, чем
DELETE
без WHERE
.
В отличие от этого, TRUNCATE TABLE
не может использоваться в пределах транзакции, или если у Вас
есть блокировка на таблице. См. разделы
14.1.30 и
14.3.5.
Скорость операции удаления может также быть затронута факторами, обсужденными в разделе 9.2.2.3.
Чтобы гарантировать, что данный запрос
DELETE
не занимает слишком много времени, параметр
LIMIT
для row_count
DELETE
определяет максимальное количество строк, которые будут удалены. Если число
строк, чтобы удалить, больше предела, повторите DELETE
до числа затронутых строк меньше LIMIT
.
Вы не можете удалить из таблицы и выбрать из той же самой таблицы в одном подзапросе.
DELETE
поддерживает явный выбор разделения, используя опцию
PARTITION
, которая берет список разделенных запятой значений
названий из одного или более разделов или подразделов (или обоих), из
которых можно выбрать строки, которые будут исключены. Проигнорировано
разделение, не включенное в список. Учитывая разделенную таблицу
t
с разделом p0
, выполнение DELETE
FROM t PARTITION (p0)
имеет тот же самый эффект на таблицу как
выполнение ALTER
TABLE t TRUNCATE PARTITION (p0)
,
в обоих случаях все строки в разделе p0
удалены.
PARTITION
может использоваться наряду с WHERE
,
тогда условие проверено только на строках в перечисленном разделе. Например,
DELETE FROM t PARTITION (p0) WHERE c < 5
удаляет строки только из раздела p0
для которых верно условие
c < 5
, строки в любом другом разделе не проверены и таким
образом не затронуты DELETE
.
Опция PARTITION
может также использоваться в многотабличном
DELETE
. Вы можете использовать до одной такой опции на таблицу,
названную в опции FROM
.
См. раздел 20.5.
Если Вы удаляете строку, содержащую максимальное значение для
AUTO_INCREMENT
, значение не использовано снова для
MyISAM
или InnoDB
. Если Вы удаляете все строки в
таблице с DELETE FROM
(без
tbl_name
WHERE
) в режиме
autocommit
, последовательность запускается для всех механизмов
хранения, кроме InnoDB
и MyISAM
.
Есть некоторые исключения к этому поведению для InnoDB
, см.
раздел 16.8.5.
Для MyISAM
Вы можете определить второй столбец
AUTO_INCREMENT
в многостолбцовом ключе. В этом случае повторное
использование значений, удаленных из вершины последовательности, происходит
даже для MyISAM
. См.
раздел 4.6.9.
DELETE
поддерживает следующие модификаторы:
Если Вы определяете LOW_PRIORITY
, сервер задерживает
выполнение DELETE
пока никакие другие клиенты не читают из таблицы. Это затрагивает только
механизмы хранения, которые используют только блокировку на уровне таблицы
(такие, как MyISAM
, MEMORY
и MERGE
).
MyISAM
таблицы, если Вы используете параметр
QUICK
, механизм хранения не сливает листья индекса во время
удаления, что может убыстрить некоторые виды удаления.IGNORE
заставляет MySQL игнорировать ошибки во время
процесса удаления строк. Ошибки, с которыми сталкиваются во время этапа
парсинга, обработаны в обычной манере. Ошибки, которые проигнорированы из-за
использования IGNORE
, возвращены как предупреждения.
Если DELETE
включает
ORDER BY
, строки удалены в порядке, определенном пунктом. Это
полезно прежде всего в соединении с LIMIT
.
Например, следующий запрос находит строки, соответствующие
WHERE
, сортирует их по timestamp_column
и удаляет первую (самый старую):
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
ORDER BY
также помогает удалить строки в порядке, требуемом,
чтобюы избегать нарушений ссылочной целостности.
Если Вы удаляете много строк из большой таблицы, Вы можете превысить
табличный размер блокировки для InnoDB
.
Чтобы избежать этой проблемы или просто минимизировать время, когда таблица
остается заблокированной, следующая стратегия (которая не использует
DELETE
вообще), могла
бы быть полезным:
Выберите строки, которые не будут удалены в пустую таблицу, у которой есть та же самая структура, как у оригинальной:
INSERT INTO t_copy SELECT * FROM t WHERE ... ;
RENAME TABLE
,
чтобы атомарно переместить оригинальную таблицу из пути и переименовать
копию к настоящему имени:
RENAME TABLE t TO t_old, t_copy TO t;
DROP TABLE t_old;
Никакие другие сеансы не могут получить доступ к вовлеченным таблицам в то
время, как работает RENAME TABLE
, таким образом, переименование не подвергается проблемам параллелизма.
См. раздел 14.1.29.
В MyISAM
удаленные строки поддержаны в связанном списке и
последующие INSERT
повторно используют старые позиции строки. Чтобы восстановить неиспользуемое
место и уменьшить размеры файла, используйте
OPTIMIZE TABLE
или
myisamchk,
чтобы реорганизовать таблицы. OPTIMIZE
TABLE
легче использовать, но
myisamchk быстрее. См. разделы
14.7.2.4 и
5.6.4.
QUICK
затрагивает, слиты ли листья индекса для операции
удаления. DELETE QUICK
является самым полезным для приложений,
где индексные значения для удаленных строк заменены подобными индексными
значениями от строк, вставленных позже. В этом случае места, оставленные
удаленными значениями, снова использованы.
DELETE QUICK
не полезно, когда удаленные значения приводят к
слишком сильному опустошению индексных блоков, охватывающих диапазон
значений, для которых новые вставки происходят снова. В этом случае
использование QUICK
может привести к потраченному впустую
пространству в индексировании, которое остается неисправленным. Вот
пример такого сценария:
Составьте таблицу, которая содержит индексированный
столбец AUTO_INCREMENT
.
DELETE QUICK
.В этом сценарии блоки индекса, связанные с удаленными
значениями, становятся сильно пустыми, но не слиты с другим блоками индекса
из-за использования QUICK
. Они остаются такими,
когда новые вставки происходят, потому что новые строки не имеют индексных
значений в удаленном диапазоне. Кроме того, они остаются пустыми
даже если Вы позже используете
DELETE
без QUICK
,
если некоторые из удаленных индексных значений лежат в
блоках в пределах или смежных с незаполненными блоками.
Чтобы исправить неиспользованное индексное пространство при этих
обстоятельствах, используют
OPTIMIZE TABLE
.
Если Вы собираетесь удалить много строк из таблицы, могло бы быть быстрее,
использовать DELETE QUICK
сопровождаемый
OPTIMIZE TABLE
.
Это восстанавливает индексирование вместо того, чтобы делать много
операций слияния индексных блоков.
Вы можете определить много таблиц в
DELETE
, чтобы удалить строки из
одной или более таблиц в зависимости от условия в WHERE
.
Вы не можете использовать ORDER BY
или LIMIT
в
многотабличном DELETE
. table_references
перечисляет таблицы, вовлеченные в соединение, как описано в
разделе 14.2.9.2.
Для первого многотабличного синтаксиса соответствуют только строки от
таблиц, перечисленных перед FROM
. Для второго
соответствуют только строки от таблиц, перечисленных в
FROM
(до USING
). Эффект состоит в том, что Вы
можете удалить строки из многих таблиц в то же самое время и иметь
дополнительные таблицы, которые используются только для того, чтобы искать:
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;Или:
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;Эти запросы используют все три таблицы, ища строки, чтобы удалить, но удаляют соответствующие строки только из таблиц
t1
и t2
.
Предыдущее использование в качестве примера INNER JOIN
, но
мультитабличный DELETE
может
использовать другие типы соединения, разрешенные в
SELECT
, например,
LEFT JOIN
. Например, чтобы удалить строки, которые существуют в
t1
, у которых нет никакого соответствия в
t2
, используйте LEFT JOIN
:
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;Синтаксис допускает
.*
после каждого
tbl_name
для совместимости с
Access.
Если Вы используете многотабличный DELETE
с таблицами InnoDB
, для которых есть ограничения
внешнего ключа, оптимизатор MySQL мог бы обработать таблицы в порядке,
который отличается от их родительских/дочерних отношений. В этом случае
запрос терпит неудачу и откатывается. Вместо этого Вы должны удалить из
единственной таблицы и использовать ON DELETE
, который
обеспечивает InnoDB
, чтобы заставить другие таблицы
быть измененными соответственно.
Если Вы объявляете псевдоним для таблицы, Вы должны использовать псевдоним, обращаясь к таблице:
DELETE t1 FROM test AS t1, test2 WHERE ...
Табличные псевдонимы в многотабличном
DELETE
должны быть объявлены только в части table_references
.
В другом месте ссылки псевдонима разрешены, но не декларации псевдонима.
Правильно:
DELETE a1, a2 FROM t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id=a2.id; DELETE FROM a1, a2 USING t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id=a2.id;Неправильно:
DELETE t1 AS a1, t2 AS a2 FROM t1 INNER JOIN t2 WHERE a1.id=a2.id; DELETE FROM t1 AS a1, t2 AS a2 USING t1 INNER JOIN t2 WHERE a1.id=a2.id;
DOexpr
[,expr
] ...
DO
выполняет выражения, но не
возвращает результатов. В большинстве отношений
DO
сокращение для SELECT
expr
, ...
, но имеет преимущество, что это
немного быстрее, когда Вы не заботитесь о результате.
DO
полезно прежде всего с функциями,
у которых есть побочные эффекты, например, с
RELEASE_LOCK()
.
Пример: Этот SELECT
тормозит запросы, но также и производит набор результатов:
mysql> SELECT SLEEP(5); +----------+ | SLEEP(5) | +----------+ | 0 | +----------+ 1 row in set (5.02 sec)
DO
, с другой стороны, делает такую же
паузу, не производя набор результатов:
mysql> DO SLEEP(5); Query OK, 0 rows affected (4.99 sec)Это могло быть полезно, например в сохраненной функции или триггере которые запрещают запросы, которые производят наборы результатов.
DO
только выполняет выражения. Это не может использоваться во всех случаях,
где SELECT
. Например, DO id FROM t1
недопустимо, потому что это ссылается на таблицу.
HANDLERtbl_name
OPEN [ [AS]alias
] HANDLERtbl_name
READindex_name
{ = | <= | >= | < | > } (value1
,value2
,...) [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
READindex_name
{ FIRST | NEXT | PREV | LAST } [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
READ { FIRST | NEXT } [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
CLOSE
HANDLER
обеспечивает прямой доступ к табличным интерфейсам
механизма хранения. Это доступно для
InnoDB
и MyISAM
.
HANDLER ... OPEN
открывает таблицу, делая это доступным
последующму использованию HANDLER ... READ
.
Этот табличный объект не использован совместно другими сеансами и не закрыт
до HANDLER ... CLOSE
или конца сеанса.
Если Вы открываете таблицу, используя псевдоним, дальнейшие ссылки на
открытую таблицу с другим HANDLER
должны использовать псевдоним,
а не имя таблицы. Если Вы не используете псевдоним, но открываете таблицу,
используя имя таблицы, квалифицированное именем базы данных, дальнейшие
ссылки должны использовать неквалифицированное имя таблицы. Например, для
таблицы, открытой, используя mydb.mytable
,
дальнейшие ссылки должны использовать mytable
.
Первый синтаксис HANDLER ... READ
приносит строку, где указанный индекс удовлетворяет данные значения и
соблюдает WHERE
. Если у Вас есть многостолбцовый индекс,
укажите список значений столбцов как список разделенных запятой значений. Или
определите значения для всех столбцов в индексировании, или определите
значения для крайнего левого префикса индекса столбцов. Предположите, что
индекс my_idx
включает три столбца
col_a
, col_b
и col_c
, в этом порядке.
HANDLER
может определить значения для всех трех столбцов в
индексе или для столбцов в крайнем левом префиксе. Например:
HANDLER ... READ my_idx = (col_a_val,col_b_val,col_c_val) ... HANDLER ... READ my_idx = (col_a_val,col_b_val) ... HANDLER ... READ my_idx = (col_a_val) ...Чтобы использовать
HANDLER
интерфейс, чтобы обратиться к таблице
PRIMARY KEY
, используйте заключенный в
кавычки идентификатор `PRIMARY`
:
HANDLER tbl_name
READ `PRIMARY` ...
Второй синтаксис HANDLER ... READ
приносит строку от таблицы в
порядке индекса, который соответствует WHERE
.
Третий синтаксис HANDLER ... READ
приносит строку от таблицы в естественном порядке строк, который
соответствует WHERE
. Это быстрее
HANDLER
,
когда полное сканирование таблицы желаемо. Естественный порядок строк
это порядок, в котором строки сохранены в файле данных.
Это запрос работает на tbl_name
READ
index_name
InnoDB
также, но нет такого понятия,
потому что нет никакого отдельного файла с данными.
Без LIMIT
все формы HANDLER ... READ
принесут единственную строку.
Чтобы возвратить определенное число строк, включайте LIMIT
.
У него есть тот же самый синтаксис, как у
SELECT
, см.
раздел 14.2.9.
HANDLER ... CLOSE
закрывает таблицу, которая была
открыта HANDLER ... OPEN
.
Есть несколько причин использовать интерфейс HANDLER
вместо нормального SELECT
:
HANDLER
быстрее
SELECT
:
Определяемый объект обработчика механизма хранения выделен для
HANDLER ... OPEN
. Объект снова использован для последующего
HANDLER
для этой таблицы: это не должно быть повторно
инициализировано для каждого.
SELECT
обычно не разрешает.HANDLER
облегчает портирование на MySQL
приложения MySQL, которые используют низкий уровень ISAM
См. раздел 16.19.HANDLER
позволяет Вам пересечь базу данных в манере, которая
является трудной (или даже невозможной) с
SELECT
. HANDLER
более естественный способ смотреть на данные, работая с приложениями, которые
обеспечивают интерактивный пользовательский интерфейс базе данных.
HANDLER
несколько низкоуровневый запрос. Например, это не
обеспечивает последовательность. Таким образом,
HANDLER ... OPEN
не
берет снимок таблицы, и не
блокирует таблицу. Это означает, что после HANDLER ... OPEN
табличные данные могут быть изменены (текущим сеансом или другими сеансами),
и эти модификации могли бы быть только частично видимыми в
HANDLER ... NEXT
или HANDLER ... PREV
.
Открытый обработчик может быть закрыт и отмечен для повторного открытия, когда обработчик теряет свою позицию в таблице. Это происходит, когда оба из следующих обстоятельств истинны:
Любой сеанс выполняет
FLUSH TABLES
или запросы DDL на таблице обработчика.
HANDLER
запросы для таблицы.TRUNCATE TABLE
закрывает все обработчики для таблицы, которые были
открыты с HANDLER OPEN
.
Если таблица сбрасывается с FLUSH TABLES
, обработчик неявно
сбрасывается и теряет свою позицию.tbl_name
WITH READ LOCK
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]Или:tbl_name
[PARTITION (partition_name
,...)] [(col_name
,...)] {VALUES | VALUE} ({expr
| DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATEcol_name
=expr
[,col_name
=expr
] ... ]
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]Или:tbl_name
[PARTITION (partition_name
,...)] SETcol_name
={expr
| DEFAULT}, ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
[,col_name
=expr
] ... ]
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[PARTITION (partition_name
,...)] [(col_name
,...)] SELECT ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
[,col_name
=expr
] ... ]
INSERT
вставляет новые строки в существующую таблицу.
INSERT ... VALUES
и
INSERT ... SET
формы вставляют строки, основанные на явно указанных значениях.
INSERT ... SELECT
вставляет строки, выбранные из другой таблицы или таблиц.
INSERT ... SELECT
рассмотрена в разделе 14.2.5.1.
Вставляя в разделенную таблицу, Вы можете управлять, какие раздел и
подраздел принимают новые строки. PARTITION
берет список разделенных запятой значений названий одного или более раздела
или подразда (или оба) таблицы. Если любая из строк, которые будут вставлены
данным INSERT
не соответствует одному из перечисленных
разделов, INSERT
терпит неудачу с ошибкой
Found a row not matching the given partition set. См.
раздел 20.5.
В MySQL 8.0 DELAYED
принято, но проигнорировано сервером. См.
раздел 14.2.5.2.
Вы можете использовать REPLACE
вместо INSERT
, чтобы
перезаписывать старые строки. REPLACE
копия INSERT IGNORE
в
обработке новых строк, которые содержат уникальные значения ключа, которые
дублируют старые строки: новые строки используются, чтобы заменить старые
строки вместо того, чтобы отказать, см. раздел
14.2.8.
tbl_name
таблица, в которую должны быть вставлены
строки. Столбцы, для которых запрос обеспечивает значения, могут быть
определены следующим образом:
Вы можете обеспечить список разделенных запятой значений имен
столбцов после имени таблицы. В этом случае значение для каждого названного
столбца должно быть обеспечено списком VALUES
или
SELECT
.
INSERT ... VALUES
или
INSERT ... SELECT
,
значения для каждого столбца в таблице должны быть обеспечены
VALUES
или SELECT
.
Если Вы не знаете порядка столбцов в таблице, надо использовать
DESCRIBE tbl_name
.SET
указывает на имена столбцов явно.Значения столбцов могут быть даны несколькими способами:
Если Вы не работаете в строгом режиме SQL, любой столбец, не явно заданный, установлен в его значение по умолчанию (явное или неявное). Например, если Вы определяете список столбца, который не называет все столбцы в таблице, неназванные столбцы установлены в их значения по умолчанию. Назначение значения по умолчанию описано в разделе 12.7. См. раздел 1.8.3.3.
Если Вы хотите, чтобы INSERT
произвел ошибку, если Вы явно не определяете значения для всех столбцов, у
которых нет значения по умолчанию, Вы должны использовать строгий режим. См.
раздел 6.1.8.
DEFAULT
, чтобы установить столбец
явно в его значение по умолчанию. Это облегчает написание
INSERT
, которые назначают значения
всем кроме нескольких столбцов, потому что это позволяет Вам избежать писать
неполный список VALUES
, который не включает значение для каждого
столбца в таблице. Иначе, Вы должны были бы выписать список имен столбцов,
соответствующих каждому значению в VALUES
.
Вы можете также использовать
DEFAULT(
как более общую форму,
которая может использоваться в выражениях, чтобы произвести значение по
умолчанию данного столбца.col_name
)
VALUES
список пуст,
INSERT
создает строку с каждым
столбцом, установленным к его значению по умолчанию:
INSERT INTO tbl_name
() VALUES();
В строгом режиме происходит ошибка, если у какого-либо столбца нет значения
по умолчанию. Иначе MySQL использует неявное значение по умолчанию для любого
столбца, у которого нет явно определенного значения по умолчанию.expr
, чтобы
обеспечить значение столбца. Это могло бы вовлечь преобразование типа, если
тип выражения не соответствует тип столбца, и преобразование данного значения
может привести к различным вставленным значениям в зависимости от типа
данных. Например, вставка строки '1999.0e-2'
в
INT
,
FLOAT
,
DECIMAL(10,6)
или
YEAR
приводит к значениям
1999
, 19.9921
, 19.992100
и
1999
, соответственно. Причина: значение, сохраненное в
INT
и
YEAR
1999
это конверсия строки к целому числу только на такое большое количество
начальной части строки, как может считаться допустимым целым числом или
годом. Для столбцов с плавающей запятой и столбцов фиксированной точки,
преобразование строки к плавающей запятой считает всю строку допустимым
значением с плавающей запятой.
expr
может обратиться к любому столбцу, который был
установлен ранее в списке значения. Например, Вы можете сделать это потому,
что значение для col2
обращается к col1
,
который был ранее назначен:
INSERT INTO tbl_name
(col1,col2) VALUES(15,col1*2);
Но следующее не является законным, потому что значение для
col1
обращается к col2
,
который назначен после col1
:
INSERT INTO tbl_name
(col1,col2) VALUES(col2*2,15);
Одно исключение вовлекает столбцы, которые содержат
AUTO_INCREMENT
. Поскольку AUTO_INCREMENT
произведено после других значений, любые ссылки на столбец
AUTO_INCREMENT
возвращают 0
.INSERT
с использованием
VALUES
может вставить многократные строки. Чтобы сделать это,
включайте многократные списки значений столбцов, каждый в пределах круглых
скобок и отделенный запятыми. Пример:
INSERT INTO tbl_name
(a,b,c)
VALUES(1,2,3), (4,5,6), (7,8,9);
Список значений для каждой строки должен быть приложен в пределах круглых
скобок. Следующий запрос незаконный, потому что число значений в списке не
соответствует числу имен столбцов:
INSERT INTO tbl_name
(a,b,c)
VALUES(1,2,3,4,5,6,7,8,9);
VALUE
синоним VALUES
этом контексте. Ни один ничего
не подразумевает о числе списков значений, и может использоваться, есть ли
единственный список значений или многократные списки.
Число затронутых строк для INSERT
может быть получено, используя
ROW_COUNT()
(см.
раздел 13.14) или
mysql_affected_rows()
C API (см.
раздел 25.8.7.1).
Если Вы используете INSERT ... VALUES
с многократными списками значения или
INSERT ... SELECT
, запрос
возвращает информационную строку в этом формате:
Records: 100 Duplicates: 0 Warnings: 0
Records
указывает на число строк, обработанных запросом.
Это не обязательно число строк, фактически вставленных, потому что
Duplicates
может быть отличным от нуля. Duplicates
указывает на число строк, которые не могли быть вставлены, потому что они
дублируют некоторые существующие уникальные индексные значения.
Warnings
указывает на число попыток вставить значения столбцов,
которые были проблематичны в некотором роде. Предупреждения могут произойти
при любом из следующих условий:
Вставка NULL
в столбец, который был объявлен
NOT NULL
. Для многострочного
INSERT
или
INSERT INTO ... SELECT
столбец установлен в неявное значение по умолчанию для типа данных столбца.
Это 0
для числовых типов, пустая строка (''
)
для строковых типов и нулевое значение для типов
времени и даты. INSERT INTO ...
SELECT
обработаны так же, как многократные строки, потому что
сервер не исследует набор результатов от
SELECT
, чтобы
видеть, возвращает ли это единственную строку. Для единственной строки
INSERT
никакое предупреждение не
происходит, когда NULL
вставлен в столбец NOT NULL
.
Вместо этого запрос терпит неудачу с ошибкой.
'10.34 a'
числовому столбцу. Нечисловой текст отрезан, а остающаяся числовая часть
вставлена. Если у строкового значения нет никакой ведущей числовой части,
столбец установлен в 0
.CHAR
,
VARCHAR
,
TEXT
или
BLOB
), которая
превышает максимальную длину столбца. Значение является усеченным к
максимальной длине столбца.Если произведенный столбец вставлен явно, единственное разрешенное
значение DEFAULT
. См.
раздел 14.1.15.5.
Если Вы используете C API, информационная строка может быть получена,
вызывая mysql_info()
, см.
раздел 25.8.7.36.
Если INSERT
вставляет строку в таблицу, которая имеет AUTO_INCREMENT
,
Вы можете считать значение для этого столбца при использовании SQL
LAST_INSERT_ID()
.
Из C API используйте
mysql_insert_id()
. Однако, Вы должны отметить, что две функции не
всегда ведут себя тождественно. Поведение
INSERT
относительно
AUTO_INCREMENT
рассмотрено в разделах
13.14 и
25.8.7.38.
INSERT
поддерживает следующие модификаторы:
INSERT DELAYED
устарел в MySQL 5.7 и намечен для возможного удаления. В MySQL 8.0
DELAYED
принято, но проигнорировано. Надо использовать
INSERT
(без DELAYED
), см.
раздел 14.2.5.2.
LOW_PRIORITY
, выполнение
INSERT
отсрочено, пока никакие
другие клиенты не читают из таблицы. Это включает других клиентов, которые
начали читать в то время, как существующие клиенты читают, и в то время как
INSERT LOW_PRIORITY
ждет. Возможно, поэтому, для клиента,
который выполнил INSERT LOW_PRIORITY
ждать долго.
LOW_PRIORITY
не должен обычно использоваться с таблицами
MyISAM
, потому что его выполнение отключает параллельные
вставки. См. раздел 9.11.3.
Если Вы определяете HIGH_PRIORITY
, это переопределяет эффект
--low-priority-updates
, если сервер был запущен с этой опцией. Это
также заставляет параллельные вставки не использоваться. См.
раздел 9.11.3.
LOW_PRIORITY
и HIGH_PRIORITY
затронут только механизмы хранения, которые используют только блокировку на
уровне таблицы (MyISAM
,
MEMORY
и MERGE
).
IGNORE
,
ошибки, которые происходят, выполняя
INSERT
проигнорированы. Например, без IGNORE
строка, которая дублирует существующий индекс UNIQUE
или
значение PRIMARY KEY
в таблице вызывает ошибку, и запрос
прерван. С IGNORE
от строки отказываются, и никакая ошибка не
происходит. Проигнорированные ошибки производят предупреждения вместо этого.
IGNORE
имеет подобный эффект на вставки в разделенные
таблицы, где никакой раздел, соответствующий данному значению, не найден.
Без IGNORE
INSERT
прерван с ошибкой, однако, когда INSERT
IGNORE
применен, работа вставки терпит неудачу тихо для строки,
содержащей несоответствующее значение, но любые строки, которые являются
соответствующими, вставлены. Для примера см.
раздел 20.2.2.
Преобразования данных, которые вызвали бы ошибки, прерывают запрос, если
IGNORE
не определен. С IGNORE
недопустимые значения скорректированы к самым близким значениям и вставлены,
предупреждения произведены, но запрос не прерывается. Вы можете определить с
mysql_info()
C API, сколько
строк было фактически вставлено в таблицу.
ON DUPLICATE KEY UPDATE
, и строка
вставлена, которая вызвала бы дубликат значения в индексе
UNIQUE
или PRIMARY KEY
,
UPDATE
из старой строки выполнен.
Значение затронутых строк за строку 1, если строка вставлена как новая
строка, 2, если существующая строка обновлена, и 0, если существующая строка
установлена в ее текущее значение. Если Вы определяете
CLIENT_FOUND_ROWS
для
mysql_real_connect()
, соединяясь с mysqld
, значение затронутых строк 1 (не 0), если существующая
строка установлена в ее текущее значение. См.
раздел 14.2.5.3.Вставка в таблицу требует привилегии
INSERT
для таблицы. Если ON DUPLICATE KEY UPDATE
используется, и
дубликат ключа вызываетUPDATE
вместо этого, запрос требует привилегию
UPDATE
для столбцов, которые будут обновлены. Для столбцов, которые считаны, но
не изменены, нужна только SELECT
(для столбцов в правой части
col_name
=expr
в ON DUPLICATE KEY UPDATE
).
В MySQL 8.0 INSERT
, затрагивающий разделенную таблицу,
используя такой механизм хранения, как
MyISAM
, который
использует блокировки на уровне таблицы, блокирует только тот раздел, в
который фактически вставлены строки. Для механизмов хранения вроде
InnoDB
, которые используют
блокировку на уровне строки, никакая блокировка раздела не имеет места. См.
Partitioning and Locking.
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO]Сtbl_name
[PARTITION (partition_name
,...)] [(col_name
,...)] SELECT ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
INSERT ... SELECT
Вы можете быстро вставить много строк в таблицу от одной или
многих таблиц. Например:
INSERT INTO tbl_temp2 (fld_id) SELECT tbl_temp1.fld_order_id FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;Следующие условия держатся для
INSERT ... SELECT
:
Определите IGNORE
, чтобы
проигнорировать строки, которые вызвали бы ошибки дублирования ключа.
INSERT
может появиться в FROM
части
SELECT
запроса. Это не было возможно в некоторых более старых
версиях MySQL. Однако, Вы не можете вставить в таблицу и выбрать из той же
самой таблицы в подзапросе.
Выбирая из и вставляя в таблицу в то же самое время, MySQL составляет
временную таблицу, чтобы держать строки из
SELECT
и затем вставляет те строки в целевую таблицу. Однако, это
остается истиной, что Вы не можете использовать INSERT INTO t ...
SELECT ... FROM t
, когда t
TEMPORARY
,
потому что таблицы TEMPORARY
не могут быть упомянуты дважды в
том же самом запросе (см. раздел
B.5.6.2).
AUTO_INCREMENT
работают как обычно.INSERT ... SELECT
(см.
раздел 9.11.3).SELECT
и
INSERT
обращаются
к той же самой таблице, обеспечьте уникальный псевдоним для каждой таблицы,
используемой в части SELECT
,
и определите имена столбцов в этой части с соответствующим псевдонимом.
Вы можете явно выбрать, какой раздел или подраздел (или оба) источника или
таблицы назначения (или обеих) должны использоваться с опцией
PARTITION
после названия таблицы. Когда PARTITION
используется с названием исходной таблицы в части
SELECT
,
строки выбраны только из раздела или подраздела, названного в его списке
разделов. Когда PARTITION
используется с названием целевой таблицы для части
INSERT
,
тогда должно быть возможно вставить все строки в раздел или подраздел,
названный в списке разделов после опции, иначе INSERT ...
SELECT
терпит неудачу. Для получения дополнительной информации и
примеров см. раздел 20.5.
В части значений ON DUPLICATE KEY UPDATE
Вы можете обратиться к столбцам в других таблицах, пока Вы не используете
GROUP BY
в части SELECT
. Один побочный эффект состоит в том, что Вы должны квалифицировать
групповые имена столбцов в части значений.
Порядок, в котором строки возвращены
SELECT
без
ORDER BY
не определен. Это означает, что, используя репликацию
нет никакой гарантии, что такой SELECT
возвращает в том же самом порядке на ведущем и ведомом устройствах, это может
привести к несогласованностям между ними. Чтобы препятствовать этому,
Вы должны всегда писать INSERT ... SELECT
, которые должны
копироваться как INSERT ... SELECT ... ORDER BY
. Выбор column
column
не имеет значения, пока тот же самый порядок строк проведен в жизнь на
ведущем и на ведомом устройствах. См. также
раздел 19.4.1.17.
Из-за этой проблемы
INSERT ...
SELECT ON DUPLICATE KEY UPDATE
и
INSERT IGNORE ... SELECT
отмечены как опасные для основанной на запросе репликации. С этим изменением
такие запросы производят предупреждение в журнале, используя основанный на
запросе режим и зарегистрированы, используя основанный на строке формат,
используя режим MIXED
(Bug #11758262, Bug #50439).
См. также раздел 19.2.1.1.
В MySQL 8.0 INSERT ... SELECT
, который действовал на
разделенные таблицы, используя такой механизм хранения, как
MyISAM
, который
использует блокировки на уровне таблицы, блокирует все разделы целевой
таблицы. Однако, только тот раздел, который фактически считан из исходной
таблицы, заблокирован. Это не происходит с таблицами, используя такие
механизмы хранения, как InnoDB
,
которые работают с блокировкой на уровне строки. См.
Partitioning and Locking.
INSERT DELAYED ...Опция
DELAYED
для
INSERT
в MySQL это
расширение MySQL к стандартному SQL. В предыдущих версиях MySQL это может
использоваться для определенных видов таблиц (таких, как
MyISAM
), таким образом это, когда клиент использует
INSERT DELAYED
,
регистрируется сервером сразу, и строка стоит в очереди, чтобы быть
вставленной, когда таблица не находится в использовании
никаким другим потоком.
DELAYED
устарела в MySQL 5.6.6. В MySQL 8.0
DELAYED
не поддерживается. Сервер признает, но игнорирует
DELAYED
, обрабатывает вставку как неотсроченную вставку и
производит предупреждение ER_WARN_LEGACY_SYNTAX_CONVERTED
(INSERT DELAYED is no longer supported. The statement was
converted to INSERT). DELAYED
намечено для удаления в будущем выпуске.
Если Вы определяете ON DUPLICATE KEY UPDATE
, и строка
вставлена, которая вызвала бы дубликат значения в индексе
UNIQUE
или PRIMARY KEY
, MySQL применит
UPDATE
из старой строки.
Например, если столбец a
объявлен как UNIQUE
и
содержит значение 1
, следующие два запроса
имеют подобный эффект:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;Эффекты не идентичны для таблицы
InnoDB
,
где a
столбец auto-increment. Со столбцом auto-increment
INSERT
увеличивает значение auto-increment, но
UPDATE
не делает.
ON DUPLICATE KEY UPDATE
может содержать многократные назначения столбца, отделенные запятыми.
С ON DUPLICATE KEY UPDATE
значение затронутых строк за строку
1, если строка вставлена как новая строка, 2, если существующая строка
обновлена, и 0, если существующая строка установлена в ее текущее значение.
Если Вы определяете CLIENT_FOUND_ROWS
для
mysql_real_connect()
соединяясь с mysqld
, значение затронутых строк 1 (не 0), если существующая строка
установлена в ее текущее значение.
Если b
также уникален,
INSERT
эквивалентен
UPDATE
:
UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;Если
a=1 OR b=2
соответствует несколько строк, только одна
обновлена. Вообще, Вы должны попытаться избегать использования
ON DUPLICATE KEY UPDATE
на таблицах с
уникальным многократным индексом.
Вы можете использовать
VALUES(
в
col_name
)UPDATE
, чтобы обратиться к
значениям столбцов из части INSERT
запроса INSERT ...
ON DUPLICATE KEY UPDATE
. Другими словами,
VALUES(
в col_name
)ON DUPLICATE KEY UPDATE
относится к значению
col_name
было бы вставлено, если бы не было никакой
ошибки дублирования ключа. Эта функция особенно полезна при вставке многих
строк. VALUES()
является значащей только в INSERT ... UPDATE
,
иначе вернет NULL
:
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);Этот запрос идентичен следующим двум запросам:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3; INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;Если таблица содержит
AUTO_INCREMENT
и
INSERT ... ON DUPLICATE KEY
UPDATE
вставляет или обновляет строку,
LAST_INSERT_ID()
возвращает значение AUTO_INCREMENT
.
DELAYED
проигнорирована, когда Вы используете
ON DUPLICATE KEY UPDATE
.
Поскольку результаты
INSERT ... SELECT
зависят от упорядочивания строк из
SELECT
и этот порядок не может всегда гарантироваться, возможно, регистрируя
INSERT ...
SELECT ON DUPLICATE KEY UPDATE
для ведущего и ведомого устройств
получить разные результаты. Таким образом,
INSERT ...
SELECT ON DUPLICATE KEY UPDATE
отмечены как опасные для основанной
на запросе репликации. С этим изменением такие запросы производят
предупреждение в журнале, используя основанный на запросе режим и
зарегистрированы, используя основанный на строке формат, используя режим
MIXED
. Кроме того,
INSERT ...
ON DUPLICATE KEY UPDATE
для таблицы, имеющей больше чем один уникальный или первичный ключ, также
отмечен как опасный (Bug #11765650, Bug #58637), см.
раздел 19.2.1.1.
В MySQL 8.0 INSERT ... ON DUPLICATE KEY UPDATE
на разделенной таблице, используя механизм хранения
MyISAM
, который
использует блокировки на уровне таблицы, блокирует любой раздел таблицы, в
котором обновлен ключевой столбец раздела. Для механизмов хранения, которые
используют блокировку на уровне строки, это не так. См.
Partitioning and Locking.
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name
' [REPLACE | IGNORE] INTO TABLEtbl_name
[PARTITION (partition_name
,...)] [CHARACTER SETcharset_name
] [{FIELDS | COLUMNS} [TERMINATED BY 'string
'] [[OPTIONALLY] ENCLOSED BY 'char
'] [ESCAPED BY 'char
'] ] [LINES [STARTING BY 'string
'] [TERMINATED BY 'string
'] ] [IGNOREnumber
{LINES | ROWS}] [(col_name_or_user_var
,...)] [SETcol_name
=expr
,...]
LOAD DATA INFILE
читает строки из текстового файла в таблицу на сверхвысокой скорости.
LOAD DATA INFILE
дополнение SELECT ... INTO OUTFILE
, см. раздел 14.2.9.1).
Чтобы писать данные из таблицы в файл, надо использовать
SELECT ... INTO OUTFILE
.
Чтобы считать файл назад в таблицу, надо использовать
LOAD DATA INFILE
. Синтаксис
FIELDS
и LINES
тот же самый для обоих запросов. Оба пункта являются дополнительными, но
FIELDS
должен предшествовать LINES
,
если оба определены.
Вы можете также загрузить файлы с данными при использовании
mysqlimport
, это работает, посылая серверу запрос
LOAD DATA INFILE
. Опция
--local
заставляет mysqlimport
читать файлы с данными из хоста клиента. Вы можете
определить
--compress
, чтобы получить лучшую работу по медленным сетям, если
клиент и сервер поддерживают сжатый протокол. См.
раздел 5.5.5.
Имя файла должно быть дано как буквальная строка. На Windows определите
наклонные черты влево в путях как наклонные черты вправо или удвоенные
наклонные черты влево.
character_set_filesystem
управляет интерпретацией имени файла.
LOAD DATA
поддерживает явный выбор раздел, используя
PARTITION
со списком разделенных запятой значений одного или
более названий разделов, подразделов или обоих. Когда эта опция используется,
если какие-либо строки из файла не могут быть вставлены ни в один раздел,
названный в списке, запрос терпит неудачу с ошибкой
Found a row not matching the given partition set. См.
раздел 20.5.
Для разделенных таблиц, используя механизмы хранения, которые используют
табличные блокировки, например,
MyISAM
, LOAD DATA
не может сократить блокировки раздела. Это не относится к таблицам,
использующим механизмы хранения, которые используют блокировку на уровне
строки, например, InnoDB
. См.
Partitioning and Locking.
Сервер использует набор символов, обозначенный
character_set_database
, чтобы интерпретировать информацию в файле.
SET NAMES
и установка
character_set_client
не затрагивают интерпретацию ввода. Если содержание входного
файла использует набор символов, который отличается от значения по умолчанию,
обычно предпочтительно определить набор символов файла при использовании
CHARACTER SET
. Набор символов binary
определяет отсутствие конвертации.
LOAD DATA INFILE
интерпретирует все области в файле как наличие того же самого набора
символов, независимо от типов данных столбцов, в которые загружены значения
полей. Для правильной интерпретации содержания файла Вы должны гарантировать,
что он был написан с правильным набором символов. Например, если Вы пишете
файл с данными с mysqldump -T
или через SELECT ...
INTO OUTFILE
в mysql
, надо убедиться, что использовали опцию
--default-character-set
, чтобы вывод был написан в наборе
символов, который будет использоваться, когда файл загружен
LOAD DATA INFILE
.
Невозможно загрузить файлы с данными, которые используют
ucs2
, utf16
,
utf16le
или utf32
.
Если Вы используете LOW_PRIORITY
, выполнение
LOAD DATA
отсрочено, пока никакие другие клиенты не читают из таблицы. Это затрагивает
только механизмы хранения, которые используют только блокировку на уровне
таблицы (MyISAM
, MEMORY
и MERGE
).
Если Вы определяете CONCURRENT
с
MyISAM
, которая удовлетворяет условию для параллельных вставок
(то есть, не содержит свободных блоков в середине), другие потоки могут
получить данные от таблицы в то время, как работает
LOAD DATA
.
Эта опция затрагивает исполнение LOAD
DATA
, даже если никакой другой поток не использует таблицу в то
же самое время.
С основанной на строке репликацией CONCURRENT
копируется независимо от версии MySQL. С основанной на запросе репликацией
CONCURRENT
не копируется до MySQL 5.5.1 (см. Bug #34628). См.
раздел 19.4.1.18.
LOCAL
затрагивает ожидаемое местоположение файла и обработку
ошибок, как описано позже. LOCAL
применим
только если Ваш сервер и Ваш клиент оба были сконфигурированы, чтобы
разрешить это. Например, если
mysqld был запущен с
--local-infile=0
,
LOCAL
не работает. См.
раздел 7.1.6.
LOCAL
затрагивает, где файл, как ожидают, будет найден:
Если LOCAL
определен, файл считан программой клиента
на хосте клиента и послан на сервер. Файл может быть дан как полный путь,
чтобы определить его точное местоположение. Если дано как относительный путь,
имя интерпретируется относительно каталога, в котором была
запущена программа клиента.
Используя LOCAL
с LOAD DATA
, копия файла создается во временном каталоге сервера. Это не
каталог, определенный значением
tmpdir
или
slave_load_tmpdir
, а временный каталог операционной системы, и он не конфигурируем в
сервере MySQL. Как правило, временный каталог системы /tmp
в
Linux и C:\WINDOWS\TEMP
в Windows. Нехватка достаточного
пространства для копии в этом каталоге может вызвать сбой
LOAD DATA LOCAL
.
LOCAL
не определен, файл должен быть расположен на
машине сервера и считан непосредственно сервером. Сервер использует следующие
правила определения местонахождения файла:
Если имя файла абсолютный путь, сервер использует его как дано.
В не-LOCAL
случае эти правила означают, что файл
./myfile.txt
считан из каталога данных сервера, тогда как файл
myfile.txt
считан из каталога базы данных по умолчанию.
Например, если база данных значения по умолчанию db1
,
следующий запрос LOAD DATA
читает файл data.txt
из каталога базы данных db1
,
даже при том, что запрос явно загружает файл в таблицу в db2
:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;Из соображений безопасности, читая текстовые файлы, расположенные на сервере, файлы должны находиться в каталоге базы данных или быть читаемыми учетной записью пользователя, используемой, чтобы выполнить сервер. Кроме того, чтобы использовать
LOAD DATA INFILE
на файлах сервера Вы должны иметь привилегию
FILE
. См.
раздел 7.2.1.
Для не-LOCAL
, если
secure_file_priv
установлена в непустое имя каталога, файл,
который будет загружен, должен быть расположен в том каталоге.
Использование LOCAL
немного медленнее, чем разрешение серверу
получить доступ к файлам непосредственно, потому что содержание файла должен
послать по соединению клиент к серверу. С другой стороны, Вы не нуждаетесь в
привилегии FILE
, чтобы
загрузить местные файлы.
LOCAL
также меняет обработку ошибок:
С LOAD DATA INFILE
интерпретация данных и ошибки дубликата ключа заканчивают работу.
LOAD DATA LOCAL INFILE
интерпретация данных и ошибки дубликата ключа
становятся предупреждениями, и работа продолжается, потому что у сервера нет
никакого способа остановить передачу файла в середине работы.
Для ошибок дубликата ключа это то же самое, как будто указан
IGNORE
. IGNORE
объяснен позже в этом разделе.
REPLACE
и IGNORE
управляют обработкой входных
строк, которые дублируют существующие строки на уникальных значениях ключа:
Если указан REPLACE
, входные строки заменяют
существующие строки. Другими словами, строки, у которых есть то же самое
значение для первичного ключа или уникального индекса как у
существующей строки. См. раздел 14.2.8.
IGNORE
, от строк, которые дублируют существующую
строку на уникальном значении ключа, отказываются.LOCAL
. Без LOCAL
ошибка происходит, когда
дублирующее значение ключа найдено, и остальная часть текстового файла
проигнорирована. С LOCAL
поведение по умолчанию то же самое, как
будто IGNORE
определен, потому что у сервера нет никакого
способа остановить передачу файла в середине работы.Чтобы проигнорировать ограничения внешнего ключа во время работы загрузки,
установите SET foreign_key_checks = 0
перед
LOAD DATA
.
Если Вы используете LOAD DATA
INFILE
на пустой таблице MyISAM
, все групповые
индексы создаются в отдельном пакете (что касается
REPAIR TABLE
).
Обычно это делает LOAD DATA INFILE
намного быстрее, когда Вы имеете много индексов. В некоторых крайних
случаях Вы можете создать индексирование еще быстрее, выключая их с
ALTER TABLE ... DISABLE KEYS
прежде, чем загрузить файл в таблицу и используя
ALTER TABLE ... ENABLE KEYS
, чтобы пересоздать
индексирование после загрузки файла. См.
раздел 9.2.2.1.
Для LOAD DATA INFILE
и
SELECT ... INTO OUTFILE
синтаксис FIELDS
и LINES
одинаков.
Оба пункта являются дополнительными, но FIELDS
должен предшествовать LINES
, если оба определены.
Если Вы определяете FIELDS
, каждый из его подпунктов
(TERMINATED BY
, [OPTIONALLY] ENCLOSED BY
и
ESCAPED BY
) является также дополнительным, за исключением того,
что Вы должны определить по крайней мере один из них.
Если Вы не определяете FIELDS
или LINES
,
значения по умолчанию те же самые, как будто Вы написали:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY ''Наклонная черта влево это символ ESC MySQL в пределах строк в запросах SQL, чтобы определить буквальную наклонную черту влево, Вы должны определить две наклонных черты влево для значения, которое будет интерпретироваться как единственная наклонная черта влево. Escape-последовательности
'\t'
и '\n'
определяют символы
tab и newline, соответственно.
Другими словами, по умолчанию в
LOAD DATA INFILE
спецсимволы обработаны следующим образом, когда ввод читается:
Ищет границы строки в новых строках.
\
как escape-последовательности. Например,
\t
, \n
и \\
значат
tab, newline и backslash, соответственно. См. обсуждение FIELDS ESCAPED
BY
позже для полного списка escape-последовательностей.
Наоборот значения по умолчанию
SELECT ... INTO OUTFILE
в выводе:
Пишет tab между областями.
\
, чтобы отметить tab, newline или
\
, где это происходит в пределах значений полей.Если Вы произвели текстовый файл на системе Windows, Вам, возможно,
придется использовать LINES TERMINATED BY '\r\n'
, чтобы
считать файл должным образом, потому что программы Windows, как правило,
используют два символа в качестве разделителя строки. Некоторые программы,
такие как WordPad,
могли бы использовать \r
как разделитель строки при записи
файлов. Чтобы считать такие файлы, надо использовать
LINES TERMINATED BY '\r'
.
Если у всех строк, которые Вы хотите читать, есть общий префикс,
который Вы хотите проигнорировать, Вы можете использовать
LINES STARTING BY '
,
чтобы перескакивать через префикс и что-либо перед ним.
Если строка не включает префикс, вся строка пропущена. Предположите, что Вы
делаете следующий запрос:
prefix_string
'
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test FIELDS TERMINATED BY ',' LINES STARTING BY 'xxx';Если файл с данными похож на это:
xxx"abc",1 something xxx"def",2 "ghi",3Получающиеся строки будут
("abc",1)
и ("def",2)
.
Третья строка в файле пропущена, потому что это не содержит префикс.
IGNORE
может использоваться, чтобы проигнорировать строки в начале файла. Например,
Вы можете использовать number
LINESIGNORE 1 LINES
, чтобы
перескакивать через начальную строку заголовка, содержащую имена столбцов:
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;Когда Вы используете
SELECT
... INTO OUTFILE
c LOAD DATA
INFILE
, чтобы написать данные от базы данных в файл и затем
считать файл назад в базу данных позже, опции для обоих запросов должны
соответствовать. Иначе LOAD DATA
INFILE
не будет интерпретировать содержание файла должным образом.
Предположите, что Вы используете SELECT
... INTO OUTFILE
, чтобы написать файл с
областями, разграниченными запятыми:
SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM table2;Чтобы считать файл разделенных запятыми значений назад, правильный запрос:
LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';Если бы вместо этого Вы попытались читать файл запросом, показанным ниже, то это не работало бы, потому что это инструктирует
LOAD DATA INFILE
искать tab между областями:
LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';Вероятный результат состоит в том, что каждая входная строка интерпретировалась бы как единственная область.
LOAD DATA INFILE
может использоваться, чтобы считать файлы, полученные из внешних источников.
Например, много программ могут экспортировать данные в формате отделенных
запятыми значений (CSV). Если строки в таком файле закончены возвратом
каретки и новой строкой, запрос, показанный здесь, иллюстрирует опции,
которые Вы использовали бы, чтобы загрузить файл:
LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n' IGNORE 1 LINES;
Если входные значения не обязательно приложены в пределах кавычек, надо
использовать OPTIONALLY
перед ENCLOSED BY
.
Любая опция может определить пустую строку (''
). Если не
пуста, значения FIELDS [OPTIONALLY] ENCLOSED BY
и FIELDS
ESCAPED BY
должны быть единственным символом.
FIELDS TERMINATED BY
, LINES STARTING BY
и
LINES TERMINATED BY
могут быть больше, чем одним символом.
Например, чтобы написать строки, которые закончены возвратом каретки/
переводом строки или считать файл, содержащий такие строки, определяют
LINES TERMINATED BY '\r\n'
clause.
Считать файл, содержащий записи, которые отделены строками, состоящими из
%%
, можно таким запросом:
CREATE TABLE jokes (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, joke TEXT NOT NULL); LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes FIELDS TERMINATED BY '' LINES TERMINATED BY '\n%%\n' (joke);
FIELDS [OPTIONALLY] ENCLOSED BY
управляет цитированием полей.
Для вывода (SELECT ... INTO OUTFILE
), если Вы опускаете слово OPTIONALLY
,
все области заключены в символ ENCLOSED BY
.
Пример такого вывода (использующий запятую в качестве полевого разделителя):
"1","a string","100.20" "2","a string containing a , comma","102.20" "3","a string containing a \" quote","102.20" "4","a string containing a \", quote and comma","102.20"Если указано
OPTIONALLY
, символ ENCLOSED BY
используется только, чтобы приложить значения от столбцов, у которых есть
строковый тип данных
(CHAR
,
BINARY
,
TEXT
или
ENUM
):
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a \" quote",102.20 4,"a string containing a \", quote and comma",102.20Возникновения символа
ENCLOSED BY
в пределах значения поля оставляют, предварительно помечая их символом
ESCAPED BY
. Также отметьте, что если Вы определяете пустой
ESCAPED BY
, возможно неосторожно произвести вывод, который не
может быть считан должным образом LOAD DATA
INFILE
. Например, предыдущий вывод выглядел бы следующим образом,
если символ ESC пуст. Заметьте, что вторая область в четвертой строке
содержит запятую после кавычки, которая ошибочно заканчивает область:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a " quote",102.20 4,"a string containing a ", quote and comma",102.20Для ввода символ
ENCLOSED BY
, если есть, отрезан от концов
значений полей. Это истина, независимо от того, определен ли
OPTIONALLY
, OPTIONALLY
не имеет никакого эффекта на входную интерпретацию. Возникновения
символа ENCLOSED BY
, которому предшествует символ
ESCAPED BY
интерпретируются как часть текущего значения поля.
Если область начинается с ENCLOSED BY
, экземпляры
того символа признаны завершением значения поля, только если сопровождаемы
областью или строкой TERMINATED BY
.
Чтобы избегать двусмысленности возникновений, ENCLOSED BY
в пределах значения поля может быть удвоен и интерпретируется как
единственный случай символа. Например, если ENCLOSED BY '"'
определен, кавычки обработаны как показано здесь:
"The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss The ""BIG"" boss-> The ""BIG"" boss
FIELDS ESCAPED BY
определяет,
как читать или писать специальные символы:
Для ввода, если FIELDS ESCAPED BY
не пуст, возникновения этого символа обрезаны
и следующий символ взят буквально в качестве части значения поля. Некоторые
двухсимвольные последовательности, которые являются исключениями, где первый
символ это символ ESC. Эти последовательности показывают в следующей таблице
(использован \
для символа ESC). Правила для обработки
NULL
описаны позже в этом разделе.
Символ | Escape-последовательность |
---|---|
\0
| ASCII NUL (X'00' ) |
\b
| backspace |
\n
| newline (linefeed) |
\r
| carriage return |
\t
| tab |
\Z
| ASCII 26 (Control+Z) |
\N
| NULL |
Если FIELDS ESCAPED BY
пуст,
интерпретация escape-последовательности не происходит.
FIELDS ESCAPED BY
не пуст, он используется
как префикс следующих символов:
FIELDS ESCAPED BY
.
FIELDS [OPTIONALLY] ENCLOSED BY
.FIELDS TERMINATED BY
и
LINES TERMINATED BY
.0
(что фактически написано после символа ESC, ASCII
0
, не нулевой байт).Если FIELDS ESCAPED BY
пуст, никаких символов не оставляют и
NULL
выведен как NULL
, не \N
.
Это, вероятно, не хорошая идея определить пустой символ ESC, особенно если
значения полей в Ваших данных содержат какой-либо из символов
из данного списка.
В определенных случаях взаимодействуют опции:
Если LINES TERMINATED BY
пустая, а
FIELDS TERMINATED BY
непустая, строки также закончены с
FIELDS TERMINATED BY
.
FIELDS TERMINATED BY
и FIELDS ENCLOSED BY
обе пусты (''
), (неразграниченный) формат фиксированной строки
используется. С форматом фиксированной строки никакие разделители не
используются между областями (но у Вас может все еще быть разделитель
строки). Вместо этого значения столбцов считаны и написаны, используя
ширину, достаточно большую, чтобы содержать все значения в области. Для
TINYINT
,
SMALLINT
,
MEDIUMINT
,
INT
и
BIGINT
ширина 4, 6, 8, 11 и 20, соответственно, независимо от того какова
заявленная ширина отображения.
LINES TERMINATED BY
все еще используется, чтобы отделить
строки. Если строка не содержит все области, остальная часть столбцов
установлена в их значения по умолчанию. Если у Вас нет разделителя строки, Вы
должны установить это в ''
. В этом случае текстовый файл должен
содержать все области для каждой строки.
Формат фиксированной строки также затрагивает обработку
NULL
, как описано позже.
Формат фиксированной строки не работает, если Вы используете многобайтовый набор символов.
Обработка NULL
изменяется
согласно FIELDS
и LINES
:
Для значения по умолчанию FIELDS
и
LINES
NULL
написан как значение поля
\N
, для вывода, и значение поля \N
считано как
NULL
для ввода (предполагается, что ESCAPED BY
\
).
FIELDS ENCLOSED BY
не пусто, область, содержащая
буквальное слово NULL
считана как NULL
.
Это отличается от слова NULL
в пределах FIELDS ENCLOSED BY
, которое считано как строка 'NULL'
.FIELDS ESCAPED BY
пуст, NULL
написан как слово NULL
.FIELDS TERMINATED BY
и FIELDS ENCLOSED BY
пусты),
NULL
написан как пустая строка. Это делает значения
NULL
и пустые строки в таблице неразличимыми, когда написаны
в файл, потому что оба написаны как пустые строки. Если Вы должны быть в
состоянии их отличить, когда идет чтение файла
Вы не должны использовать формат фиксированной строки.Попытка загрузить NULL
в столбец NOT NULL
вызывает назначение неявного значения по умолчанию для типа данных столбца и
предупреждения или ошибки в строгом режиме SQL. Неявные значения по умолчанию
обсуждены в раздел 12.7.
Некоторые случаи не поддержаны
LOAD DATA INFILE
:
Строки фиксированного размера (FIELDS TERMINATED BY
и
FIELDS ENCLOSED BY
пусты) и столбцы
BLOB
или
TEXT
.
LOAD DATA INFILE
не может интерпретировать ввод должным образом. Например, следующее
FIELDS
вызовет проблемы:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
FIELDS ESCAPED BY
пуст,
значение поля, которое содержит возникновение FIELDS ENCLOSED BY
или LINES TERMINATED BY
, сопровождаемый
FIELDS TERMINATED BY
,
LOAD DATA INFILE
прекратит читать область или строку слишком рано. Это происходит потому, что
LOAD DATA INFILE
не может должным образом определить, где область или строка кончается.
Следующий пример загружает все
столбцы таблицы persondata
:
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;По умолчанию, когда никакой список столбцов не обеспечен в конце
LOAD DATA INFILE
,
входные строки, как ожидают, будут содержать область для каждого столбца
таблицы. Если Вы хотите загрузить только некоторые из столбцов таблицы,
определите список столбцов:
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);Вы должны также определить список столбцов, если порядок областей во входном файле отличается от порядка столбцов в таблице. Иначе, MySQL не может сказать, как соотнести поля ввода со столбцами таблицы.
Список столбцов может содержать имена столбцов или пользовательские
переменные. С пользовательскими переменными SET
позволяет Вам выполнить преобразования на их значениях прежде, чем
назначить результат столбцам.
Пользовательские переменные в SET
могут
использоваться несколькими способами. Следующий пример использует первый
входной столбец непосредственно для значения t1.column1
и назначает второй входной столбец на пользовательскую переменную, которая
подвергнута делению прежде, чем назначена t1.column2
:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, @var1) SET column2 = @var1/100;
SET
может использоваться, чтобы поставлять значения, не
сделанные во входном файле. Следующий запрос установит
column3
к текущей дате и времени:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, column2) SET column3 = CURRENT_TIMESTAMP;Вы можете также отказаться от входного значения, назначая его на пользовательскую переменную, но не назначая переменную столбцу таблицы:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, @dummy, column2, @dummy, column3);Использование списка столбца/переменной и
SET
подвергается следующим ограничениям:
У SET
должны быть только имена столбцов на левой
стороне операторов назначения.
SET
.
Подзапрос, который возвращает значение, которое будет назначено на столбец,
может быть только скалярным подзапросом. Кроме того, Вы не можете
использовать подзапрос, чтобы выбрать из таблицы, которая загружается.IGNORE
,
не обработаны для списка столбца/переменной или SET
.Обрабатывая входную строку, LOAD
DATA
разделяет ее на области
и использует значения согласно списку столбца/переменной и SET
,
если они присутствуют. Тогда получающаяся строка вставлена в таблицу. Если
есть BEFORE INSERT
или AFTER INSERT
триггеры для
таблицы, они активированы прежде или после вставки строки, соответственно.
Если у входной строки есть слишком много областей, дополнительные области проигнорированы, и число предупреждений увеличено.
Если у входной строки есть слишком мало областей, столбцы таблицы, для которых отсутствуют поля ввода, установлены в их значения по умолчанию. Назначение значения по умолчанию описано в разделе 12.7.
Пустое значение поля интерпретируется как отличающееся от недостающей области:
Для строковых типов столбец установлен в пустую строку.
0
.Это те же самые значения, которые будут результатом, если Вы назначаете
пустую строку явно на строку, число или тип даты или времени явно в
INSERT
или
UPDATE
.
Обработка пустых или неправильных значений полей отличается от только что
описанного, если режим SQL установлен в строгое значение. Например, если
sql_mode
TRADITIONAL
,
преобразование пустого значения или значения такого, как 'x'
для числового столбца приводит к ошибке, а не преобразованию в 0. С
LOCAL
или IGNORE
предупреждения происходят, а не ошибки, даже со строгим
sql_mode
,
и строка вставлены, используя то же самое поведение самого близкого значения,
используемое для не ограничивающих режимов SQL. Это происходит, потому что у
сервера нет никакого способа остановить передачу файла в середине работы.
TIMESTAMP
установлены в текущую дату и время, только если есть значение
NULL
для столбца (то есть, \N
) и столбец не
разрешает значения NULL
или если значение по умолчанию столбца
TIMESTAMP
текущий timestamp
и это опущено в полевом списке, когда полевой список определен.
LOAD DATA INFILE
воспринимает весь ввод как строки, таким образом, Вы не можете использовать
числовые значения для ENUM
или
SET
, как с
INSERT
. Все значения
ENUM
и
SET
должны быть
определены как строки.
Значения BIT
не могут быть загружены, используя двоичную запись (например,
b'011010'
). Чтобы работать вокруг этого, определите значения как
регулярные целые числа и используйте SET
, чтобы преобразовать их
так, чтобы MySQL выполнил числовое преобразование типа и загрузил их в
столбец BIT
должным образом:
shell> cat /tmp/bit_test.txt 2 127 shell> mysql test mysql> LOAD DATA INFILE '/tmp/bit_test.txt' -> INTO TABLE bit_test (@var1) SET b = CAST(@var1 AS UNSIGNED); Query OK, 2 rows affected (0.00 sec) Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 mysql> SELECT BIN(b+0) FROM bit_test; +----------+ | bin(b+0) | +----------+ | 10 | | 1111111 | +----------+ 2 rows in set (0.00 sec)В Unix, если
LOAD DATA
надо
читать из канала, Вы можете использовать следующий метод (пример загружает
каталог /
в таблицу db1.t1
):
mkfifo /mysql/data/db1/ls.dat chmod 666 /mysql/data/db1/ls.dat find / -ls > /mysql/data/db1/ls.dat & mysql -e "LOAD DATA INFILE 'ls.dat' INTO TABLE t1" db1Здесь Вы должны выполнить команду, которая производит данные, которые будут загружены и mysql на отдельных терминалах или выполнить процесс генерации данных в фоне (как показано в предыдущем примере). Если Вы не сделаете этого, то канал заблокируется, пока данные не считаны процессом mysql.
Когда LOAD DATA INFILE
завершится, это возвращает информационную строку в следующем формате:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0Предупреждения происходят при тех же самых обстоятельствах как когда значения вставлены, используя
INSERT
(см. раздел 14.2.5),
за исключением того, что LOAD DATA
INFILE
также производит предупреждения, когда есть слишком мало
или слишком много областей во входной строке.
Вы можете использовать SHOW WARNINGS
, чтобы получить список первых
max_error_count
предупреждений как информацию о том, что пошло не так, как надо. См.
раздел 14.7.5.40.
Если Вы используете C API, Вы можете получить информацию о запросе,
вызывая mysql_info()
. См.
раздел 25.8.7.36.
LOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name
' [REPLACE | IGNORE] INTO TABLE [db_name
.]tbl_name
[CHARACTER SETcharset_name
] [ROWS IDENTIFIED BY '<tagname
>'] [IGNOREnumber
{LINES | ROWS}] [(field_name_or_user_var
,...)] [SETcol_name
=expr
,...]
LOAD XML
читает данные из XML-файла в таблицу. file_name
должен быть дан как буквальная строка. tagname
в дополнительном ROWS IDENTIFIED BY
должен также быть дан как буквальная строка, и должен быть окружен
угловыми скобками (<
и >
).
LOAD XML
работает как дополнение выполнения
mysql
в режим вывода XML (то есть, запуская клиента с
--xml
).
Чтобы написать данные от таблицы в XML-файл, Вы можете вызвать
mysql с
опциями --xml
и
-e
:
shell> mysql --xml -e 'SELECT * FROM mydb.mytable' > file.xmlЧтобы считать файл назад в таблицу, надо использовать
LOAD XML INFILE
.
По умолчанию элемент <row>
является эквивалентом строки таблицы базы данных, это может быть изменено,
используя ROWS IDENTIFIED BY
.
Этот запрос поддерживает три различных формата XML:
Имена столбцов как признаки и значения столбцов как значения атрибута:
<row
column1
="value1
"column2
="value2
" .../>
<row
> <column1
>value1
</column1
> <column2
>value2
</column2
> </row
>
name
признаки тэгов
<field>
, значения как содержание этих тегов:
contents of these tags:
<row> <field name='Это формат, используемый другими инструментами MySQL, такими как mysqldump.column1
'>value1
</field> <field name='column2
'>value2
</field> </row>
Все три формата могут использоваться в том же самом XML-файле, подпрограмма импорта автоматически обнаруживает формат для каждой строки и интерпретирует это правильно. Теги являются соответствующими, основываясь на теге или названии атрибута и имени столбца.
Следующие пункты работают для
LOAD XML
по существу аналогично
LOAD DATA
:
LOW_PRIORITY
или CONCURRENT
LOCAL
REPLACE
или IGNORE
CHARACTER SET
SET
См. раздел 14.2.6.
(
список разделенных запятой значений одной или более областей XML или
пользовательских переменных. Название пользовательской переменной,
используемой с этой целью, должно соответствовать название области из
XML-файла с префиксом field_name_or_user_var
, ...)@
. Вы можете использовать имена полей,
чтобы выбрать только желаемые области. Пользовательские переменные могут
использоваться, чтобы сохранить соответствующие значения полей для
последующего повторного использования.
IGNORE
или number
LINESIGNORE
пропускает первые
number
ROWSnumber
строк в XML-файле. Это походит на
LOAD DATA
IGNORE ... LINES
.
Предположите, что нам назвали таблицу person
,
создаваемую как показано здесь:
USE test; CREATE TABLE person (person_id INT NOT NULL PRIMARY KEY, fname VARCHAR(40) NULL, lname VARCHAR(40) NULL, created TIMESTAMP);Предположите далее, что эта таблица первоначально пуста.
Теперь предположите, что у нас есть простой XML-файл
person.xml
, чье содержание показано здесь:
<list> <person person_id="1" fname="Kapek" lname="Sainnouine"/> <person person_id="2" fname="Sajon" lname="Rondela"/> <person person_id="3"><fname>Likame</fname><lname>ц√rrtmons</lname></person> <person person_id="4"><fname>Slar</fname><lname>Manlanth</lname></person> <person><field name="person_id">5</field><field name="fname">Stoma</field> <field name="lname">Milu</field></person> <person><field name="person_id">6</field><field name="fname">Nirtam</field> <field name="lname">Sklц╤d</field></person> <person person_id="7"><fname>Sungam</fname><lname>Dulbц╔d</lname></person> <person person_id="8" fname="Sraref" lname="Encmelt"/> </list>Каждый из допустимых форматов XML, обсужденных ранее, представлен в этом файле в качестве примера.
Импортировать данные из person.xml
в таблицу
person
можно так:
mysql> LOAD XML LOCAL INFILE 'person.xml' -> INTO TABLE person -> ROWS IDENTIFIED BY '<person>'; Query OK, 8 rows affected (0.00 sec) Records: 8 Deleted: 0 Skipped: 0 Warnings: 0Здесь мы принимаем, что
person.xml
расположен в каталоге данных MySQL. Если файл не может быть найден,
то будет ошибка:
ERROR 2 (HY000): File '/person.xml' not found (Errcode: 2)
ROWS IDENTIFIED BY '<person>'
означает, что каждый
элемент <person>
в XML-файле считают эквивалентным строке
в таблице, в которую должны быть импортированы данные. В этом случае это
таблица person
в базе данных test
.
Как видно из ответа по серверу, 8 строк были импортированы в таблицу
test.person
. Это может быть проверено простым
SELECT
:
mysql> SELECT * FROM person; +-----------+--------+------------+---------------------+ | person_id | fname | lname | created | +-----------+--------+------------+---------------------+ | 1 | Kapek | Sainnouine | 2007-07-13 16:18:47 | | 2 | Sajon | Rondela | 2007-07-13 16:18:47 | | 3 | Likame | ц√rrtmons | 2007-07-13 16:18:47 | | 4 | Slar | Manlanth | 2007-07-13 16:18:47 | | 5 | Stoma | Nilu | 2007-07-13 16:18:47 | | 6 | Nirtam | Sklц╤d | 2007-07-13 16:18:47 | | 7 | Sungam | Dulbц╔d | 2007-07-13 16:18:47 | | 8 | Sreraf | Encmelt | 2007-07-13 16:18:47 | +-----------+--------+------------+---------------------+ 8 rows in set (0.00 sec)Это показывает, как заявлено ранее в этом разделе, что любые из 3 форматов XML могут появиться в единственном файле и быть считаны при использовании
LOAD XML
.
Инверсия работы импорта то есть, вывод табличных данных MySQL в XML, может быть достигнута, используя mysql:
shell> mysql --xml -e "SELECT * FROM test.person" > person-dump.xml shell> cat person-dump.xml <?xml version="1.0"?> <resultset statement="SELECT * FROM test.person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <row> <field name="person_id">1</field> <field name="fname">Kapek</field> <field name="lname">Sainnouine</field> </row> <row> <field name="person_id">2</field> <field name="fname">Sajon</field> <field name="lname">Rondela</field> </row> <row> <field name="person_id">3</field> <field name="fname">Likema</field> <field name="lname">ц√rrtmons</field> </row> <row> <field name="person_id">4</field> <field name="fname">Slar</field> <field name="lname">Manlanth</field> </row> <row> <field name="person_id">5</field> <field name="fname">Stoma</field> <field name="lname">Nilu</field> </row> <row> <field name="person_id">6</field> <field name="fname">Nirtam</field> <field name="lname">Sklц╤d</field> </row> <row> <field name="person_id">7</field> <field name="fname">Sungam</field> <field name="lname">Dulbц╔d</field> </row> <row> <field name="person_id">8</field> <field name="fname">Sreraf</field> <field name="lname">Encmelt</field> </row> </resultset>
Опция --xml
предписывает клиенту mysql
использовать XML-формат для его вывода, опция
-e
заставляет клиента немедленно выполнить запрос SQL после опции. См.
раздел 5.5.1.
Вы можете проверить, что дамп допустим, создавая копию person
и импортируя файл дампа в новую таблицу:
mysql> USE test; mysql> CREATE TABLE person2 LIKE person; Query OK, 0 rows affected (0.00 sec) mysql> LOAD XML LOCAL INFILE 'person-dump.xml' INTO TABLE person2; Query OK, 8 rows affected (0.01 sec) Records: 8 Deleted: 0 Skipped: 0 Warnings: 0 mysql> SELECT * FROM person2; +-----------+--------+------------+---------------------+ | person_id | fname | lname | created | +-----------+--------+------------+---------------------+ | 1 | Kapek | Sainnouine | 2007-07-13 16:18:47 | | 2 | Sajon | Rondela | 2007-07-13 16:18:47 | | 3 | Likema | ц√rrtmons | 2007-07-13 16:18:47 | | 4 | Slar | Manlanth | 2007-07-13 16:18:47 | | 5 | Stoma | Nilu | 2007-07-13 16:18:47 | | 6 | Nirtam | Sklц╤d | 2007-07-13 16:18:47 | | 7 | Sungam | Dulbц╔d | 2007-07-13 16:18:47 | | 8 | Sreraf | Encmelt | 2007-07-13 16:18:47 | +-----------+--------+------------+---------------------+ 8 rows in set (0.00 sec)Нет никакого требования что каждая область в XML-файле быть соответствующей столбцу в соответствующей таблице. Пропущены области, у которых нет никаких соответствующих столбцов. Вы можете видеть это, опустошив таблицу
person2
и удалив столбец
created
, затем используйте тот же самый LOAD XML
:
mysql> TRUNCATE person2; Query OK, 8 rows affected (0.26 sec) mysql> ALTER TABLE person2 DROP COLUMN created; Query OK, 0 rows affected (0.52 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> SHOW CREATE TABLE person2\G *************************** 1. row *************************** Table: person2 Create Table: CREATE TABLE `person2` ( `person_id` int(11) NOT NULL, `fname` varchar(40) DEFAULT NULL, `lname` varchar(40) DEFAULT NULL, PRIMARY KEY (`person_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> LOAD XML LOCAL INFILE 'person-dump.xml' INTO TABLE person2; Query OK, 8 rows affected (0.01 sec) Records: 8 Deleted: 0 Skipped: 0 Warnings: 0 mysql> SELECT * FROM person2; +-----------+--------+------------+ | person_id | fname | lname | +-----------+--------+------------+ | 1 | Kapek | Sainnouine | | 2 | Sajon | Rondela | | 3 | Likema | ц√rrtmons | | 4 | Slar | Manlanth | | 5 | Stoma | Nilu | | 6 | Nirtam | Sklц╤d | | 7 | Sungam | Dulbц╔d | | 8 | Sreraf | Encmelt | +-----------+--------+------------+ 8 rows in set (0.00 sec)Порядок, в котором области даны в каждой строке XML-файла, не затрагивает работу
LOAD XML
, полевой порядок может измениться от строки до
строки, и не обязан быть в том же самом порядке, как
соответствующие столбцы в таблице.
Как упомянуто ранее, Вы можете использовать список из одной или более
областей XML (
(чтобы выбрать желаемые области только) или пользовательские
переменные (чтобы сохранить соответствующие значения полей для более позднего
использования). Пользовательские переменные могут быть особенно полезными,
когда Вы хотите вставить данные из XML-файла в столбцы таблицы, имена которых
не соответствуют таковым из областей XML. Чтобы видеть, как это работает, мы
сначала составляем таблицу field_name_or_user_var
, ...)
individual
, которая соответствует
структуре person
, но столбцы называются по-другому:
mysql> CREATE TABLE individual (individual_id INT NOT NULL PRIMARY KEY, -> name1 VARCHAR(40) NULL, -> name2 VARCHAR(40) NULL, made TIMESTAMP); Query OK, 0 rows affected (0.42 sec)В этом случае Вы не можете просто загрузить XML-файл непосредственно в таблицу, потому что имена полей и имена столбцов не соответствуют:
mysql> LOAD XML INFILE '../bin/person-dump.xml' INTO TABLE test.individual; ERROR 1263 (22004): Column set to default value; NULL supplied to NOT NULL column 'individual_id' at row 1Это происходит, потому что сервер MySQL ищет имена полей, соответствующие имена столбцов целевой таблицы. Вы можете работать вокруг этой проблемы, выбирая значения полей в пользовательские переменные, затем устанавливая столбцы целевой таблицы, равные значениям тех переменных, через использование
SET
. Вы можете выполнить обе эти операции в единственном
запросе, как показано здесь:
mysql> LOAD XML INFILE '../bin/person-dump.xml' -> INTO TABLE test.individual (@person_id, @fname, @lname, @created) -> SET individual_id=@person_id, name1=@fname, name2=@lname, made=@created; Query OK, 8 rows affected (0.05 sec) Records: 8 Deleted: 0 Skipped: 0 Warnings: 0 mysql> SELECT * FROM individual; +---------------+--------+------------+---------------------+ | individual_id | name1 | name2 | made | +---------------+--------+------------+---------------------+ | 1 | Kapek | Sainnouine | 2007-07-13 16:18:47 | | 2 | Sajon | Rondela | 2007-07-13 16:18:47 | | 3 | Likema | ц√rrtmons | 2007-07-13 16:18:47 | | 4 | Slar | Manlanth | 2007-07-13 16:18:47 | | 5 | Stoma | Nilu | 2007-07-13 16:18:47 | | 6 | Nirtam | Sklц╤d | 2007-07-13 16:18:47 | | 7 | Sungam | Dulbц╔d | 2007-07-13 16:18:47 | | 8 | Srraf | Encmelt | 2007-07-13 16:18:47 | +---------------+--------+------------+---------------------+ 8 rows in set (0.00 sec)Названия пользовательских переменных должны соответствовать таковым из соответствующих областей XML-файла с добавлением необходимого префикса
@
, чтобы указать, что это переменные.
Пользовательские переменные не должны быть перечислены или назначены в том же
самом порядке в качестве соответствующих областей.
Используя ROWS IDENTIFIED BY '<
возможно импортировать данные из того же самого XML-файла в
таблицы базы данных с различными определениями.
Для этого примера, предположите, что Вам назвали файл
tagname
>'address.xml
, который содержит следующий XML:
<?xml version="1.0"?> <list> <person person_id="1"> <fname>Robert</fname> <lname>Jones</lname> <address address_id="1" street="Mill Creek Road" zip="45365" city="Sidney"/> <address address_id="2" street="Main Street" zip="28681" city="Taylorsville"/> </person> <person person_id="2"> <fname>Mary</fname> <lname>Smith</lname> <address address_id="3" street="River Road" zip="80239" city="Denver"/> <!-- <address address_id="4" street="North Street" zip="37920" city="Knoxville"/> --> </person> </list>Вы можете снова использовать таблицу
test.person
как определено ранее в этом разделе, после очистки всех существующих
записей из таблицы и затем показа ее структуры как показано здесь:
mysql< TRUNCATE person; Query OK, 0 rows affected (0.04 sec) mysql< SHOW CREATE TABLE person\G *************************** 1. row *************************** Table: person Create Table: CREATE TABLE `person` ( `person_id` int(11) NOT NULL, `fname` varchar(40) DEFAULT NULL, `lname` varchar(40) DEFAULT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`person_id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 1 row in set (0.00 sec)Теперь создайте таблицу
address
в базе данных test
,
используя следующий запрос CREATE TABLE
:
CREATE TABLE address (address_id INT NOT NULL PRIMARY KEY, person_id INT NULL, street VARCHAR(40) NULL, zip INT NULL, city VARCHAR(40) NULL, created TIMESTAMP);Чтобы импортировать данные из XML-файла в
person
,
выполните следующий запрос LOAD XML
, который определяет, что строки должны быть
определены элементом <person>
;
mysql> LOAD XML LOCAL INFILE 'address.xml' -> INTO TABLE person -> ROWS IDENTIFIED BY '<person>'; Query OK, 2 rows affected (0.00 sec) Records: 2 Deleted: 0 Skipped: 0 Warnings: 0Вы можете проверить, что записи были импортированы, используя
SELECT
:
mysql> SELECT * FROM person; +-----------+--------+-------+---------------------+ | person_id | fname | lname | created | +-----------+--------+-------+---------------------+ | 1 | Robert | Jones | 2007-07-24 17:37:06 | | 2 | Mary | Smith | 2007-07-24 17:37:06 | +-----------+--------+-------+---------------------+ 2 rows in set (0.00 sec)Начиная с
<address>
у элементов в XML-файле нет никаких
соответствующих столбцов в person
, они пропущены.
Чтобы импортировать данные из элементов <address>
в таблицу address
, используйте
LOAD XML
так:
mysql> LOAD XML LOCAL INFILE 'address.xml' -> INTO TABLE address -> ROWS IDENTIFIED BY '<address>'; Query OK, 3 rows affected (0.00 sec) Records: 3 Deleted: 0 Skipped: 0 Warnings: 0Вы можете видеть, что данные были импортированы, используя такой запрос
SELECT
, как этот:
mysql> SELECT * FROM address; +------------+-----------+-----------------+-------+--------------+---------------------+ | address_id | person_id | street | zip | city | created | +------------+-----------+-----------------+-------+--------------+---------------------+ | 1 | 1 | Mill Creek Road | 45365 | Sidney | 2007-07-24 17:37:37 | | 2 | 1 | Main Street | 28681 | Taylorsville | 2007-07-24 17:37:37 | | 3 | 2 | River Road | 80239 | Denver | 2007-07-24 17:37:37 | +------------+-----------+-----------------+-------+--------------+---------------------+ 3 rows in set (0.00 sec)Данные из элемента
<address>
, который приложен в
XML-комментариях, не импортированы. Однако, начиная со столбца
person_id
в таблице address
,
значение person_id
от родительского элемента
<person>
для каждого <address>
импортировано в таблицу address
.
Соображения безопасности.
Как с LOAD DATA
,
передача XML-файла от хоста клиента до узла сервера начата сервером MySQL. В
теории исправленный сервер мог быть создан, который скажет программе клиента
передавать файл, выбранный сервером, а не файл, названный клиентом в
LOAD XML
.
Такой сервер мог получить доступ к любому файлу на хосте клиента, к которому
пользователь клиента имеет доступ.
В Web клиенты обычно соединяются с MySQL от веб-сервера. Пользователь,
который может выполнить любую команду сервера MySQL, может использовать
LOAD XML LOCAL
, чтобы
читать любые файлы, к которым процесс веб-сервера имеет доступ.
В этой окружающей среде клиент относительно сервера MySQL фактически
веб-сервер, а не удаленная программа, выполняемая пользователем, который
соединяется с веб-сервером.
Вы можете отключить загрузку XML-файлов от клиентов, запуская сервер с
опциецй --local-infile=0
или
--local-infile=OFF
. Эта опция может также использоваться, запуская
mysql,
чтобы выключить LOAD XML
для этого сеанса клиента.
Чтобы препятствовать тому, чтобы клиент загрузил XML-файлы из сервера, не
предоставляйте привилегию FILE
соответствующей учетной записи пользователя MySQL или отмените эту
привилегию, если у учетной записи пользователя клиента она уже есть.
Отмена привилегии FILE
(или не предоставление этого) не даст пользователю выполнять только
LOAD XML INFILE
(так же как LOAD_FILE()
), это не препятствует тому, чтобы пользователь
выполнил LOAD XML LOCAL INFILE
.
Чтобы отвергнуть этот запрос, Вы должны запустить сервер или клиента с
опцией --local-infile=OFF
.
Другими словами, привилегия FILE
затрагивает только, может ли клиент читать файлы на сервере,
у этого нет никакого действия, может ли клиент считать файлы в
местной файловой системе.
Для разделенных таблиц, используя механизмы хранения, которые используют
табличные блокировки, например,
MyISAM
, любые блокировки, вызванные LOAD XML
,
блокируют все разделы таблицы. Это не относится к таблицам, использующим
механизмы хранения, которые используют блокировку на уровне строки, например,
InnoDB
. См.
Partitioning and Locking.
REPLACE [LOW_PRIORITY | DELAYED] [INTO]Или:tbl_name
[PARTITION (partition_name
,...)] [(col_name
,...)] {VALUES | VALUE} ({expr
| DEFAULT},...),(...),...
REPLACE [LOW_PRIORITY | DELAYED] [INTO]Или:tbl_name
[PARTITION (partition_name
,...)] SETcol_name
={expr
| DEFAULT}, ...
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
[PARTITION (partition_name
,...)] [(col_name
,...)] SELECT ...
REPLACE
работает точно как
INSERT
, за исключением того, что,
если у старой строки в таблице есть то же самое значение, как новая строка
для PRIMARY KEY
или индекса UNIQUE
,
старая строка удалена прежде, чем новая строка вставлена. См.
раздел 14.2.5.
REPLACE
это
расширение MySQL к стандарту SQL. Это вставляет или удаляет
и вставляет. Для другого расширения MySQL к стандарту SQL, которое
вставляет или обноввляет, см.
раздел 14.2.5.3.
DELAYED
вставки и замены устарели в
MySQL 5.6.6. В MySQL 8.0 DELAYED
не работает.
Сервер признает, но игнорирует DELAYED
,
обрабатывает замену как неотсроченную замену, и производит предупреждение
ER_WARN_LEGACY_SYNTAX_CONVERTED
(REPLACE DELAYED is
no longer supported. The statement was converted to REPLACE).
DELAYED
будет удалено в будущем выпуске.
REPLACE
имеет смысл, только если у таблицы есть
PRIMARY KEY
или индекс UNIQUE
.
Иначе это становится эквивалентным
INSERT
, потому что нет индекса,
чтобы определить, дублирует ли новая строка другую.
Значения для всех столбцов взяты от значений, определенных в
REPLACE
.
Любые недостающие столбцы установлены в их значения по умолчанию, как это
происходит для INSERT
.
Вы не можете обратиться к значениям от текущей строки и использовать их в
новой строке. Если Вы используете такое назначение, как
SET
, ссылка на имя столбца на правой стороне обработана как
col_name
= col_name
+1
DEFAULT(
, таким образом, назначение эквивалентно
col_name
)SET
.col_name
=
DEFAULT(col_name
) + 1
Если произведенный столбец заменен явно, единственное разрешенное значение
DEFAULT
. Для информации о произведенных столбцах см.
раздел 14.1.15.5.
Чтобы использовать REPLACE
,
у Вас должны быть обе привилегии
INSERT
и
DELETE
для таблицы.
REPLACE
поддерживает явный выбор раздела, используя
PARTITION
со списком разделенных запятой значений названий
разделов, подразделов или обоих. Как с INSERT
, если не возможно вставить новую строку в какой-либо раздел или
подраздел, REPLACE
терпит неудачу с ошибкой Found a row
not matching the given partition set. См.
раздел 20.5.
REPLACE
возвращает количество,
чтобы указать на число затронутых строк. Это сумма удаленных и вставленных
строк. Если количество 1 для однострочного
REPLACE
,
строка была вставлена, но никакие строки не были удалены. Если количество
больше 1, одна или более старых строк были удалены прежде, чем новая строка
была вставлена. Для единственной строки возможно заменить больше, чем одну
старую строку, если таблица содержит много уникальных индексов, и новые
значения дубликатов строки для различных старых строк в
разных уникальных индексах.
Количество затронутых строк облегчает определение того, что
REPLACE
только добавил строку или
заменял также какие-либо строки: проверьте, является ли счетчик 1 (добавил)
или больше (заменил).
Если Вы используете C API, количество затронутых строк может быть
получено, используя
mysql_affected_rows()
.
Вы не можете заменять в таблице и выбрать из той же самой таблицы в подзапросе.
MySQL использует следующий алгоритм для
REPLACE
(и
LOAD DATA ... REPLACE
):
Попытайтесь вставить новую строку в таблицу.
Удалите из таблицы противоречивую строку, у которой есть дублирующее значение ключа.
Возможно, что в случае
ключевой ошибки, механизм хранения может обработать
REPLACE
как обновление, а не удаление плюс вставка, но семантика
та же самая. Нет никаких видимых пользователем эффектов, кроме возможной
разницы в том, как механизм хранения постепенно увеличивает переменную
Handler_
.xxx
Поскольку результаты REPLACE ... SELECT
зависят от упорядочивания строк из SELECT
, и этот порядок не может всегда гарантироваться, возможно,
регистрируя эти запросы для ведущего и ведомого устройств получить разный
порядок. Поэтому REPLACE ... SELECT
отмечены как опасный для основанной на запросе репликации. С этим изменением
такие запросы производят предупреждение в журнале, используя
двоичной режим журналирования STATEMENT
и зарегистрированы,
используя основанный на строке формат, используя режим MIXED
.
См. раздел 19.2.1.1.
Изменяя существующую таблицу, которая не разделена, чтобы добавить
разделение или изменяя разделение уже разделенной таблицы, Вы можете
рассмотреть изменение первичного ключа таблицы (см.
раздел 20.6.1). Вы должны знать что, если Вы делаете это, результаты
REPLACE
могут быть затронуты, как если бы Вы изменили первичный
ключ неразделенной таблицы. Считайте таблицу создаваемой следующим
запросом CREATE TABLE
:
CREATE TABLE test (id INT UNSIGNED NOT NULL AUTO_INCREMENT, data VARCHAR(64) DEFAULT NULL, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id));Когда мы составляем эту таблицу и выполняем запросы, показанные в клиенте mysql, результаты следующие:
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00'); Query OK, 1 row affected (0.04 sec) mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42'); Query OK, 2 rows affected (0.04 sec) mysql> SELECT * FROM test; +----+------+---------------------+ | id | data | ts | +----+------+---------------------+ | 1 | New | 2014-08-20 18:47:42 | +----+------+---------------------+ 1 row in set (0.00 sec)Теперь мы составляем вторую таблицу, почти идентичную первой , за исключением того, что первичный ключ теперь покрывает 2 столбца, как показано здесь (подчеркнутый текст):
CREATE TABLE test2 (id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(64) DEFAULT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON
UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id, ts));
Когда мы работаем с test2
, те же самые два
REPLACE
, как мы сделали на оригинальной таблице
test
, дают различный результат:
mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00'); Query OK, 1 row affected (0.05 sec) mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42'); Query OK, 1 row affected (0.06 sec) mysql> SELECT * FROM test2; +----+------+---------------------+ | id | data | ts | +----+------+---------------------+ | 1 | Old | 2014-08-20 18:47:00 | | 1 | New | 2014-08-20 18:47:42 | +----+------+---------------------+ 2 rows in set (0.00 sec)Это потому, что значения столбцов
id
и ts
должны
соответствовать таковым из существующей строки для строки, которая будет
заменена, иначе строка вставлена.
В MySQL 8.0 REPLACE
, затрагивающий разделенную таблицу,
используя механизм хранения подобный
MyISAM
,
блокирует на уровне таблицы только раздел, содержащий строки, которые
соответствуют параметру WHERE
в REPLACE
, пока ни
один из столбцов раздела таблицы не обновлен,
иначе вся таблица заблокирована. Для механизмов хранения вроде
InnoDB
с
блокировкой на уровне строки, никакой блокировки раздела нет. См.
Partitioning and Locking.
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [MAX_STATEMENT_TIME =N
] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr
[,select_expr
...] [FROMtable_references
[PARTITIONpartition_list
] [WHEREwhere_condition
] [GROUP BY {col_name
|expr
|position
} [ASC | DESC], ... [WITH ROLLUP]] [HAVINGwhere_condition
] [ORDER BY {col_name
|expr
|position
} [ASC | DESC], ...] [LIMIT {[offset
,]row_count
|row_count
OFFSEToffset
}] [PROCEDUREprocedure_name
(argument_list
)] [INTO OUTFILE 'file_name
' [CHARACTER SETcharset_name
]export_options
| INTO DUMPFILE 'file_name
' | INTOvar_name
[,var_name
]] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
используется, чтобы получить строки, выбранные из одной или более таблиц, и
может включать UNION
и подзапросы.
См. разделы 14.2.9.3 и
14.2.10.
Обычно используемые параметры
SELECT
:
Каждый select_expr
указывает на столбец, который Вы хотите получить. Должен быть по крайней
мере один select_expr
.
table_references
указывает на таблицу или таблицы,
из которых нужно получить строки. Его синтаксис описан в
разделе 14.2.9.2.SELECT
поддерживает явный выбор раздела, используя
PARTITION
со списком разделов или подраздов (или обоих) после
названия таблицы в table_reference
(см.
раздел 14.2.9.2). В этом случае строки выбраны
только из перечисленного раздела, и любой другой раздел таблицы
проигнорирован. Для получения дополнительной информации и примеров см.
раздел 20.5.
SELECT ... PARTITION
от таблиц, используя механизмы хранения
вроде MyISAM
,
который выполняет блокировки на уровне таблицы (и таким образом блокировки
разделов), блокирует только разделы или подразделы,
названные в опции PARTITION
.
WHERE
, если есть, указывает на условие или условия, которым
строки должны удовлетворять, чтобы быть выбранными.
where_condition
выражение, которое оценивается
к истине для каждой строки, которая будет выбрана. Запрос выбирает все
строки, если нет WHERE
.
В WHERE
Вы можете использовать любую из функций и операторов,
которые MySQL поддерживает, за исключением совокупных (итоговых) функций. См.
раздел 10.5 и
главу 13.
SELECT
может также использоваться, чтобы получить строки, вычисленные независимо
от любой таблицы.
Например:
mysql> SELECT 1 + 1; -> 2Вам разрешают определить
DUAL
как фиктивное имя таблицы в
ситуациях, где ни на какие таблицы не ссылаются:
mysql> SELECT 1 + 1 FROM DUAL; -> 2
DUAL
просто для удобства людей, которые требуют, что все
запросы SELECT
должны иметь FROM
и, возможно, другие параметры. MySQL
может проигнорировать параметры. MySQL не требует FROM DUAL
,
если ни на какие таблицы не ссылаются.
Вообще, используемые пункты должны быть поданы точно в порядке, показанном
в описании синтаксиса. Например, HAVING
должен быть после любого
GROUP BY
и перед любым ORDER BY
.
Исключение то, что INTO
может появиться как показано в описании
синтаксиса или немедленно после списка select_expr
.
См. раздел 14.2.9.1.
Список select_expr
включают избранный список,
который указывает, которые столбцы получить. Это определяет столбец или
выражение или может использовать *
-сокращения:
Список, состоящий только из *
может использоваться, чтобы выбрать все столбцы из всех таблиц:
SELECT * FROM t1 INNER JOIN t2 ...
tbl_name
.*
может использоваться, чтобы выбрать все столбцы из названной таблицы:
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
*
с другими элементами в избранном списке
может произвести ошибку разбора. Чтобы избежать этой проблемы, используйте
tbl_name
.*
:
SELECT AVG(score), t1.* FROM t1 ...
Следующий список обеспечивает дополнительную информацию о
других параметрах SELECT
:
select_expr
может быть дан использованием
псевдонима AS
.
Псевдоним используется в качестве имени столбца выражения и может
использоваться в alias_name
GROUP BY
,
ORDER BY
или HAVING
:
SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
AS
является дополнительным, когда совмещение имен
select_expr
с идентификатором. Предыдущий пример может
быть написан так:
SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;Однако, потому что
AS
является дополнительным, тонкая проблема
может произойти, если Вы забываете запятую между двумя
select_expr
: MySQL интерпретирует второе как имя
псевдонима. Например, в следующем запросе, columnb
обработан как имя псевдонима:
SELECT columna columnb FROM mytable;Поэтому хорошая практика иметь привычку использовать
AS
явно, определяя псевдонимы столбца.
Недопустимо обратиться к псевдониму столбца в WHERE
,
потому что значение столбца еще не могло бы быть определено, когда
WHERE
выполнен, см.
раздел B.5.4.4.
FROM table_references
указывает на таблицу или таблицы, из которых можно получить строки. Если Вы
называете больше, чем одну таблицу, Вы выполняете соединение. Для информации
о синтаксисе соединения см. раздел 14.2.9.2.
Для каждой определенной таблицы Вы можете произвольно определить псевдоним.
tbl_name
[[AS]alias
] [index_hint
]
Использование индексной подсказки предоставляет оптимизатору информацию о том, как выбрать индекс во время обработки запроса. Для описания синтаксиса, чтобы определить эти подсказки см. раздел 9.9.4.
Вы можете использовать SET
max_seeks_for_key=
как альтернативный способ вынудить MySQL предпочесть просмотр ключей вместо
сканирования таблицы. См. раздел
6.1.5.value
tbl_name
или как
db_name
.tbl_name
,
чтобы определить базу данных явно. Вы можете обратиться к столбцу как
col_name
,
tbl_name
.col_name
или
db_name
.tbl_name
.
col_name
. Вы не должны определить префикс
tbl_name
или db_name
.
tbl_name
для ссылки на столбец, если ссылка не была бы
неоднозначна. См. раздел 10.2.1.
tbl_name
AS
alias_name
или
tbl_name alias_name
:
SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
ORDER BY
и GROUP BY
,
используя имена столбцов, псевдонимы столбца или позиции столбца. Позиции
столбца это целые числа и начинаются с 1:
SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;Чтобы сортировать в обратном порядке, добавьте
DESC
к названию столбца в ORDER BY
, которым Вы сортируете. Значение
по умолчанию: порядок по возрастанию, это может быть определено
явно, используя ASC
.
Если ORDER BY
происходит в пределах подзапроса и также
применен во внешнем запросе, наиболее удаленный ORDER BY
имеет приоритет. Например, результаты следующего запроса отсортированы в
порядке убывания, а не по возрастанию:
(SELECT ... ORDER BY a) ORDER BY a DESC;Использование позиций столбца устарело, потому что синтаксис был удален из стандарта SQL.
GROUP BY
, выходные строки сортированы
согласно GROUP BY
, как будто Вы имели ORDER BY
для
тех же самых столбцов. Чтобы избегать повторной сортировки
этого GROUP BY
, добавьте ORDER BY NULL
:
SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;Доверие неявному
GROUP BY
в MySQL 8.0 устарело.
Чтобы достигнуть определенного порядка сортировки сгруппированных
результатов, предпочтительно использовать явное ORDER BY
.
Сортировка GROUP BY
это расширение MySQL, которое может
измениться в будущем выпуске, например, чтобы позволить оптимизатору
упорядочить группировки в любой манере, которую он считает самой эффективной
и избегать издержек сортировки.GROUP BY
так, чтобы Вы могли также определить ASC
и DESC
после того, как назвали столбцы:
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC;
GROUP BY
, чтобы разрешить
выбирать области, которые не упомянуты в GROUP BY
.
Если Вы не получаете результаты, которые Вы ожидаете от своего запроса,
читайте описание GROUP BY
разделе 13.19.GROUP BY
позволяет модификатор WITH ROLLUP
.
См. раздел 13.19.2.HAVING
применен почти последним, непосредственно
перед тем, как элементы посылают клиенту, без оптимизации. LIMIT
применен после HAVING
.
SQL требует, что HAVING
должен сослаться только на столбцы в
GROUP BY
или столбцы, которые используются в совокупных
функциях. Однако, MySQL поддерживает расширение к этому поведению и разрешает
HAVING
обратиться к столбцам в
SELECT
и столбцам во внешних подзапросах также.
Если HAVING
относится к столбцу, который неоднозначен,
предупреждение происходит. В следующем запросе col2
неоднозначно, потому что это используется в качестве псевдонима и в
качестве имени столбца:
SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;Предпочтение отдано стандартному поведению SQL, так если имя столбца
HAVING
используется в GROUP BY
и как
псевдоним столбца в выходном списке столбца, предпочтение отдано
столбцу в GROUP BY
.HAVING
для элементов, которые должны
быть в WHERE
. Например, не пишите следующее:
SELECTПишите это так:col_name
FROMtbl_name
HAVINGcol_name
> 0;
SELECTcol_name
FROMtbl_name
WHEREcol_name
> 0;
HAVING
может отнестись к совокупным функциям, которые
WHERE
не может:
SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;Это не работало в некоторых более старых версиях MySQL.
select_expr
с тем же самым именем. Это расширение к стандартному SQL. Поскольку MySQL
также разрешает GROUP BY
и HAVING
обратиться к
select_expr
, это может привести к двусмысленности:
SELECT 12 AS a, a FROM t GROUP BY a;В этом запросе у обоих столбцов есть имя
a
. Чтобы гарантировать,
что правильный столбец используется для того, чтобы сгруппировать,
используйте различные имена для каждого select_expr
.
ORDER BY
ища в select_expr
,
затем в столбцах таблиц в FROM
.
Для GROUP BY
или HAVING
это ищет FROM
прежде, чем искать в
select_expr
. Для GROUP BY
и
HAVING
это отличается от pre-MySQL 5.0, которые использовали те
же самые правила, что касаются ORDER BY
.LIMIT
может использоваться, чтобы ограничить число строк,
возвращенных SELECT
.
LIMIT
берет один или два числовых параметра, которые должны оба
быть неотрицательными константами целого числа, с этими исключениями:
В пределах готовых запросов LIMIT
параметры могут
быть определены, используя маркеры заполнителя ?
.
LIMIT
параметры могут быть определены, используя оцененные к целому числу
обычные параметры или местные переменные.С двумя параметрами первый параметр определяет смещение первой строки, чтобы возвратить, второе определяет максимальное количество строк, чтобы возвратить. Смещение начальной строки 0 (не 1):
SELECT * FROM tbl LIMIT 5,10; # Вернет строки 6-15Чтобы получить все строки от определенного смещения до конца набора результатов, Вы можете использовать некоторое большое количество для второго параметра. Это запрос получает все строки от 96-ой строки до последней:
SELECT * FROM tbl LIMIT 95,18446744073709551615;С одним параметром значение определяет число строк, чтобы возвратить с начала набора результатов:
SELECT * FROM tbl LIMIT 5; # Вернет первые 5 строкДругими словами,
LIMIT row_count
эквивалентно LIMIT 0, row_count
.
Для готовых запросов Вы можете использовать заполнители. Следующие
запросы возвратят одну строку из tbl
:
SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;Следующие запросы возвратят строки 2-6 из
tbl
:
SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;Для совместимости с PostgreSQL MySQL также поддерживает синтаксис
LIMIT row_count
OFFSET
offset
.
Если LIMIT
происходит в пределах подзапроса и также применен
во внешнем запросе, наиболее удаленный LIMIT
имеет приоритет. Например, следующий запрос производит две строки, не одну:
(SELECT ... LIMIT 1) LIMIT 2;
PROCEDURE
вызывает процедуру, которая должна обработать
данные в наборе результатов. Для примера см.
раздел 9.4.2.4,
который описывает ANALYSE
, процедуру, которая может
использоваться, чтобы получить предложения для оптимальных типов данных
столбца, которые могут помочь уменьшить табличные размеры.
PROCEDURE
не разрешен в
UNION
.
SELECT ... INTO
позволяет результату запроса быть записанным в файл или сохранится в
переменных. Для получения дополнительной информации см.
раздел 14.2.9.1.FOR UPDATE
с механизмом хранения,
который использует блокировку страницы или строки, строки, исследованные
запросом, блокированы на запись до конца текущей транзакции. Использование
LOCK IN SHARE MODE
устанавливает совместно используемую
блокировку, которая разрешает другим транзакциям читать исследованные строки,
но не обновлять или удалять их. См.
раздел 16.5.2.4.
Кроме того, Вы не можете использовать FOR UPDATE
как часть
SELECT
в таком запросе, как
CREATE
TABLE
.
Если Вы пытаетесь сделать так, запрос отклонен с ошибкой
Can't update table 'new_table
SELECT ... FROM
old_table
...old_table
' while
'new_table
' is being created.
Это изменение в поведении MySQL 5.5 и ранее, который разрешал
CREATE TABLE ... SELECT
, чтобы произвести изменения в таблицах кроме составленной таблицы.
После SELECT
Вы можете использовать много опций, которые затрагивают работу запроса.
HIGH_PRIORITY
, MAX_STATEMENT_TIME
,
STRAIGHT_JOIN
и опции SQL_
это
расширения MySQL к стандартному SQL.
ALL
и DISTINCT
определяют, должны ли дублирующиеся строки быть возвращены.
ALL
(значение по умолчанию), определяет, что все строки
соответствия должны быть возвращены, включая дубликаты.
DISTINCT
определяет удаление дублирующихся строк из набора
результатов. Ошибка определить обе опции.
DISTINCTROW
синоним для DISTINCT
.
HIGH_PRIORITY
дает SELECT
более высокий приоритет, чем запросу, который обновляет таблицу.
Вы должны использовать это только для запросов, которые очень быстры и должны
быть сделаны сразу. SELECT HIGH_PRIORITY
блокирует таблицу для чтения, даже если есть запрос обновления, ждущий
таблицу. Это затрагивает только механизмы хранения, которые используют только
блокировку на уровне таблицы
(MyISAM
, MEMORY
и MERGE
).
HIGH_PRIORITY
не может использоваться с
SELECT
,
которые являются частью UNION
.
STRAIGHT_JOIN
вынуждает оптимизатор присоединять таблицы в
порядке, в котором они перечислены в FROM
.
Вы можете использовать это, чтобы ускорить запрос, если оптимизатор
присоединяет таблицы в неоптимальном порядке.
STRAIGHT_JOIN
также может использоваться в
table_references
. См.
раздел 14.2.9.2.
STRAIGHT_JOIN
не относится ни к какой таблице, которую
оптимизатор обрабатывает как
const
или system
. Такая таблица производит единственную строку, считанную во время
фазы оптимизации выполнения запроса, и ссылки на ее столбцы заменены
соответствующими значениями столбцов прежде, чем выполнение запроса
продолжится. Эти таблицы будут казаться первыми в плане запроса, выведенном
на экран EXPLAIN
. См.
раздел 9.8.1.
Это исключение, возможно, не относится к таблицам
const
или
system
, которые
используются на NULL
-стороне
внешнего соединения (то есть, таблица правой стороны в LEFT JOIN
или таблица левой стороны в RIGHT JOIN
.
SQL_BIG_RESULT
или SQL_SMALL_RESULT
может использоваться с GROUP BY
или DISTINCT
, чтобы
сказать оптимизатору, что набор результатов имеет много строк или является
небольшим, соответственно. Для SQL_BIG_RESULT
MySQL
непосредственно использует основанные на диске временные таблицы, если нужно,
и предпочитает сортировать с использованием временной таблицы с ключом
элементы GROUP BY
. Для SQL_SMALL_RESULT
MySQL
использует быстрые временные таблицы, чтобы сохранить получающуюся таблицу
вместо того, чтобы использовать сортировку. Это не должно
обычно быть необходимо.SQL_BUFFER_RESULT
вынуждает результат быть помещенным во
временную таблицу. Это помогает MySQL освободить табличные блокировки рано и
помогает в случаях, где требуется много времени, чтобы послать набор
результатов клиенту. Эта опция может использоваться только для верхнего
уровня SELECT
, не для подзапросов
или после UNION
.SQL_CALC_FOUND_ROWS
говорит MySQL вычислять сколько строк
было бы в наборе результатов, игнорируя любой LIMIT
.
Число строк может тогда быть получено с SELECT FOUND_ROWS()
. См.
раздел 13.14.SQL_CACHE
и SQL_NO_CACHE
влияют на кэширование результатов запроса в кэше запроса (см.
раздел 9.10.3). SQL_CACHE
говорит MySQL хранить результат в кэше запроса, если это кэшируемо и значение
query_cache_type
2
или DEMAND
. С SQL_NO_CACHE
сервер не использует кэш запроса. Это не проверяет кэш запроса, чтобы видеть,
кэшировал ли результат уже, и при этом не кэширует результат запроса.
Эти две опции являются взаимоисключающими, и ошибка происходит, если они
обе определены. Кроме того, эти опции не разрешены в подзапросах (включая
подзапросы в FROM
), и SELECT
в объединениях кроме первого
SELECT
.
Для представлений SQL_NO_CACHE
применяется, если это появляется в каком-либо
SELECT
в запросе. Для кэшируемого
запроса SQL_CACHE
применяется, если это появляется в первом
SELECT
из представления, упомянутого запросом.
В MySQL 8.0 SELECT
из разделенной таблицы, используя такой
механизм хранения, как
MyISAM
, блокируется только раздел, содержащий строки, которые
соответствуют параметру WHERE
в SELECT
.
Это не происходит с механизмами хранения вроде
InnoDB
, которые используют блокировку на уровне строки. См.
Partitioning and Locking.
SELECT ... INTO
позволяет результату запроса быть сохраненным в переменных или файле:
SELECT ... INTO
выбирает значения столбцов и хранит их в переменных.var_list
SELECT ... INTO OUTFILE
пишет выбранные строки в файл.
Столбец и разделители строки могут быть определены, чтобы произвести
определенный выходной формат.SELECT ... INTO DUMPFILE
пишет
единственную строку в файл без форматирования.SELECT
(см. раздел 14.2.9) показывает INTO
около конца запроса. Также возможно использовать INTO
немедленно
после select_expr
.
INTO
не должен использоваться во вложенном
SELECT
потому что такой
SELECT
должен возвратить его результат к внешнему контексту.
INTO
может назвать список из одной или более переменных,
которые могут быть определяемыми пользователем переменными, параметрами
хранимой процедуры или функции или местными переменными сохраненной
программы. В пределах готового SELECT ... INTO OUTFILE
только определяемые пользователем переменные разрешены, см.
раздел 14.6.4.2.
Выбранные значения назначены на переменные. Число переменных должно
соответствовать числу столбцов. Запрос должен возвратить единственную строку.
Если запрос не возвращает строк, происходит предупреждение с кодом ошибки
1329 (No data
), и значения переменных остаются неизменными. Если
запрос возвращает много строк, происходит ошибка (Result consisted of
more than one row
). Если возможно, что запрос может получить много
строк, Вы можете использовать LIMIT 1
, чтобы
ограничить набор результатов единственной строкой.
SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;Пользовательские имена переменных не являются чувствительными к регистру. См. раздел 10.4.
SELECT ... INTO
OUTFILE '
пишет выбранные строки в файл. Файл создается на сервере, таким образом, Вы
должны иметь привилегию file_name
'FILE
. file_name
не может быть существующим файлом.
character_set_filesystem
управляет интерпретацией имени файла.
SELECT ... INTO OUTFILE
предназначено прежде всего, чтобы позволить Вам очень быстро выводить таблицу
в текстовый файл на машине сервера. Если Вы хотите создать получающийся файл
на некотором другом хосте, чем сервер, Вы обычно не можете использовать
SELECT ... INTO OUTFILE
.
Однако, если клиентское программное обеспечение MySQL установлено на
удаленной машине, Вы можете вместо этого использовать команду клиента
mysql -e "SELECT ..." >
,
чтобы произвести файл на хосте клиента.file_name
Также возможно создать получающийся файл на ином хосте кроме сервера, если к местоположению файла на удаленном хосте можно получить доступ, используя отображенный на сеть путь в файловой системе сервера. В этом случае присутствие mysql не требуется на целевом хосте.
SELECT ... INTO OUTFILE
дополнение LOAD DATA INFILE
.
Значения столбцов записаны преобразованными в набор символов, определенный в
CHARACTER SET
. Если никакой такой пункт не присутствует,
значения выведены, используя binary
.
В действительности нет никакого преобразования набора символов. Если набор
результатов будет содержать столбцы в нескольких наборах символов, то файл
выходных данных будет такой же, и Вы не можете перезагрузить файл правильно.
Синтаксис для export_options
состоит из тех же самых
FIELDS
и LINES
из
LOAD DATA INFILE
. См.
раздел 14.2.6.
FIELDS ESCAPED BY
управляет, как написать специальные
символы. Если FIELDS ESCAPED BY
не пуст, он используется, когда
необходимо избежать двусмысленности как префикс, который предшествует
следующим символам в выводе:
FIELDS ESCAPED BY
.
FIELDS [OPTIONALLY] ENCLOSED BY
.FIELDS TERMINATED BY
и
LINES TERMINATED BY
.NUL
(нулевой байт, то, что фактически написано после
символа ESC, является ASCII 0
).FIELDS TERMINATED BY
, ENCLOSED BY
,
ESCAPED BY
или LINES TERMINATED BY
нужно экранировать, чтобы Вы могли читать файл назад.
Получающийся файл не должен соответствовать синтаксису SQL, таким образом, ничто иное не должно быть экранировано.
Если FIELDS ESCAPED BY
символ пуст, никакие символы не
экранируются, NULL
в выводе будет
NULL
, не \N
. Вероятно, не хорошая идея определить
пустой символ ESC, особенно если значения полей в Ваших данных содержат
какой-либо из символов в списке.
Вот пример, который производит файл с отделенными запятыми значениями (формат CSV), используемый многими программами:
SELECT a, b, a+b INTO OUTFILE '/tmp/result.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;
Если Вы используете INTO DUMPFILE
вместо
INTO OUTFILE
, MySQL пишет только одну строку в файл, без любого
столбца или завершения строки и не выполняя обработки escape. Это полезно,
если Вы хотите сохранить BLOB
в файл.
Любой файл, создаваемый INTO OUTFILE
или
INTO DUMPFILE
перезаписываем всеми пользователями на сервере.
Причина этого состоит в том, что сервер MySQL не может создать файл, который
принадлежит никому, кроме пользователя, от учетной записи которого он
работает. Вы никогда не должны выполнять
mysqld как root
.
Файл таким образом должен быть перезаписываемым всеми, чтобы Вы могли
управлять его содержанием.
Если secure_file_priv
установлена в непустое имя каталога, файл, который будет написан,
должен быть расположен в том каталоге.
В контексте SELECT ... INTO
запросы, которые происходят как часть событий, запущенных Планировщиком
Событий, сообщения диагностики (не только ошибки, но также и предупреждения)
написаны в журнал ошибок и в Windows в журнал событий приложения. Для
дополнительной информации см. раздел
21.4.5.
MySQL поддерживает следующие синтаксисы JOIN
для
части table_references
в
SELECT
и мультитабличных
DELETE
и
UPDATE
:
Табличная ссылка также известна как выражение соединения.table_references:
escaped_table_reference
[,escaped_table_reference
] ...escaped_table_reference
:table_reference
| { OJtable_reference
}table_reference
:table_factor
|join_table
table_factor
:tbl_name
[PARTITION (partition_names
)] [[AS]alias
] [index_hint_list
] |table_subquery
[AS]alias
| (table_references
)join_table
:table_reference
[INNER | CROSS] JOINtable_factor
[join_condition
] |table_reference
STRAIGHT_JOINtable_factor
|table_reference
STRAIGHT_JOINtable_factor
ONconditional_expr
|table_reference
{LEFT|RIGHT} [OUTER] JOINtable_reference
join_condition
|table_reference
NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOINtable_factor
join_condition
: ONconditional_expr
| USING (column_list
)index_hint_list
:index_hint
[,index_hint
] ...index_hint
: USE {INDEX|KEY} [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list
]) | IGNORE {INDEX|KEY} [FOR {JOIN|ORDER BY|GROUP BY}] (index_list
) | FORCE {INDEX|KEY} [FOR {JOIN|ORDER BY|GROUP BY}] (index_list
)index_list
:index_name
[,index_name
] ...
Табличная ссылка (когда это обращается к разделенной таблице) может
содержать PARTITION
, включая список разделенных запятой значений
разделов. Эта опция следует за названием таблицы и предшествует любой
декларации псевдонима. Эффект этой опции состоит в том, что строки выбраны
только из перечисленного раздела. Другими словами, любой раздел или
подраздел, не названный в списке, проигнорирован. Для получения
дополнительной информации см.
раздел 20.5.
Синтаксис table_factor
расширен по сравнению со
стандартом SQL. Последний принимает только table_reference
, а не список в круглых скобках.
Это консервативное расширение, если мы рассматриваем каждую запятую в
списке table_reference
как эквивалент внутреннему соединению. Например:
SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)аналогично вот этому:
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)В MySQL
JOIN
, CROSS JOIN
и INNER JOIN
синтаксические эквиваленты (они могут заменить друг друга). В стандартном SQL
они не эквивалентны. INNER JOIN
используется с
ON
, CROSS JOIN
иначе.
Вообще, круглые скобки могут быть проигнорированы в выражениях соединения, содержащих только внутренние операции соединения. MySQL также поддерживает вложенные соединения (см. раздел 9.2.1.11).
Индексные подсказки могут быть определены, чтобы затронуть, как оптимизатор MySQL использует индекс. Для получения дополнительной информации см. раздел 9.9.4.
Следующий список описывает общие факторы, чтобы принять во внимание при написании соединений.
Табличная ссылка может быть использованием псевдонима
или
tbl_name
AS
alias_name
tbl_name alias_name
:
SELECT t1.name, t2.salary FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
table_subquery
также известен как подзапрос в
FROM
. Такие подзапросы должны включать
псевдоним, чтобы дать результату подзапроса имя таблицы. Тривиальный пример
следует, см. также раздел 14.2.10.8
.
SELECT * FROM (SELECT 1, 2, 3) AS t1;
INNER JOIN
и запятая (,
)
семантически эквивалентны в отсутствие условия соединения: оба производят
объединение между указанными таблицами (то есть, каждая строка в первой
таблице соединена с каждой строкой во второй таблице).
Однако, приоритет оператора запятой меньше, чем
INNER JOIN
, CROSS JOIN
, LEFT JOIN
и
и т.д. Если Вы смешиваете соединения запятой с другими типами соединения,
когда есть условие соединения, может произойти ошибка формы
Unknown column '
.
Информация о контакте с этой проблемой дана позже в этом разделе.col_name
' in 'on clause'
conditional_expr
, используемый с ON
,
это любое условное выражение формы, которая может использоваться в
WHERE
. Вообще Вы должны использовать ON
для
условий, которые определяют, как присоединиться к таблицам, и
WHERE
, чтобы ограничить, какие строки Вы
хотите в наборе результатов.ON
или USING
в LEFT JOIN
,
строка со всем набором столбцов установлена в NULL
и
используется для правой таблицы. Вы можете использовать этот факт, чтобы
найти строки в таблице, у которых нет никакой копии в другой таблице:
SELECT left_tbl.* FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id WHERE right_tbl.id IS NULL;Этот пример находит все строки в
left_tbl
с
id
, которое не присутствует в right_tbl
(то есть, все строки в left_tbl
без соответствующей строки в
right_tbl
). Это принимает, что
right_tbl.id
NOT NULL
. См.
раздел 9.2.1.9.USING(column_list
)
называет список столбцов, которые должны существовать в обеих таблицах. Если
таблицы a
и b
обе содержат столбцы c1
,
c2
и c3
, следующее соединение сравнивает
соответствующие столбцы от этих двух таблиц:
a LEFT JOIN b USING (c1,c2,c3)
NATURAL [LEFT] JOIN
из двух таблиц определен, чтобы быть
семантически эквивалентным INNER JOIN
или LEFT JOIN
с USING
, который называет все столбцы, которые
существуют в обеих таблицах.RIGHT JOIN
аналог LEFT JOIN
.
Чтобы сохранить код портируемым через базы данных, рекомендуется, чтобы Вы
использовали LEFT JOIN
вместо RIGHT JOIN
.{ OJ ... }
синтаксис, показанный в описании синтаксиса
соединения, существует только для совместимости с ODBC. Вьющиеся скобы в
синтаксисе должны быть написаны буквально: они не метасинтаксис как в
другом месте в описаниях синтаксиса.
SELECT left_tbl.* FROM { OJ left_tbl LEFT OUTER JOIN right_tbl ON left_tbl.id = right_tbl.id } WHERE right_tbl.id IS NULL;Вы можете использовать другие типы соединений в пределах
{ OJ ...}
, например,
INNER JOIN
или RIGHT OUTER JOIN
.
Это помогает с совместимостью с некоторыми имеющими отношение к третьей
стороне приложениями, но не является официальным синтаксисом ODBC.STRAIGHT_JOIN
подобен JOIN
,
за исключением того, что левая таблица всегда читается перед правой таблицей.
Это может использоваться для тех случаев, для которых оптимизатор помещает
таблицы в неправильном порядке.Некоторые примеры соединения:
SELECT * FROM table1, table2; SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id; SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; SELECT * FROM table1 LEFT JOIN table2 USING (id); SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id;Присоединитесь к изменениям обработки в MySQL 5.0.12
Естественные соединения и соединения с USING
,
включая внешние разновидности соединения, обработаны согласно стандарту
SQL:2003. Цель состояла в том, чтобы выровнять синтаксис и семантику MySQL
относительно NATURAL JOIN
и JOIN ... USING
согласно SQL:2003. Однако, эти изменения в обработке соединения могут
привести к различным выходным столбцам для некоторых соединений. Кроме того,
некоторые запросы, которые, казалось, работали правильно в более старых
версиях (до 5.0.12) должны быть переписаны, чтобы выполнить стандарт.
У этих изменений есть пять основных аспектов:
Способ, из которого MySQL определяет столбцы результата
операции соединения NATURAL
или USING
(и таким образом результат всего FROM
).
SELECT *
и SELECT
tbl_name
.*
в список выбранных столбцов.NATURAL
или USING
.NATURAL
или
USING
в JOIN ... ON
.ON
JOIN ... ON
.Следующий список обеспечивает больше деталей относительно нескольких эффектов текущей обработки соединения против обработки в более старых версиях. Термин старые значит до MySQL 5.0.12.
Столбцы в NATURAL
или USING
при соединении могут отличаться от того, что было ранее. Определенно,
избыточные выходные столбцы больше не появляются, и порядок столбцов для
SELECT *
может отличаться.
Рассмотрите этот набор запросов:
CREATE TABLE t1 (i INT, j INT); CREATE TABLE t2 (k INT, j INT); INSERT INTO t1 VALUES(1,1); INSERT INTO t2 VALUES(1,1); SELECT * FROM t1 NATURAL JOIN t2; SELECT * FROM t1 JOIN t2 USING (j);Ранее, запросы произвели этот вывод:
+---+---+---+---+ | i | j | k | j | +---+---+---+---+ | 1 | 1 | 1 | 1 | +---+---+---+---+ +---+---+---+---+ | i | j | k | j | +---+---+---+---+ | 1 | 1 | 1 | 1 | +---+---+---+---+В первом
SELECT
столбец j
появляется в обеих таблицах и таким образом становится
столбцом соединения, таким образом, согласно стандартному SQL, это должно
появиться только однажды в выводе, а не дважды. Точно так же во втором
SELECT столбец j
назван в USING
и должен появиться только однажды в выводе, а не дважды. Но в обоих случаях
избыточный столбец не устранен. Кроме того, порядок столбцов не правилен,
согласно стандартному SQL.
Теперь запросы производят этот вывод:
+---+---+---+ | j | i | k | +---+---+---+ | 1 | 1 | 1 | +---+---+---+ +---+---+---+ | j | i | k | +---+---+---+ | 1 | 1 | 1 | +---+---+---+Избыточный столбец устранен, и порядок следования столбцов правилен, согласно стандартному SQL:
Во-первых, общие столбцы двух таблиц присоединяются в порядке, в котором они происходят в первой таблице.
Единственный столбец результата, который заменяет два общих столбца,
определен, используя объединение. Таким образом, для двух столбцов
t1.a
и t2.a
получающийся единственный столбец соединения a
определен как a = COALESCE(t1.a, t2.a)
, где:
COALESCE(x, y) = (CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END)Если работа соединения какое-либо другое соединение, столбцы результата соединения состоит из связи всех столбцов таблиц, к которым присоединяются. Это то же самое, как ранее.
Последствие определения соединенных столбцов:
для внешних соединений соединенный столбец содержит значение столбца
не-NULL
, если один из двух столбцов всегда NULL
.
Если ни один или оба столбца не NULL
, у обоих общих столбцов
есть то же самое значение, таким образом, не имеет значения, какой выбран в
качестве значения соединенного столбца.
Простой способ интерпретировать это состоит в том, чтобы полагать, что
соединенный столбец внешнего соединения представлен общим столбцом внутренней
таблицы JOIN
. Предположите, что таблицы
t1(a,b)
и t2(a,c)
имеют следующее содержание:
t1 t2 ---- ---- 1 x 2 z 2 y 3 wТогда:
mysql> SELECT * FROM t1 NATURAL LEFT JOIN t2; +---+---+------+ | a | b | c | +---+---+------+ | 1 | x | NULL | | 2 | y | z | +---+---+------+Здесь столбец
a
содержит значения t1.a
.
mysql> SELECT * FROM t1 NATURAL RIGHT JOIN t2; +---+---+------+ | a | c | b | +---+---+------+ | 2 | z | y | | 3 | w | NULL | +---+---+------+Здесь столбец
a
содержит значения t2.a
.
Сравните эти результаты с иначе эквивалентными
запросами с JOIN ... ON
:
mysql> SELECT * FROM t1 LEFT JOIN t2 ON (t1.a = t2.a); +---+---+------+------+ | a | b | a | c | +---+---+------+------+ | 1 | x | NULL | NULL | | 2 | y | 2 | z | +---+---+------+------+ mysql> SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a = t2.a); +------+------+---+---+ | a | b | a | c | +------+------+---+---+ | 2 | y | 2 | z | | NULL | NULL | 3 | w | +------+------+---+---+
USING
мог быть переписан как ON
,
который сравнивает соответствующие столбцы. Например, следующие два пункта
были семантически идентичны:
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3Теперь эти два пункта больше не вполне то же самое:
Относительно определения, какие строки удовлетворяют условие соединения, оба соединения остаются семантически идентичными.
SELECT *
, два соединения не семантически идентичны.
USING
соединение выбирает соединенное значение соответствующих
столбцов, тогда как ON
выбирает все столбцы из всех таблиц. Для
предыдущего USING
SELECT *
выбирает эти значения:
COALESCE(a.c1,b.c1), COALESCE(a.c2,b.c2), COALESCE(a.c3,b.c3)Для
ON
SELECT *
выбирает эти значения:
a.c1, a.c2, a.c3, b.c1, b.c2, b.c3С внутренним соединением
COALESCE(a.c1,b.c1)
то же самое, как
a.c1
или b.c1
потому что у обоих столбцов будет то
же самое значение. С внешним соединением (например, LEFT JOIN
)
один из двух столбцов может быть NULL
. Тот столбец будет
убран из результата.NATURAL
или USING
,
и это может потребовать перезаписи запроса. Предположите, что у Вас есть три
таблицы t1(a,b)
, t2(c,b)
и t3(a,c)
,
которые имеют одну строку: t1(1,2)
, t2(10,2)
и
t3(7,10)
. Предположите также, что у Вас есть
NATURAL JOIN
на этих трех таблицах:
SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3;Ранее, левый операнд второго соединения, как полагали, был
t2
,
тогда как это должно быть вложенное соединение (t1 NATURAL JOIN t2)
. В результате столбцы t3
проверены на общие столбцы
только в t2
, и, если t3
имеет общие столбцы с
t1
, эти столбцы не используются в качестве столбцов equi-join.
Таким образом, ранее, предыдущий запрос был преобразован к
следующему equi-соединению:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c;То соединение пропускает еще один предикат equi-соединения
(t1.a = t3.a)
. В результате это производит одну строку, а не
пустой результат, как должно. Правильный эквивалентный запрос:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a;Если Вы требуете того же самого результата запроса в текущих версиях MySQL, как в более старых версиях, переписывайте естественное соединение как первое equi-соединение.
,
) и JOIN
был тот же
самый приоритет, таким образом, выражение соединения
t1, t2 JOIN t3
интерпретировалось как
((t1, t2) JOIN t3)
. Теперь JOIN
имеет более высокий
приоритет, таким образом, выражение интерпретируется как (t1, (t2 JOIN
t3))
. Это изменение затрагивает запросы, которые используют
ON
, потому что тот пункт может отнестись только к столбцам в
операндах соединения, и изменению в интерпретации изменений приоритета того,
каковы те операнды.
Например:
CREATE TABLE t1 (i1 INT, j1 INT); CREATE TABLE t2 (i2 INT, j2 INT); CREATE TABLE t3 (i3 INT, j3 INT); INSERT INTO t1 VALUES(1,1); INSERT INTO t2 VALUES(1,1); INSERT INTO t3 VALUES(1,1); SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);Ранее
SELECT
было законным из-за неявной группировки
t1,t2
как (t1,t2)
. Теперь JOIN
имеет приоритет, таким образом, операнды для ON
это t2
и t3
. Поскольку t1.i1
не столбец в любом из операндов, результат: ошибка Unknown column
't1.i1' in 'on clause'
. Чтобы позволить соединению быть обработанным,
сгруппируйте первые две таблицы явно с круглыми скобками так, чтобы операнды
для ON
(t1,t2)
и t3
:
SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);Альтернативно, избегите использования оператора запятой и используйте вместо него
JOIN
:
SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);Это изменение также относится к запросам, которые смешивают оператор запятой с
INNER JOIN
, CROSS JOIN
, LEFT JOIN
и
RIGHT JOIN
, у всех из которых теперь есть более высокий
приоритет, чем у оператора запятой.ON
мог отнестись к столбцам в таблицах, названных с
правой стороны от него. Теперь ON
может отнестись только к его операндам.
Пример:
CREATE TABLE t1 (i1 INT); CREATE TABLE t2 (i2 INT); CREATE TABLE t3 (i3 INT); SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;Ранее
SELECT
был законным. Теперь запрос терпит неудачу с ошибкой
Unknown column 'i3' in 'on clause'
, поскольку
i3
столбец в t3
,
который не является операндом ON
.
Запрос должен быть переписан следующим образом:
SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);
NATURAL
или
USING
отличаются от того, что было ранее.
Для имен столбцов, которые вне FROM
, MySQL
теперь обрабатывает супернабор запросов по сравнению с ранней логикой. Таким
образом, в случаях, когда MySQL прежде выпустил ошибку, что некоторый столбец
неоднозначен, запрос теперь обработан правильно. Это вследствие того, что
MySQL теперь обрабатывает общие столбцы соединения
NATURAL
или USING
как единственный столбец, так
что, когда запрос обращается к таким столбцам, компилятор запроса не
рассматривает их как неоднозначные.
Пример:
SELECT * FROM t1 NATURAL JOIN t2 WHERE b > 1;Ранее этот запрос произвел бы ошибку
ERROR 1052 (23000): Column 'b' in
where clause is ambiguous
.
Теперь запрос приводит к правильному результату:
+---+---+---+ | b | c | y | +---+---+---+ | 4 | 2 | 3 | +---+---+---+Одно расширение MySQL по сравнению со стандартом SQL:2003 состоит в том, что MySQL позволяет Вам указать общие (coalesced) столбцы соединения
NATURAL
или USING
(так же, как ранее) в то время,
как стандарт отвергает это.SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION
используется, чтобы объединить следствие многократного
SELECT
в
единственный набор результатов.
Имена столбцов из первого SELECT
используются как имена столбцов для возврата результатов. Выбранные столбцы
перечислены в соответствующих позициях каждого
SELECT
должны иметь тот же самый тип данных. Например, у первого столбца, выбранного
первым запросом, должен быть тот же самый тип, как первый столбец,
выбранный другими запросами.
Если типы данных соответствующих столбцов
SELECT
не соответствуют типам и длинам столбцов в
UNION
,
принимаются во внимание значения, полученные всеми
SELECT
.
Например, рассмотрите следующее:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | bbbbbbbbbb | +---------------+
SELECT
это нормальные
запросы, но со следующими ограничениями:
Только последний SELECT
может использовать INTO OUTFILE
. Однако, все результаты
UNION
написаны в файл.
HIGH_PRIORITY
не может использоваться с
SELECT
, которые являются частью
UNION
.
Если Вы определяете это для первого
SELECT
,
это не имеет никакого эффекта. Если Вы определяете это для кого-либо
последующего SELECT
,
будет синтаксическая ошибка.Поведение по умолчанию для UNION
:
дублирующиеся строки удалены из результата. Дополнительно
DISTINCT
не имеет никакого эффекта кроме значения по умолчанию,
потому что это также определяет удаление дублирующейся строки. С
дополнительным ALL
удаления дублирующейся строки не происходит,
и результат включает все строки соответствия от всех
SELECT
.
Вы можете смешать UNION
ALL
и UNION DISTINCT
в
запросе. Смешанные UNION
обработаны таким образом, что
a DISTINCT
переопределяет любой ALL
с его левой стороны. DISTINCT
может быть произведен явно при
использовании UNION DISTINCT
или неявно при использовании UNION
без следующего DISTINCT
или ALL
.
Применять ORDER BY
или LIMIT
к отдельному
SELECT
можно, поместив его
в круглых скобках, которые сопровождают
SELECT
:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);Однако, использование
ORDER BY
для отдельного
SELECT
ничего не подразумевает о порядке, в котором строки появляются в
окончательном результате, потому что
UNION
по умолчанию производит
неупорядоченный набор строк. Поэтому, использование ORDER BY
в этом контексте, как правило, находится в соединении с
LIMIT
, чтобы это использовалось, чтобы определить подмножество
выбранных строк для SELECT
,
даже при том, что это не обязательно затрагивает порядок тех строк в
финальном результате UNION
. Если
ORDER BY
появляется без LIMIT
в
SELECT
,
это оптимизировано далеко, потому что это не будет иметь никакого эффекта
так или иначе.
Используя ORDER BY
или LIMIT
, чтобы
сортировать или ограничить все
UNION
, введите индивидуальный
SELECT
поместите ORDER BY
или LIMIT
после последнего.
Следующий пример использует оба параметра:
(SELECT a FROM t1 WHERE a=10 AND B=1) UNION (SELECT a FROM t2 WHERE a=11 AND B=2) ORDER BY a LIMIT 10;Запрос без круглых скобок эквивалентен одному параметру, как показано.
Этот ORDER BY
не может использовать ссылки столбца, которые
включают имя таблицы (то есть, имена в формате
tbl_name
.col_name
).
Вместо этого обеспечьте псевдоним столбца в первом
SELECT
и обратитесь к псевдониму в ORDER BY
.
Альтернативно, обратитесь к столбцу в ORDER BY
с использованием
его позиции столбца. Однако, использование позиций столбца устарело.
Кроме того, если столбец, который будет сортирован, является псевдонимом,
ORDER BY
должен отнестись к псевдониму, а
не имени столбца. Первый из следующих запросов будет работать, но второй
потерпит неудачу с ошибкой Unknown column 'a' in 'order clause'
:
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b; (SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;При вызове строк в
UNION
результат будет состоять из наборов строк, полученных каждым
SELECT
один за другим, выберите дополнительный столбец в каждом
SELECT
, чтобы
использовать в качестве столбца сортировки и добавить
ORDER BY
после последнего
SELECT
:
(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1) UNION (SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;Чтобы дополнительно поддержать порядок сортировки в пределах
SELECT
, добавьте вторичный
столбец к ORDER BY
:
(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1) UNION (SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;Использование дополнительного столбца также позволяет Вам определить, из которого
SELECT
каждая строка прибывает. Дополнительные столбцы могут предоставить другую
информацию об идентификации также, такую как строку, которая указывает
на имя таблицы.
Запросы UNION
с совокупной функцией в ORDER BY
отклонены с ошибкой
ER_AGGREGATE_ORDER_FOR_UNION
:
SELECT 1 AS foo UNION SELECT 2 ORDER BY MAX(1);
Подзапрос это SELECT
в пределах другого запроса.
Все подформы запросов и операции, которых требует стандарт SQL, поддержаны, так же как несколько особенностей, которые являются MySQL-определенными.
Вот пример подзапроса:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);В этом примере
SELECT * FROM t1 ...
внешний запрос, а (SELECT column1 FROM t2)
подзапрос. Мы говорим, что подзапрос
вложен в пределах внешнего запроса и фактически
возможно вложить подзапросы в пределах других подзапросов на значительную
глубину. Подзапрос должен всегда появляться в пределах круглых скобок.
Основные преимущества подзапросов:
Они позволяют запросы, которые структурированы так, чтобы было возможно изолировать каждую часть запроса.
Вот запрос в качестве примера, который показывает важные пункты о синтаксисе подзапроса, как определено стандартом SQL и поддержано в MySQL:
DELETE FROM t1 WHERE s11 > ANY (SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS (SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM (SELECT * FROM t5) AS t5)));Подзапрос может возвратить скаляр (единственное значение), единственную строку, единственный столбец или таблицу (одна или более строк одного или более столбцов). Их называют скаляром, столбцом, строкой и табличными подзапросами. Подзапросы, которые возвращают особый вид результата, часто могут использоваться только в определенных контекстах, как описано в следующих разделах.
Есть немного ограничений на тип запросов, в которых могут использоваться
подзапросы. Подзапрос может содержать многие из ключевых слов, которые
допустимы в рамках SELECT
:
DISTINCT
, GROUP BY
,
ORDER BY
, LIMIT
, объединения,
UNION
,
комментарии, функции и так далее.
Внешний запрос подзапроса может быть любым из:
SELECT
,
INSERT
,
UPDATE
,
DELETE
,
SET
или
DO
.
В MySQL Вы не можете изменить таблицу и выбрать из той же самой таблицы в
подзапросе. Это относится к таким запросам, как
DELETE
,
INSERT
,
REPLACE
,
UPDATE
и (потому что подзапросы могут использоваться в SET
)
LOAD DATA INFILE
.
В его самой простой форме подзапрос это скалярный подзапрос, который
возвращает единственное значение. Скалярный подзапрос это простой операнд, и
Вы можете использовать его почти где угодно, единственное значение столбца
или литерал является законным, и Вы можете ожидать, что у этого будут те
характеристики, которые имеют все операнды: тип данных, длина, признак, что
это может быть NULL
и так далее. Например:
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL); INSERT INTO t1 VALUES(100, 'abcde'); SELECT (SELECT s2 FROM t1);Подзапрос в этом
SELECT
возвращает единственное значение ('abcde'
), у этого есть тип
данных CHAR
, длина 5,
набор символов и сопоставление, равное значениям по умолчанию во время
CREATE TABLE
,
и признак, что значение в столбце может быть NULL
.
Такие значения, выбранные скалярным подзапросом, не скопированы, потому что,
если результат подзапроса пуст, результат NULL
. Для показанного
подзапроса, если t1
пуст, результат будет NULL
даже
при том, что s2
NOT NULL
.
Есть несколько контекстов, в которых не может использоваться скалярный
подзапрос. Если запрос разрешает только буквальное значение, Вы не можете
использовать подзапрос. Например, LIMIT
требует буквальных
параметров целого числа, и
LOAD DATA INFILE
требует буквального строкового имени файла. Вы не можете использовать
подзапросы, чтобы поставлять эти значения.
Когда Вы видите примеры в следующих разделах, которые содержат довольно
спартанскую конструкцию (SELECT column1 FROM t1)
,
предположите, что Ваш собственный код содержит намного более
разнообразные и сложные конструкции.
Предположите, что мы делаем две таблицы:
CREATE TABLE t1 (s1 INT); INSERT INTO t1 VALUES (1); CREATE TABLE t2 (s1 INT); INSERT INTO t2 VALUES (2);Тогда выполните
SELECT
:
SELECT (SELECT s1 FROM t2) FROM t1;Результат
2
потому что есть строка в t2
, содержащая
столбец s1
, а у этого есть значение 2
.
Скалярный подзапрос может быть частью выражения, но помните про круглые скобки, даже если подзапрос это операнд, который обеспечивает параметр для функции. Например:
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
Наиболее популярный способ использования подзапроса находится в форме:
Здесьnon_subquery_operand
comparison_operator
(subquery
)
comparison_operator
один из этих операторов:
= > < >= <= <> != <=>Например:
... WHERE 'a' = (SELECT column1 FROM t1)MySQL также разрешает эту конструкцию:
Когда-то единственное место для подзапроса было на правой стороне сравнения, и Вы могли бы все еще найти некоторые старые DBMS, которые настаивают на этом.non_subquery_operand
LIKE (subquery
)
Вот пример сравнения подзапроса стандартной формы, которое Вы не можете
сделать с соединением. Это находит все строки в таблице t1
для
которых column1
равно максимальному значению в таблице
t2
:
SELECT * FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);Вот другой пример, который снова невозможен с соединением, потому что он вовлекает соединение для одной из таблиц. Это находит все строки в таблице
t1
, содержа значение, которое встречается
дважды в данном столбце:
SELECT * FROM t1 AS t WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);Для сравнения подзапроса и скаляра подзапрос должен возвратить скаляр. Для сравнения подзапроса со строкой подзапрос должен быть подзапросом строки, который возвращает строку с тем же самым числом значений, как конструктор строки. См. раздел 14.2.10.5.
Здесьoperand
comparison_operator
ANY (subquery
)operand
IN (subquery
)operand
comparison_operator
SOME (subquery
)
comparison_operator
одно из:
= > < >= <= <> !=
ANY
должно следовать за оператором сравнения, означает
вернуть TRUE
, если сравнение TRUE
для
ANY
из значений в столбце, который вернул подзапрос
:
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);Предположите, что есть строка в таблице
t1
, содержащая
(10)
. Выражение TRUE
, если таблица t2
содержит (21,14,7)
потому, что есть значение 7
в
t2
, это меньше 10
. Выражение FALSE
,
если таблица t2
содержит (20,10)
, или если таблица
t2
пуста. Выражение неизвестно (то есть,
NULL
), если таблица t2
содержит
(NULL,NULL,NULL)
.
Когда используется с подзапросом IN
псевдоним для
= ANY
. Таким образом, эти два запроса то же самое:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN(SELECT s1 FROM t2);
IN
и = ANY
не синонимы, когда используются
со списком выражений. IN
может взять список выражений, но
= ANY
нет, см. раздел
13.3.2.
NOT IN
псевдоним не для <> ANY
, а для
<> ALL
. См.
раздел 14.2.10.4.
SOME
псевдоним для ANY
.
Таким образом, эти два запроса то же самое:
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);Использование слова
SOME
редко, но этот пример показывает,
почему это могло бы быть полезно. Большинству людей фраза
a не равный любому b означает
нет никакого b, который равен a,
но это не то, что предназначается синтаксисом SQL. Синтаксис означает
есть некоторый b, который не равен a. Использование
<> SOME
вместо этого помогает гарантировать, что все
понимают значение запроса.
operand
comparison_operator
ALL (subquery
)
ALL
, который должен следовать за оператором сравнения, означает
вернуть TRUE
, если сравнение TRUE
для
ALL
значений в столбце, который вернул подзапрос:
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);Предположите, что есть строка в таблице
t1
, содержащая
(10)
. Выражение TRUE
, если таблица t2
содержит (-5,0,+5)
, поскольку 10
больше чем все три значения в t2
. Выражение FALSE
,
если таблица t2
содержит (12,6,NULL,-100)
потому,
что есть единственное значение 12
в таблице t2
,
которое больше 10
. Выражение неизвестно
(то есть, NULL
), если таблица t2
содержит
(0,NULL,1)
.
Наконец, выражение TRUE
, если таблица t2
пуста.
Так, следующее выражение TRUE
,
когда таблица t2
пуста:
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);Но это выражение
NULL
, когда таблица t2
пуста:
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);Кроме того, следующее выражение
NULL
когда таблица t2
пуста:
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);Вообще, таблицы, содержащие значения
NULL
и пустые таблицы проблемные ситуации
при написании подзапросов, всегда рассматривайте, приняли ли Вы эти две
возможности во внимание.
NOT IN
псевдоним для <> ALL
.
Таким образом, эти два запроса те же самые:
SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);
Скаляр или подзапросы столбца возвращают единственное значение или столбец значений. Подзапрос строки это разновидность подзапроса, которая возвращает единственную строку и может таким образом возвратить больше, чем одно значение столбца. Операторы для сравнений подзапроса строки:
= > < >= <= <> != <=>Вот два примера:
SELECT * FROM t1 WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10); SELECT * FROM t1 WHERE ROW(col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);Для обоих запросов, если таблица
t2
содержит единственную
строку с id = 10
, подзапрос возвращает единственную строку. Если
эта строка имеет значения col3
и col4
, равные
col1
и col2
любых строк в
t1
, WHERE
TRUE
и каждый запрос возвращает те строки t1
. Если значения строк
col3
и col4
в t2
не равны
значениям col1
и col2
любой строки в
t1
, выражение FALSE
и запрос возвращает пустой
набор результатов. Выражение неизвестно
(то есть, NULL
), если подзапрос не производит строк. Ошибка
происходит, если подзапрос производит много строк, потому что подзапрос
строки может возвратить самое большее одну строку.
Выражения (1,2)
и ROW(1,2)
иногда называются
конструкторами строки. Эти два эквивалентны.
Конструктор строки и строка, возвращенная подзапросом, должны содержать то же
самое число значений.
Конструктор строки используется для сравнений с подзапросами, которые возвращают два или больше столбца. Когда подзапрос возвращает единственный столбец, это расценено как скалярное значение, а не как строка, таким образом, конструктор строки не может использоваться с подзапросом, который не возвращает по крайней мере два столбца. Таким образом, следующий запрос терпит неудачу с синтаксической ошибкой:
SELECT * FROM t1 WHERE ROW(1) = (SELECT column1 FROM t2)Конструкторы строки являются законными в других контекстах. Например, следующие два запроса семантически эквивалентны (и обработаны таким же образом оптимизатором):
SELECT * FROM t1 WHERE (column1,column2) = (1,1); SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;Следующий запрос отвечает на запрос найти все строки в таблице
t1
, которые также существуют в таблице
t2
:
SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);
Если подзапрос возвращает какие-либо строки вообще, EXISTS
subquery
TRUE
, а NOT EXISTS
subquery
FALSE
:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);Традиционно подзапрос
EXISTS
начинается с
SELECT *
, но это могло начаться с
SELECT 5
или SELECT column1
или вообще с чего угодно. MySQL игнорирует список
SELECT
в таком подзапросе, таким образом, это не имеет никакого значения.
Для предыдущего примера, если t2
содержит любые строки, даже
строки только со значениями NULL
, условие EXISTS
TRUE
. Это фактически маловероятный пример потому, что
подзапрос [NOT] EXISTS
почти всегда содержит корреляции.
Вот некоторые более реалистические примеры:
Какое хранилище присутствует в одном или более городах?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS (SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));
Последний пример двоичным образом вложенный запрос
NOT EXISTS
. Таким образом, у этого есть
NOT EXISTS
в пределах NOT EXISTS
.
Формально это отвечает на вопрос есть ли город
с хранилищем, которое не находится в Stores
?
Но легче сказать что вложенный NOT EXISTS
отвечает на вопрос
есть ли x
TRUE
для всех y
?
Коррелированый подзапрос это подзапрос, который содержит ссылку на таблицу, которая также появляется во внешнем запросе. Например:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);Заметьте, что подзапрос содержит ссылку на столбец
t1
даже при
том, что FROM
подзапроса не упоминает таблицу t1
.
MySQL смотрит вне подзапроса и находит t1
во внешнем запросе.
Предположите, что таблица t1
содержит строку, где
column1 = 5
и column2 = 6
,
тем временем таблица t2
содержит строку, где
column1 = 5
и column2 = 7
. Простое выражение
... WHERE column1 = ANY (SELECT column1 FROM t2)
было бы
TRUE
, но в этом примере WHERE
в пределах подзапроса
FALSE
(потому что (5,6)
не (5,7)
),
таким образом, выражение в целом FALSE
.
Правило обзора данных: MySQL оценивает изнутри к внешней стороне. Например:
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));В этом запросе
x.column2
должен быть столбец в таблице
t2
потому, что SELECT column1 FROM t2 AS x ...
переименовывает t2
. Это не столбец в таблице t1
,
потому что SELECT column1 FROM t1 ...
внешний запрос, который дальше отсутствует.
Для подзапросов в HAVING
или ORDER BY
MySQL
также ищет имена столбцов во внешнем избранном списке.
Для определенных случаев оптимизирован коррелированый подзапрос. Например:
Иначе они неэффективны и вероятны будут медленными. Запрос переписан, поскольку соединение могло бы улучшить работу.val
IN (SELECTkey_val
FROMtbl_name
WHEREcorrelated_condition
)
Совокупные функции в коррелированых подзапросах могут содержать внешние ссылки, если функция содержит только внешние ссылки, и если функция не содержится в другой функции или выражении.
Подзапросы являются законными в параметре FROM
SELECT
:
SELECT ... FROM (subquery
) [AS]name
...
[AS] name
принудителен, потому что каждая
таблица в FROM
должна иметь имя. Любые столбцы в
subquery
должны иметь уникальные имена.
Ради иллюстрации предположите, что у Вас есть эта таблица:
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);Вот как использовать подзапрос в
FROM
, используя
таблицу в качестве примера:
INSERT INTO t1 VALUES (1,'1',1.0); INSERT INTO t1 VALUES (2,'2',2.0); SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;Результат:
2, '2', 4.0
.
Вот другой пример: предположите, что Вы хотите знать среднее число ряда сумм для сгруппированной таблицы. Это не работает:
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;Однако, этот запрос предоставляет желаемую информацию:
SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;Заметьте, что имя столбца, использованное в пределах подзапроса (
sum_column1
), признано во внешнем запросе.
Подзапросы в FROM
могут
возвратить скаляр, столбец, строку или таблицу. Подзапросы в
FROM
не могут быть коррелированными подзапросами, если не
используются в пределах ON
в JOIN
.
В MySQL 8.0 оптимизатор определяет информацию о полученных таблицах таким
способом, для которого не происходит материализация их для
EXPLAIN
. См.
раздел 9.2.1.18.3.
Возможно при определенных обстоятельствах изменить табличное использование
данных, применив EXPLAIN SELECT
.
Это может произойти, если внешние запросы обращаются к
любым таблицам, а внутренний запрос вызывает сохраненную функцию, которая
изменяет одну или более строк таблицы. Предположите, что есть две таблицы
t1
и t2
в базе данных d1
, создаваемой
как показано здесь:
mysql> CREATE DATABASE d1; Query OK, 1 row affected (0.00 sec) mysql> USE d1; Database changed mysql> CREATE TABLE t1 (c1 INT); Query OK, 0 rows affected (0.15 sec) mysql> CREATE TABLE t2 (c1 INT); Query OK, 0 rows affected (0.08 sec)Теперь мы создаем сохраненную функцию
f1
, которая изменяет
t2
:
mysql> DELIMITER // mysql> CREATE FUNCTION f1(p1 INT) RETURNS INT mysql> BEGIN mysql> INSERT INTO t2 VALUES (p1); mysql> RETURN p1; mysql> END // Query OK, 0 rows affected (0.01 sec) mysql> DELIMITER ;Ссылка на функцию непосредственно в
EXPLAIN SELECT
не имеет никакого эффекта на t2
, как показано здесь:
mysql> SELECT * FROM t2; Empty set (0.00 sec) mysql> EXPLAIN SELECT f1(5); +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM t2; Empty set (0.00 sec)Это потому, что
SELECT
не ссылается ни на какие таблицы, как может быть замечено в столбцах
table
и Extra
вывода.
Это также верно для вложенного следующего
SELECT
:
mysql> EXPLAIN SELECT NOW() AS a1, (SELECT f1(5)) AS a2; +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS; +-------+------+------------------------------------------+ | Level | Code | Message | +-------+------+------------------------------------------+ | Note | 1249 | Select 2 was reduced during optimization | +-------+------+------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM t2; Empty set (0.00 sec)Однако, если внешний
SELECT
ссылаетя на любые таблицы, оптимизатор выполняет запрос в подзапросе также:
mysql> EXPLAIN SELECT * FROM t1 AS a1, (SELECT f1(5)) AS a2; +----+-------------+------------------+--------+---------------+------+---------+------+------+---------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------------+--------+---------------+------+---------+------+------+---------------------+ | 1 | PRIMARY | a1 | system | NULL | NULL | NULL | NULL | 0 | const row not found | | 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | | | 2 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | +----+-------------+------------------+--------+---------------+------+---------+------+------+---------------------+ 3 rows in set (0.00 sec) mysql> SELECT * FROM t2; +----+ | c1 | +----+ | 5 | +----+ 1 row in set (0.00 sec)Это также означает, что такой запрос
EXPLAIN SELECT
,
как один показанный здесь, может занять много времени, чтобы выполнить,
потому что функция BENCHMARK()
выполнена однажды для каждой строки в t1
:
EXPLAIN SELECT * FROM t1 AS a1, (SELECT BENCHMARK(1000000, MD5(NOW())));
Есть некоторые ошибки, которые применяются только к подзапросам. Этот раздел описывает их.
Неподдержанный синтаксис подзапроса:
ERROR 1235 (ER_NOT_SUPPORTED_YET) SQLSTATE = 42000 Message = "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"Это означает, что MySQL не поддерживает запросы следующей формы:
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
ERROR 1241 (ER_OPERAND_COL) SQLSTATE = 21000 Message = "Operand should contain 1 column(s)"Эта ошибка происходит в таких случаях:
SELECT (SELECT column1, column2 FROM t2) FROM t1;Вы можете использовать подзапрос, который возвращает много столбцов, если цель сравнение строк. В других контекстах подзапрос должен быть скалярным операндом. См. раздел 14.2.10.5.
ERROR 1242 (ER_SUBSELECT_NO_1_ROW) SQLSTATE = 21000 Message = "Subquery returns more than 1 row"Эта ошибка происходит для запросов, куда подзапрос должен возвратить самое большее одну строку, но возвращает много строк. Рассмотрите следующий пример:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);Если
SELECT column1 FROM t2
вернет только одну строку,
предыдущий запрос будет работать. Если подзапрос возвратит больше, чем одну
строку, будет ошибка 1242. В этом случае запрос должен быть переписан так:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
Error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000 Message = "You can't specify target table 'x' for update in FROM clause"Эта ошибка происходит в таких случаях, как следующий, который пытается изменить таблицу и выбрать из той же самой таблицы в подзапросе:
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);Вы можете использовать подзапрос для назначения в пределах
UPDATE
потому, что подзапросы
являются законными в UPDATE
и
DELETE
так же, как в
SELECT
.
Однако, Вы не можете использовать ту же самую таблицу (в этом случае таблица
t1
) для обоих подзапросов FROM
и цели обновления.
Для транзакционных механизмов хранения отказ подзапроса заставляет весь запрос терпеть неудачу. Для нетранзакционных механизмов хранения модификации данных, сделанные прежде, чем столкнулись с ошибкой, сохранены.
Развитие является продолжающимся, таким образом, никакая подсказка по оптимизации не надежна в течение длительного срока. Следующий список обеспечивает некоторые интересные уловки, с которыми Вы могли бы работать:
Используйте пункты подзапроса, которые затрагивают число или порядок строк в подзапросе. Например:
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);Вместо этого:
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);Вместо этого запроса:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);Для другого примера используйте этот запрос:
SELECT (SELECT column1 + 5 FROM t1) FROM t2;Вместо этого запроса:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);Вместо этого запроса:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
NOT (a = ANY (...))
вместо
a <> ALL (...)
.x = ANY (таблица содержит
(1,2)
)
вместо x=1 OR x=2
.= ANY
вместо EXISTS
.IN
всегда медленнее =
. Например:
SELECT * FROM t1 WHERE t1.Вместо этого запроса:col_name
= (SELECT a FROM t2 WHERE b =some_const
);
SELECT * FROM t1 WHERE t1.col_name
IN (SELECT a FROM t2 WHERE b =some_const
);
Эти уловки могли бы заставить программы идти быстрее или медленнее.
Используя средства MySQL, например,
BENCHMARK()
,
Вы можете понять, что помогает в Вашей ситуации. См.
раздел 13.14.
Некоторая оптимизация, которую делает сам MySQL:
MySQL выполняет некоррелированые подзапросы только однажды.
Используйте EXPLAIN
, чтобы
удостовериться, что данный подзапрос действительно является некоррелированым.
IN
, ALL
, ANY
и
SOME
в попытке использовать в своих интересах возможность, что
столбцы избранного списка в подзапросе индексированы.EXPLAIN
описывает как специальный тип соединения
(unique_subquery
или index_subquery
):
... IN (SELECTindexed_column
FROMsingle_table
...)
MIN()
или
MAX()
, если
значения NULL
или пустые наборы вовлечены:
Например, этотvalue
{ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery
)
WHERE
:
WHERE 5 > ALL (SELECT x FROM t)мог бы быть обработан оптимизатором так:
WHERE 5 > (SELECT MAX(x) FROM t)
См. также MySQL Internals: How MySQL Transforms Subqueries.
Иногда есть другие способы проверить членство в ряде значений, чем
использование подзапроса. Кроме того, в некоторых случаях не только возможно
переписать запрос без подзапроса, но может быть более эффективно использовать
некоторые из этих методов, а не использовать подзапросы.
Один из них IN()
:
Например, этот запрос:
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);Может быть переписан как:
SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;Запросы:
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);Могут быть переписаны как:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
LEFT [OUTER] JOIN
может быть быстрее, чем эквивалентный
подзапрос, потому что сервер мог бы быть в состоянии оптимизировать это
лучше. До SQL-92 не существовали внешние соединения, таким образом,
подзапросы были единственным способом сделать определенные вещи. Сегодня
MySQL Server и много других современных систем базы данных предлагают широкий
диапазон внешних типов соединения.
MySQL Server поддерживает многотабличный
DELETE
, который может
использоваться, чтобы эффективно удалить строки, основанные на информации от
одной таблицы или даже от многих таблиц в то же самое время. Многотабличный
UPDATE
также поддержан. См. разделы
14.2.2 и
14.2.11.
Однотабличный вариант:
UPDATE [LOW_PRIORITY] [IGNORE]Многотабличный вариант:table_reference
SETcol_name1
={expr1
|DEFAULT} [,col_name2
={expr2
|DEFAULT}] ... [WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
UPDATE [LOW_PRIORITY] [IGNORE]Для однотабличного синтаксисаtable_references
SETcol_name1
={expr1
|DEFAULT} [,col_name2
={expr2
|DEFAULT}] ... [WHEREwhere_condition
]
UPDATE
обновляет столбцы существующих строк в названной таблице с новыми
значениями. SET
указывает, какие столбцы изменить и значения им
нужно дать. Каждое значение может быть дано как выражение или ключевое слово
DEFAULT
, чтобы установить столбец явно в его значение по
умолчанию. WHERE
, если дано, определяет условия, которые
идентифицируют который строки обновить. Без WHERE
все строки обновлены. Если ORDER BY
определен, строки обновлены в порядке, который определен.
LIMIT
устанавливает границу числа строк, которые
могут быть обновлены.
Для многотабличного синтаксиса UPDATE
строки обновлены в каждой таблице, названной в
table_references
, которая удовлетворяет условиям.
Однажды обновлена каждая строка соответствия, даже если она соответствует
условиям многократно. Для многотабличного синтаксиса
ORDER BY
и LIMIT
не могут использоваться.
Для разделенных таблиц однотабличные и многотабличные
формы этого запросы поддерживают использование PARTITION
как часть табличной ссылки. Эта опция берет список из одного или более
раздела или подраздела (или оба). Только перечисленный раздел (или
подраздел) проверен на соответствия, и строка, которая не находится ни в
одном этом разделе или подразделе, не обновлена, удовлетворяет ли она
where_condition
или нет.
В отличие от случая использования PARTITION
с
INSERT
или
REPLACE
допустимый запрос UPDATE ... PARTITION
считают успешным, даже
если никакие строки в перечисленном разделе не соответствуют
where_condition
.
См. раздел 20.5.
where_condition
выражение, которое оценивается к
истине для каждой строки, которая будет обновлена. Для синтаксиса выражения
см. раздел 10.5.
table_references
и
where_condition
определены как описано в
раздел 14.2.9.
Вы нуждаетесь в привилегии
UPDATE
только для столбцов, на которые ссылаются в
UPDATE
, которые фактически
обновлены. Вы нуждаетесь только в привилегии
SELECT
для любых столбцов, которые считаны, но не изменены.
UPDATE
поддерживает следующие модификаторы:
С LOW_PRIORITY
выполнение
UPDATE
отсрочен, пока никакие
другие клиенты не перестанут читать из таблицы. Это затрагивает только
механизмы хранения, которые используют только блокировку на уровне таблицы
(MyISAM
, MEMORY
и MERGE
).
IGNORE
запрос обновления не прерывается,
даже если ошибки происходят во время обновления. Строки, для которых
конфликты дубликатов ключей происходят на уникальном значении ключа, не
обновлены. Строки, обновленные к значениям, которые вызвали бы конверсионные
ошибки данных, обновлены к самым близким допустимым значениям вместо этого.
UPDATE IGNORE
, включая тех,
которые имеют ORDER BY
отмечены как опасные для основанной на
запросе репликации. Это потому, что порядок, в котором обновлены строки,
определяет, какие строки проигнорированы. С этим изменением такие запросы
производят предупреждение в журнале, используя основанный на запросе режим и
зарегистрированы, используя основанный на строке формат, используя режим
MIXED
(Bug #11758262, Bug #50439), см.
раздел 19.2.1.3.
Если Вы получаете доступ к столбцу от таблицы, которая будет обновлена в
выражении, UPDATE
использует текущее значение столбца. Например, следующий запрос
увеличивает col1
на единицу:
UPDATE t1 SET col1 = col1 + 1;Второе назначение устанавливает
col2
к (обновленному) текущему значению col1
, а не оригинальному
col1
. Результат:
col1
и col2
имеют то же самое значение. Это поведение отличается от стандартного SQL.
UPDATE t1 SET col1 = col1 + 1, col2 = col1;Однотабличный
UPDATE
вообще оценен слева направо. Для многотабличных обновлений нет никакой
гарантии, что назначения выполнены в любом особом порядке.
Если Вы устанавливаете столбец в значение, которое он в настоящее время имеет, MySQL замечает это и не обновляет его.
Если Вы обновляете столбец, который был объявлен NOT NULL
,
устанавливая в NULL
, ошибка происходит если строгий режим SQL
включен, иначе столбец установлен в неявное значение по умолчанию для типа
данных столбца, и количество предупреждений увеличено. Неявное значение по
умолчанию 0
для числовых типов, пустая строка (''
)
для строковых типов и нулевое значение
для типов времени и даты. См. раздел
12.7.
Если произведенный столбец обновлен явно, единственное разрешенное
значение DEFAULT
. Для информации о произведенных столбцах см.
раздел 14.1.15.5.
UPDATE
возвращает число строк, которые были фактически изменены.
mysql_info()
в C API
возвращает число строк, которые были соответствующими и обновлены и число
предупреждений, которые произошли во время
UPDATE
.
Вы можете использовать LIMIT
, чтобы ограничить контекст
row_count
UPDATE
. LIMIT
ограничение соответствующих строк. Запрос останавливается, как только он
нашел row_count
строк, которые удовлетворяют
WHERE
, неважно, были ли они фактически изменены.
Если UPDATE
запрос включает ORDER BY
,
строки обновлены в порядке, определенном параметром. Это может быть полезно
в определенных ситуациях, которые могли бы иначе привести к ошибке.
Предположите что таблица t
содержит столбец id
,
у которого есть уникальный индекс. Следующий запрос может потерпеть неудачу с
ошибкой дубликата ключа, в зависимости от порядка,
в котором обновлены строки:
UPDATE t SET id = id + 1;Например, если таблица содержит 1 и 2 в столбце
id
и 1 обновлен к 2 прежде, чем 2 будет обновлен к 3, ошибка происходит. Чтобы
избежать этой проблемы, добавьте ORDER BY
, чтобы строки с
большим id
были обновлены перед теми с меньшими значениями:
UPDATE t SET id = id + 1 ORDER BY id DESC;Вы можете также использовать
UPDATE
, покрывающий много таблиц. Однако, Вы не можете использовать ORDER
BY
или LIMIT
с многотабличным
UPDATE
.
table_references
перечисляет таблицы, вовлеченные в соединение. Его синтаксис описан в
разделе 14.2.9.2:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;Предыдущий пример показывает внутреннее соединение, которое использует оператор запятой, но многотабличный
UPDATE
может использовать любой тип соединения, разрешенного в
SELECT
, например, LEFT JOIN
.
Если Вы используете многотабличный UPDATE
с таблицами, для которых есть ограничения внешнего ключа,
оптимизатор MySQL мог бы обработать таблицы в порядке, который отличается от
нужного из их родительских/дочерних отношений. В этом случае запрос терпит
неудачу и откатывается. Вместо этого обновите единственную таблицу и
положитесь на ON UPDATE
, который обеспечивает InnoDB
, чтобы заставить другие таблицы быть измененными соответственно. См.
раздел 16.8.6.
Вы не можете обновить таблицу и выбрать из той же самой таблицы в подзапросе.
В MySQL 8.0 UPDATE
на разделенной таблице, используя механизм хранения с
блокировками на уровне таблицы, блокирует
только раздел, содержащий строки, которые соответствуют
UPDATE
WHERE
,
пока ни один из столбцов раздела не обновлен. См.
Partitioning and Locking.
MySQLподдерживает местные транзакции (в пределах данного сеанса клиента)
через запросы SET autocommit
,
START TRANSACTION
,
COMMIT
и
ROLLBACK
. См
раздел 14.3.1.
Операционная поддержка XA позволяет MySQL участвовать в распределенных
транзакциях также. См. раздел 14.3.7.
START TRANSACTION [Эти запросы обеспечивают управление использованием транзакциями:transaction_characteristic
[,transaction_characteristic
] ...]transaction_characteristic
: WITH CONSISTENT SNAPSHOT | READ WRITE | READ ONLY BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET autocommit = {0 | 1}
START TRANSACTION
или
BEGIN
запустит новую транзакцию.
COMMIT
передает текущую транзакцию, производя
ее постоянные изменения.ROLLBACK
удаляет текущую транзакцию, отменяя ее изменения.
SET autocommit
отключает или включает режим
автозавершения транзакций для текущего сеанса.По умолчанию MySQL выполняется с включенным autocommit. Это означает, что как только Вы выполняете запрос, который обновляет (изменяет) таблицу, MySQL хранит обновление на диске, чтобы сделать это постоянным. Изменение не может быть удалено до прежнего уровня.
Чтобы отключить режим неявно для единственного ряда запросов,
используют START TRANSACTION
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summary=@A WHERE type=1; COMMIT;С
START TRANSACTION
autocommit
остается отключенным, пока Вы не заканчиваете транзакцию
COMMIT
или ROLLBACK
. Режим autocommit тогда
возвращается в его предыдущий статус.
START TRANSACTION
разрешает несколько модификаторов.
Чтобы определить много модификаторов, отделите их запятыми.
WITH CONSISTENT SNAPSHOT
запускает
последовательное чтение
для механизмов хранения, которые способны к нему. Это применяется только к
InnoDB
. Эффект тот же самый, как START TRANSACTION
,
сопровождаемый SELECT
из любой
таблицы InnoDB
, см.
раздел 16.5.2.3.
WITH CONSISTENT SNAPSHOT
не изменяет текущий операционный
уровень изоляции,
таким образом, это обеспечивает последовательный снимок, только если текущий
уровень изоляции разрешает последовательное чтение.
Единственный уровень изоляции, который разрешает последовательное чтение, это
REPEATABLE READ
. Для всех других уровней изоляции WITH CONSISTENT SNAPSHOT
проигнорирован. Предупреждение произведено, когда
WITH CONSISTENT SNAPSHOT
проигнорирован.
READ WRITE
и READ ONLY
устанавливают операционный режим доступа. Они разрешают или запрещают
изменения таблиц, используемых в транзакции. READ ONLY
ограничение препятствует тому, чтобы транзакция изменила или заблокировала
транзакционные и нетранзакционные таблицы, которые видимы другим транзакциям.
Транзакция может все еще изменить или заблокировать временные таблицы.
MySQL включает дополнительную оптимизацию для запросов на
InnoDB
, когда транзакция, как известно, только для чтения.
Определение READ ONLY
гарантирует, что эта оптимизация применена
в случаях, где состояние только для чтения не может быть определено
автоматически. См. раздел
9.5.3.
Если никакой режим доступа не определен, режим по умолчанию применяется.
Если значение по умолчанию не было изменено, это чтение-запись. Не разрешено
определять сразу READ WRITE
и READ ONLY
.
В режиме только для чтения остается возможным изменить таблицы,
составленные с TEMPORARY
, используя запросы DML. Изменения,
произведенные запросами DDL, не разрешены, так же,
как с постоянными таблицами.
Подробности в разделе 14.3.6.
Если включена read_only
, явно запуская транзакцию с START TRANSACTION READ WRITE
Вы должны иметь привилегию
SUPER
.
Многие API для того, чтобы написать приложения-клиенты MySQL (такие, как
JDBC), обеспечивают их собственные методы для того, чтобы они начали
транзакции, которые могут (и иногда должны) использоваться вместо того, чтобы
послать START TRANSACTION
. См. главу 25
.
Чтобы отключить режим явно:
SET autocommit=0;После отключения autocommit установкой переменной
autocommit
в 0,
изменения безопасных от транзакции таблиц (таких, как
InnoDB
или
NDB
)
не сделаны постоянными немедленно. Вы должны использовать
COMMIT
, чтобы
сохранить Ваши изменения нв диск, или ROLLBACK
, чтобы
проигнорировать все изменения.
autocommit
переменная сеанса и должна быть установлена для каждого сеанса. Чтобы
отключить режим для каждого нового соединения, см. описание переменной
autocommit
в
разделе 6.1.5.
BEGIN
и BEGIN WORK
поддержаны как псевдонимы
START TRANSACTION
, который является стандартным синтаксисом SQL,
рекомендуемым способ запустить транзакцию, и разрешает модификаторы,
которые в BEGIN
отсутствуют.
BEGIN
отличается от использования ключевого слова
BEGIN
, которое запускает BEGIN
... END
. Последний не начинает транзакцию. См.
раздел 14.6.1.
В пределах всех сохраненных программ (хранимые процедуры и функции,
триггеры и события), анализатор обрабатывает BEGIN [WORK]
как начало BEGIN ... END
.
Начните транзакцию в этом контексте с
START TRANSACTION
.
WORK
поддержано для COMMIT
и
ROLLBACK
, как CHAIN
и RELEASE
.
CHAIN
и RELEASE
могут использоваться для
дополнительного управления операционным завершением. Значение
переменной
completion_type
определяет поведение завершения по умолчанию. См.
раздел 6.1.5.
AND CHAIN
заставляет новую транзакцию начинаться, как только
текущяя заканчивается, и у новой транзакции будет тот же самый уровень
изоляции, как у только что законченной транзакции. RELEASE
заставляет сервер разъединять текущий сеанс клиента после завершения текущей
транзакции. Включение ключевого слова NO
подавляет завершение
CHAIN
или RELEASE
, которое может быть полезным,
если переменная
completion_type
установлена, чтобы вызвать завершение объединения
в цепочку или выпуска по умолчанию.
Начало транзакции заставляет любую транзакцию на ожидании быть переданной. См. раздел 14.3.3.
Начало транзакции также снимает табличные блокировки, приобретенные с
LOCK TABLES
, как если бы Вы
выполнили UNLOCK TABLES
.
Начало транзакции не снимает глобальную блокировку чтения, приобретенную с
FLUSH TABLES WITH READ LOCK
.
Для лучших результатов транзакции должны быть выполнены, используя только таблицы, которыми управляет единственный безопасный для транзакции механизм хранения. Иначе, следующие проблемы могут произойти:
Если Вы используете таблицы больше чем от одного безопасного для
транзакции механизма хранения (такого, как InnoDB
),
и операционный уровень изоляции не
SERIALIZABLE
,
возможно, что, когда одна транзакция передает, другая продолжающаяся
транзакция, которая использует те же самые таблицы, будет видеть только
некоторые из изменений, произведенные первой. Таким образом, валентность
транзакций не гарантируется со смешанными механизмами, и могут быть
несогласованности. Если транзакции смешанного механизма являются нечастыми,
Вы можете использовать SET
TRANSACTION ISOLATION LEVEL
, чтобы установить уровень изоляции в
SERIALIZABLE
на
основе транзакции по мере необходимости.
ROLLBACK
после обновления нетранзакционной таблицы в пределах транзакции, будет
предупреждение
ER_WARNING_NOT_COMPLETE_ROLLBACK
.
Изменения безопасных для транзакции таблиц откатываются до прежнего уровня,
но небезопасные для транзакции таблицы не изменяются.Каждая транзакция сохранена в двоичном журнале в одном куске на
COMMIT
.
Ттранзакции, которые откатились, не зарегистрированы.
Исключение: Модификации нетранзакционных таблиц
не могут быть отменены. Если транзакция, которая откачена, включает
модификации нетранзакционных таблиц, вся транзакция зарегистрирована с
ROLLBACK
в конце, чтобы гарантировать, что модификации к нетранзакционным таблицам
копируются. См. раздел 6.4.4.
Вы можете изменить уровень изоляции или режим доступа для транзакций с
SET TRANSACTION
. См.
раздел 14.3.6.
Откатывание назад может быть медленной работой, которая может произойти
неявно без пользователя, явно просившего этого (например, когда ошибка
происходит). Из-за этого SHOW
PROCESSLIST
показывает Rolling back
в столбце
State
для сеанса, не только для явных отмен, выполненных с
ROLLBACK
, но также и для неявных.
В MySQL 8.0 BEGIN
, COMMIT
и
ROLLBACK
не затронуты правилами
--replicate-do-db
или
--replicate-ignore-db
.
Некоторые запросы не могут быть отменены. Вообще, они включают язык определения данных (DDL), такие запросы, как те, которые создают или удаляют базы данных, те, которые создают, удаляют или изменяют таблицы или сохраненные подпрограммы.
Вы должны разработать свои транзакции, чтобы не включать такие запросы. Если Вы делаете запрос рано в транзакции, которая не может быть удалена, а затем другой запрос позже терпит неудачу, полный эффект транзакции не может быть отменен в таких случаях.
Запросы, перечисленные в этом разделе (и любые синонимы для них) неявно
заканчивают любую транзакцию, активную в текущем сеансе, как будто Вы сделали
COMMIT
прежде, чем выполнить запрос.
Большинство этих запросов также вызывает неявное закрытие после выполнения. Намерение состоит в том, чтобы обработать каждый такой запрос в своей собственной специальной транзакции, потому что это не может быть отменено так или иначе. Операционное управление и запросы блокировки это исключения: если неявное завершение происходит перед выполнением, другое не происходит после.
Запросы Data definition language (DDL), которые
определяют или изменяют объекты базы данных.
ALTER EVENT
,
ALTER FUNCTION
,
ALTER PROCEDURE
,
ALTER SERVER
,
ALTER TABLE
,
ALTER VIEW
,
CREATE DATABASE
,
CREATE EVENT
,
CREATE FUNCTION
,
CREATE INDEX
,
CREATE PROCEDURE
,
CREATE ROLE
,
CREATE SERVER
,
CREATE TABLE
,
CREATE TRIGGER
,
CREATE VIEW
,
DROP DATABASE
,
DROP EVENT
,
DROP FUNCTION
,
DROP INDEX
,
DROP PROCEDURE
,
DROP ROLE
,
DROP SERVER
,
DROP TABLE
,
DROP TRIGGER
,
DROP VIEW
,
INSTALL PLUGIN
,
RENAME TABLE
,
TRUNCATE TABLE
и
UNINSTALL PLUGIN
.
CREATE TABLE
и
DROP TABLE
не передают
транзакцию, если ключевое слово TEMPORARY
используется.
Это не относится к другим операциям на временных таблицах, например,
ALTER TABLE
и
CREATE INDEX
,
которые действительно закрывают транзакцию. Однако, хотя не происходит
неявное завершение, ни один запрос не может быть удален, что означает, что
использование таких запросов заставляет транзакционную валентность быть
нарушенной. Например, если Вы используете
CREATE TEMPORARY TABLE
, а затем отмените транзакцию,
таблица остается существующей.
CREATE TABLE
в
InnoDB
обработан как единственная транзакция. Это означает, что
ROLLBACK
от пользователя не
отменяет CREATE TABLE
,
сделанные во время этой транзакции.
CREATE TABLE ... SELECT
неявно передает прежде и после выполнения запроса, когда Вы составляете
невременные таблицы. Этого не происходит для
CREATE TEMPORARY TABLE ... SELECT
.
Это должно предотвратить проблему при репликации, где таблица могла быть
составлена на ведущем устройстве после отката, но не зарегистрирована в
двоичном журнале, а поэтому не копируется к ведомому устройству.
mysql
.
ALTER USER
,
CREATE USER
,
DROP USER
,
GRANT
,
RENAME USER
,
REVOKE
и
SET PASSWORD
.BEGIN
,
LOCK TABLES
, SET
autocommit = 1
(если значение еще не 1),
START TRANSACTION
и
UNLOCK TABLES
.
UNLOCK TABLES
передает транзакцию, только если любые таблицы в настоящее время
блокировались с LOCK TABLES
,
чтобы приобретать нетранзакционные табличные блокировки. Этого не происходит
для UNLOCK TABLES
с
FLUSH TABLES WITH READ LOCK
,
потому что последний запрос не приобретает блокировки на уровне таблицы.
Транзакции не могут быть вложены. Это последствие неявного закрытия,
выполненного для любой текущей транзакции, когда Вы выполняете
START TRANSACTION
или один из его синонимов.
Запросы, которые вызывают неявное закрытие, не могут использоваться в
транзакции XA в то время, как транзакция
находится в состоянии ACTIVE
.
BEGIN
отличается от использования ключевого слова BEGIN
, которое
начинает блок BEGIN ... END
.
Последний не вызывает неявное закрытие. См.
раздел 14.6.1.
LOAD DATA INFILE
.
LOAD DATA INFILE
неявно передают только для таблиц, использующих механизм хранения
NDB
.ANALYZE TABLE
,
CACHE INDEX
,
CHECK TABLE
,
FLUSH
,
LOAD INDEX INTO CACHE
,
OPTIMIZE TABLE
,
REPAIR TABLE
и
RESET
.START SLAVE
,
STOP SLAVE
,
RESET SLAVE
и
CHANGE MASTER TO
.
SAVEPOINTidentifier
ROLLBACK [WORK] TO [SAVEPOINT]identifier
RELEASE SAVEPOINTidentifier
InnoDB
поддерживает запросы SQL
SAVEPOINT
,
ROLLBACK TO SAVEPOINT
,
RELEASE SAVEPOINT
и дополнительное ключевое слово WORK
для
ROLLBACK
.
SAVEPOINT
устанавливает
точку сохранения с именем identifier
.
Если у текущей транзакции есть точка сохранения с тем же самым именем, старая
удалена, новая установлена.
ROLLBACK TO SAVEPOINT
откатывает транзакцию на точку сохранения, не заканчивая транзакцию.
Модификации, которые текущая транзакция сделала со строками после точки
сохранения, отменены, но InnoDB
не
снимает блокировки строки, которые были сохранены в памяти после точки.
Для новой вставленной строки информацию о блокировке переносит операционное
ID, сохраненное в строке, блокировка не сохранена отдельно в памяти. В этом
случае блокировка строки снята при отмене. Точки, которые были установлены в
более позднее время, чем названная, удалены.
Если ROLLBACK TO SAVEPOINT
возвращает следующую ошибку, это означает, что никакой точки с указанным
именем не существует:
ERROR 1305 (42000): SAVEPOINT identifier
does not exist
RELEASE SAVEPOINT
удаляет названную точку из набора точек текущей транзакции. Завершение или
отмена не происходят. Это ошибка, если точка не существует.
Все точки текущей транзакции удалены, если Вы выполняете
COMMIT
или
ROLLBACK
,
который не называет точку.
Новый уровень точки создается, когда сохраненная функция вызвана, или триггер активирован. Точки на предыдущих уровнях становятся недоступными и таким образом не находятся в противоречии с точками на новом уровне. Когда функция или триггер заканчиваются, любые точки, который это создало, сняты, и предыдущий уровень точек восстановлен.
LOCK TABLESMySQL позволяет сеансам клиента приобрести табличные блокировки явно с целью сотрудничества с другими сеансами для доступа к таблицам, или препятствовать тому, чтобы другие сеансы изменили таблицы во время периодов, когда сеанс требует эксклюзивного доступа к ним. Сеанс может приобрести или выпустить блокировки только для себя. Один сеанс не может приобрести блокировки за другой сеанс или выпустить блокировки, проводимые другим сеансом.tbl_name
[[AS]alias
]lock_type
[,tbl_name
[[AS]alias
]lock_type
] ...lock_type
: READ [LOCAL] | [LOW_PRIORITY] WRITE UNLOCK TABLES
Блокировки могут использоваться, чтобы подражать транзакциям или получить больше скорости, обновляя таблицы. Это объяснено более подробно позже в этом разделе.
LOCK TABLES
явно приобретает табличные блокировки. Табличные блокировки могут быть
приобретены для базовых таблиц или представлений. Вы должны иметь привилегии
LOCK TABLES
и
SELECT
для каждого объекта, который будет заблокирован.
Для блокировки представления LOCK
TABLES
добавляет все базовые таблицы, используемые в
представлении, и блокирует их автоматически. Если Вы блокируете таблицу явно
с LOCK TABLES
,
любые таблицы, используемые в триггерах, также заблокированы неявно, как
описано в разделе 14.3.5.2.
UNLOCK TABLES
явно снимает любые табличные блокировки текущего сеанса.
LOCK TABLES
неявно снимает любые табличные блокировки, проводимые текущим сеансом прежде,
чем приобрести новые блокировки.
Другое использование UNLOCK
TABLES
должно выпустить глобальную блокировку чтения,
приобретенную с запросом FLUSH TABLES WITH READ
LOCK
, что позволяет Вам заблокировать все таблицы во всех базах
данных. См. раздел 14.7.6.3.
Это очень удобный способ получить резервные копии, если у Вас есть файловая
система, такая как Veritas, которая может взять снимки вовремя.
Табличная блокировка защищает только от несоответствующих чтений или
записей другими сеансами. Сеанс, держащий блокировку WRITE
,
может выполнить на уровне таблицы такие операции, как
DROP TABLE
или
TRUNCATE TABLE
.
Для сеансов, держащих блокировку READ
, операции
DROP TABLE
и
TRUNCATE TABLE
не разрешены.
Следующее обсуждение применяется только к таблицам
не-TEMPORARY
. LOCK TABLES
разрешен (но проигнорирован) для TEMPORARY
.
К таблице может получить доступ свободно сеанс, в пределах которого она
создавалась, независимо от того, чем другая блокировка может быть в
действительности. Никакая блокировка не необходима, потому что никакой другой
сеанс не может видеть таблицу.
Правила для приобретения блокировки
Чтобы приобрести табличные блокировки в пределах текущего сеанса,
используйте LOCK TABLES
.
Следующие типы блокировки доступны:
READ [LOCAL]
:
Сеанс, который держит блокировку, может читать таблицу (но не писать ее).
READ
для таблицы в то же самое время.READ
.LOCAL
позволяет не находиться в противоречии с
INSERT
(параллельные вставки) с другими сеансами в то время, как блокировка
проводится. См. раздел 9.11.3.
Однако, READ LOCAL
не может использоваться, если Вы собираетесь
управлять процессами использования базы данных, внешними к серверу, в то
время как Вы держите блокировку. Для InnoDB
READ
LOCAL
то же самое, что и READ
.[LOW_PRIORITY] WRITE
:
Сеанс, который держит блокировку, может читать и писать таблицу.
WRITE
проводится.LOW_PRIORITY
не имеет никакого эффекта. В предыдущих версиях
MySQL это затрагивало поведение блокировки, но это больше не так. Это теперь
устарело, и его использование производит предупреждение. Используйте
WRITE
без LOW_PRIORITY
.Если LOCK TABLES
должно ждать из-за блокировок, проводимых другими сеансами на любой из
таблиц, он блокируется, пока все блокировки не могут быть приобретены.
Сеанс, который требует блокировок, должен приобрести все блокировки,
которые требуются в одном запросе LOCK
TABLES
. В то время как блокировки, полученные таким образом,
проводятся, сеанс может получить доступ только к заблокированным таблицам.
Например, в следующей последовательности запросов, ошибка происходит для
попытки получить доступ к t2
, потому что это не было
заблокировано LOCK TABLES
:
mysql> LOCK TABLES t1 READ; mysql> SELECT COUNT(*) FROM t1; +----------+ | COUNT(*) | +----------+ | 3 | +----------+ mysql> SELECT COUNT(*) FROM t2; ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLESТаблицы в
INFORMATION_SCHEMA
это исключение. К ним можно
получить доступ, не будучи заблокированным явно даже в то время, как сеанс
считает табличные блокировки полученными
LOCK TABLES
.
Вы не можете обратиться к заблокированной таблице многократно в единственном запросе, используя то же самое имя. Используйте псевдонимы вместо этого, и получите отдельную блокировку для таблицы и каждого псевдонима:
mysql> LOCK TABLE t WRITE, t AS t1 READ; mysql> INSERT INTO t SELECT * FROM t; ERROR 1100: Table 't' was not locked with LOCK TABLES mysql> INSERT INTO t SELECT * FROM t AS t1;Ошибка происходит для первого
INSERT
? потому что есть две ссылки на то же самое название заблокированной
таблицы. Второq INSERT
преуспевает, потому что ссылки на таблицу используют различные имена.
Если Ваши запросы относятся к таблице посредством псевдонима, Вы должны заблокировать таблицу, используя тот же самый псевдоним. Это не работает, чтобы заблокировать таблицу, не определяя псевдоним:
mysql> LOCK TABLE t READ; mysql> SELECT * FROM t AS myalias; ERROR 1100: Table 'myalias' was not locked with LOCK TABLESНаоборот, если Вы блокируете таблицу, используя псевдоним, Вы должны обратиться к этому в Ваших запросах, используя тот псевдоним:
mysql> LOCK TABLE t AS myalias READ; mysql> SELECT * FROM t; ERROR 1100: Table 't' was not locked with LOCK TABLES mysql> SELECT * FROM t AS myalias;Блокировка
WRITE
обычно имеет более высокий приоритет, чем
READ
, чтобы гарантировать, что обновления обработаны как можно
скорее. Это означает, что если один сеанс получает блокировку
READ
, а затем другой сеанс просит WRITE
,
последующая READ
ждет, пока сеанс, который просил
WRITE
получит блокировку и выпустит ее.
LOCK TABLES
приобретает блокировки следующим образом:
Сортирует все таблицы, которые будут заблокированы во внутренне определенном порядке. С пользовательской точки зрения этот порядок неопределен.
Эта политика гарантирует, что табличная блокировка свободна от тупика.
LOCK TABLES
или UNLOCK TABLES
,
когда относится к разделенной таблице, всегда блокирует всю таблицу, эти
запросы не поддерживают блокировку разделов. См.
Partitioning and Locking.
Правила для снятия блокировки
Когда табличные блокировки, проводимые сеансом, выпущены, они все освобождены в то же самое время. Сеанс может выпустить свои блокировки явно, или блокировки могут быть выпущены неявно при определенных условиях.
Сеанс может выпустить свои блокировки явно с
UNLOCK TABLES
.
LOCK
TABLES
, чтобы приобрести блокировку в то время, как имеет
существующие блокировки, они выпущены неявно прежде, чем
новые блокировки предоставляются.START TRANSACTION
),
неявный UNLOCK TABLES
выполнен, который заставляет существующие блокировки быть выпущенными. Для
дополнительной информации о взаимодействии между табличной блокировкой и
транзакциями см. раздел
14.3.5.1.Если соединение для сеанса клиента заканчивается, сервер неявно выпускает все табличные блокировки, проводимые сеансом. Если клиент повторно соединится, то блокировок больше не будет. Кроме того, если у клиента была активная транзакция, сервер откатывает ее при разъединии, и если повторно соединяются, новый сеанс начинается, с включенным autocommit. Поэтому клиенты могут хотеть отключить автоатическое пересоединение. С auto-reconnect клиент не уведомлен, если повторно соединяется, но любые табличные блокировки или текущая транзакция будет потеряна. При выключенном auto-reconnect, если соединение удаляется, ошибка происходит для следующего сделанного запроса. Клиент может обнаружить ошибку и принять соответствующие меры, такие как переприобретение блокировок или восстановление транзакции. См. раздел 25.8.16.
Если Вы используете ALTER TABLE
на заблокированной таблице, она может разблокироваться. Например, если
Вы делаете попытку второго ALTER TABLE
, результат может быть ошибкой Table
'
.
Чтобы обработать это, заблокируйте таблицу снова до второго изменения. См.
также раздел B.5.6.1.tbl_name
' was not locked with LOCK TABLES
LOCK TABLES
и
UNLOCK TABLES
взаимодействуют с использованием транзакций следующим образом:
LOCK TABLES
не безопасно для транзакции и неявно передает любую активную транзакцию
прежде, чем попытаться заблокировать таблицы.
UNLOCK TABLES
неявно передает любую активную транзакцию, но только если
LOCK TABLES
использовался, чтобы приобрести табличные блокировки. Например, в
следующем наборе запросов UNLOCK TABLES
выпускает глобальную блокировку чтения, но не передает
транзакцию, потому что никакие табличные блокировки не работают:
FLUSH TABLES WITH READ LOCK; START TRANSACTION; SELECT ... ; UNLOCK TABLES;
START TRANSACTION
)
неявно передает любую текущую транзакцию и выпускает
существующие табличные блокировки.FLUSH TABLES WITH READ LOCK
приобретает глобальную блокировку чтения и не приобретает табличные
блокировки, таким образом, это не подвергается тому же самому поведению, как
LOCK TABLES
и
UNLOCK TABLES
относительно табличной блокировки и неявного закрытия транзакций. Например,
START TRANSACTION
не выпускает глобальную блокировку чтения. См.
раздел 14.7.6.3.LOCK
TABLES
и UNLOCK TABLES
с транзакционными таблицами это начать транзакцию с
SET autocommit = 0
(не START
TRANSACTION
) вместе с LOCK
TABLES
и не вызывать UNLOCK
TABLES
пока Вы не передаете транзакцию явно. Например, если Вы
должны написать в таблицу t1
и читать из таблицы t2
:
SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;
Когда Вы вызываете LOCK TABLES
, InnoDB
внутренне берет его собственную табличную
блокировку, и MySQL берет свою собственную табличную блокировку.
InnoDB
выпускает его внутреннюю табличную блокировку в следующей
передаче транзакции, но для MySQL, чтобы выпустить его табличную блокировку,
Вы должны вызвать UNLOCK TABLES
. Вы не должны иметь
autocommit = 1
, потому что тогда InnoDB
немедленно
выпускает внутреннюю табличную блокировку после вызова
LOCK TABLES
,
и тупики могут очень легко произойти. InnoDB
не приобретает
внутреннюю табличную блокировку вообще, если
autocommit = 1
,
чтобы помочь старым приложениям избежать ненужных тупиков.ROLLBACK
не выпускает табличные блокировки.Если Вы блокируете таблицу явно с LOCK
TABLES
, любые таблицы, используемые в триггерах,
также заблокированы неявно:
Блокировки взяты в то же самое время, как приобретенные явно с
LOCK TABLES
.
LOCK TABLES
,
но надо заблокировать для записи, потому что это могло бы быть изменено в
пределах триггера, блокировка записи, а не блокировка чтения реально взята.
Таким образом, неявная блокировка записи необходимая из-за таблицы в пределах
триггера, заставляет явный запрос блокировки чтения быть преобразованным в
запрос блокировки записи.Предположите, что Вы блокируете две таблицы, t1
и
t2
, с использованием этого запроса:
LOCK TABLES t1 WRITE, t2 READ;Если
t1
или t2
имеют любые триггеры, таблицы,
используемые в пределах триггеров, будут также заблокированы. Предположите,
что t1
имеет триггер:
CREATE TRIGGER t1_a_ins AFTER INSERT ON t1 FOR EACH ROW BEGIN UPDATE t4 SET count = count+1 WHERE id = NEW.id AND EXISTS (SELECT a FROM t3); INSERT INTO t2 VALUES(1, 2); END;Результат
LOCK TABLES
:
t1
и t2
заблокированы, потому что они появляются в
запросе, а t3
и t4
заблокированы, потому что они
используются в пределах триггера:
t1
заблокирована для того, чтобы записать.
t2
заблокирована для записи, даже при том, что запрос для
блокировки READ
. Это происходит потому, что t2
вставлена в пределах триггера, таким образом, запрос READ
преобразован в запрос WRITE
.t3
заблокирована для того, чтобы читать, потому что это
только считано изнутри триггера.t4
заблокирован для того, чтобы записать, потому что это
могло бы быть обновлено в пределах триггера.Вы можете безопасно использовать KILL
, чтобы закончить сеанс, который ждет табличной блокировки. См.
раздел 14.7.6.4.
LOCK TABLES
и
UNLOCK TABLES
не может использоваться в пределах сохраненных программ.
Таблица в performance_schema
не может быть заблокирована с
LOCK TABLES
, кроме таблиц
setup_
.xxx
Следующие запросы запрещены в то время, как
LOCK TABLES
работает:
CREATE TABLE
,
CREATE TABLE ... LIKE
,
CREATE VIEW
,
DROP VIEW
и запросы DDL
о сохраненных функциях, процедурах и событиях.
Для некоторых операций нужно получить доступ к системным таблицам в
базе данных mysql
. Например,
HELP
требует содержания серверных таблиц справки, и
CONVERT_TZ()
,
возможно, должен был бы считать таблицы часового пояса. Сервер неявно
блокирует системные таблицы для того, чтобы читать по мере необходимости так,
чтобы Вы не заблокировали их явно. Эти таблицы обработаны так:
mysql.help_category mysql.help_keyword mysql.help_relation mysql.help_topic mysql.proc mysql.time_zone mysql.time_zone_leap_second mysql.time_zone_name mysql.time_zone_transition mysql.time_zone_transition_typeЕсли Вы хотите явно поместить блокировку
WRITE
блокируйте любую из тех таблиц с LOCK
TABLES
, таблица должна быть единственной заблокированной, никакая
другая таблица не может быть заблокирована с тем же самым запросом.
Обычно Вы не должны заблокировать таблицы, потому что весь
UPDATE
атомный,
никакой другой сеанс не может вмешаться ни в какой другой в настоящее время
выполняющийся запрос SQL. Однако, есть несколько случаев, когда блокировка
таблиц может обеспечить преимущество:
Если Вы собираетесь выполнить много операций на ряде таблиц
MyISAM
, намного быстрее заблокировать таблицы, которые Вы
собираетесь использовать. Блокировка MyISAM
ускоряют вставку, обновление или удаление на них, потому что MySQL не
сбрасывает ключевой кэш для заблокированных таблиц до
UNLOCK TABLES
.
Обычно ключевой кэш сбрасывается после каждого запроса SQL.
Никакой сеанс не может обновить заблокированную как READ
таблица (включая тот, который держит блокировку), и никакой сеанс не может
получить доступ к заблокированной как WRITE
таблице кроме держащего блокировку.
LOCK TABLES
, если Вы хотите гарантировать, что никакой другой сеанс не изменяет
таблицы между SELECT
и
UPDATE
. Пример, показанный здесь,
требует LOCK TABLES
,
чтобы выполнять безопасно:
LOCK TABLES trans READ, customer WRITE; SELECT SUM(value) FROM trans WHERE customer_id=Безsome_id
; UPDATE customer SET total_value=sum_from_previous_statement
WHERE customer_id=some_id
; UNLOCK TABLES;
LOCK TABLES
возможно, что другой сеанс мог бы вставить новую строку в таблицу
trans
между SELECT
и
UPDATE
.Вы можете избегать использования LOCK
TABLES
во многих случаях при использовании относительных
обновлений (UPDATE customer SET
) или функции
value
=value
+
new_value
LAST_INSERT_ID()
.
Вы можете также избежать блокировать таблицы в некоторых случаях при
использовании консультативных функций блокировки на уровне пользователя
GET_LOCK()
и
RELEASE_LOCK()
.
Эти блокировки сохранены в хэш-таблице в сервере и осуществлены с
pthread_mutex_lock()
и
pthread_mutex_unlock()
, см.
раздел 13.18.
См. раздел 9.11.1.
SET [GLOBAL | SESSION] TRANSACTIONЭто запрос определяет параметры транзакции. Это берет список из одного или более значений, отделенных запятыми. Эти характеристики устанавливают операционный уровень изоляции или режим доступа. Уровень изоляции используется для операций наtransaction_characteristic
[,transaction_characteristic
] ...transaction_characteristic
: ISOLATION LEVELlevel
| READ WRITE | READ ONLYlevel
: REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED | SERIALIZABLE
InnoDB
. Режим доступа может быть
определен относительно того, работают ли транзакции в чтении-записи или
режиме только для чтения.
Кроме того, SET TRANSACTION
может включать дополнительный параметр GLOBAL
или
SESSION
, чтобы указать на контекст запроса.
Вы можете установить операционные характеристики глобально, для текущего сеанса или для следующей транзакции:
С GLOBAL
запрос применяется глобально для всех
последующих сеансов. Существующие сеансы не затронуты.
SESSION
запрос относится ко всем последующим транзакциям,
выполненным в пределах текущего сеанса.SESSION
или GLOBAL
запрос относится к следующей транзакции, выполненной в пределах текущего
сеанса. Последующие транзакции возвращаются к использованию
уровня изоляции SESSION
.Глобальное изменение операционных характеристик требует привилегии
SUPER
.
Любой сеанс свободен изменить свои характеристики сеанса (даже в середине
транзакции) или характеристики для следующей транзакции.
SET TRANSACTION
без
GLOBAL
или SESSION
не разрешен, в то время как есть активная транзакция:
mysql> START TRANSACTION; Query OK, 0 rows affected (0.02 sec) mysql> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progressЧтобы установить глобальный уровень изоляции по умолчанию при запуске сервера, используйте опцию
--transaction-isolation=level
для mysqld
в командной строке или в файле опции. Значения level
для этой опции используют тире, а не пробелы, таким образом, допустимые
значения
READ-UNCOMMITTED
,
READ-COMMITTED
,
REPEATABLE-READ
или SERIALIZABLE
. Например, чтобы установить уровень изоляции по умолчанию в
REPEATABLE READ
, используйте эти строки в разделе [mysqld]
файла опций:
[mysqld] transaction-isolation = REPEATABLE-READВозможно проверить или установить глобальные и операционные уровни изоляции сеанса во времени выполнения при использовании
tx_isolation
:
SELECT @@GLOBAL.tx_isolation, @@tx_isolation; SET GLOBAL tx_isolation='REPEATABLE-READ'; SET SESSION tx_isolation='SERIALIZABLE';Точно так же, чтобы установить операционный режим доступа при запуске сервера или во время выполнения, используйте
--transaction-read-only
или
tx_read_only
.
По умолчанию они OFF
(режим чтение-запись), но могут быть
установлен в ON
для режима по умолчанию только для чтения.
Установка глобального значения или значения сеанса
tx_isolation
или
tx_read_only
эквивалентно установке уровня изоляции или режима доступа с
SET GLOBAL TRANSACTION
или
SET SESSION TRANSACTION
.
См. раздел 16.5.2.1.
Операционный режим доступа может быть определен с
SET TRANSACTION
.
По умолчанию, транзакция имеет место в режиме чтения-записи с чтениями и
записями, разрешенными для таблиц, используемых в транзакции. Этот режим
может быть определен, явно используя режим доступа READ WRITE
.
Если операционный режим доступа установлен в READ ONLY
,
изменения таблиц запрещены. Это может позволить механизмам хранения сделать
исполнительные усовершенствования, которые возможны, когда
записи не разрешены.
Не разрешено определить в том же самом запросе READ WRITE
и
READ ONLY
.
В режиме только для чтения остается возможным изменить таблицы,
составленные с TEMPORARY
, используя запросы DML. Изменения,
произведенные с запросами DDL, не разрешены, так же,
как с постоянными таблицами.
READ WRITE
и READ ONLY
также могут быть определены для отдельной транзакции, используя
START TRANSACTION
.
Поддержка транзакций XA
доступна для InnoDB
. MySQL XA
основан на X/Open CAE Distributed Transaction
Processing: The XA Specification. Этот документ издан The Open Group и
доступен на http://www.opengroup.org/public/pubs/catalog/c193.htm.
Ограничения текущего выполнения XA описаны в
раздел C.6.
На стороне клиента нет никаких особых требований. Интерфейс XA к серверу
MySQL состоит из запросов SQL, которые начинаются с XA
.
Программы клиента MySQL должны быть в состоянии послать запросы SQL и понять
семантику интерфейса запросов XA.
Среди MySQL Connectors, MySQL Connector/J 5.0.0 и выше понимает XA непосредственно, посредством интерфейса класса, который обрабатывает интерфейс XA SQL для Вас.
XA поддерживает распределенные транзакции, то есть, способность разрешить многократным отдельным транзакционным ресурсам участвовать в глобальной транзакции. Транзакционные ресурсы часто RDBMS, но могут быть другими видами ресурсов.
Глобальная транзакция вовлекает несколько действий, которые являются
транзакционными в себе, но что все должны завершиться успешно как группа или
все быть откаченными как группа. В основном это расширяет свойства ACID
так, чтобы многократные транзакции могли быть выполнены как компоненты
глобальной работы, у которой также есть свойства ACID. Как с
нераспределенными транзакциями,
SERIALIZABLE
может быть предпочтен, если Ваши приложения
чувствительны, чтобы считать явления.
REPEATABLE READ
, возможно, не достаточно для распределенных транзакций.
Некоторые примеры распределенных транзакций:
Приложение может действовать как инструмент интеграции, который комбинирует службу обмена сообщениями с RDBMS. Приложение удостоверяется, что транзакции, имеющие дело с посылкой сообщения, извлечением и обработкой, которые также вовлекают транзакционную базу данных, все происходят в глобальной транзакции. Вы можете думать об этом как о транзакционной email.
Приложения, которые используют глобальные транзакции, вовлекают одного или более менеджера ресурсов и менеджера транзакций:
Resource Manager (RM) обеспечивает доступ к транзакционным ресурсам. Сервер базы данных это один вид распорядителя ресурсов. Должно быть возможно передать или удалить транзакции, которыми управляет RM.
Выполнение MySQL XA позволяет серверу MySQL действовать как Resource Manager, который обрабатывает транзакции XA в пределах глобальной транзакции. Программа клиента, которая соединяется с действиями сервера MySQL как менеджер по транзакции.
Чтобы выполнить глобальную транзакцию, необходимо знать, какие компоненты вовлечены, и подогнать каждый компонент, когда это может быть передано или удалено. В зависимости от того, как каждый компонент отчитывается о его способности преуспеть, они должны все передать или откатиться как атомная группа. Таким образом, все компоненты должны сработать или откатиться. Чтобы управлять глобальной транзакцией, необходимо принять во внимание, что любой компонент или соединяющаяся сеть могли бы потерпеть неудачу.
Процесс для того, чтобы выполнить глобальную транзакцию использует двухфазовую передачу (2PC). Это имеет место после того, как действия, выполненные ответвлениями глобальной транзакции, были выполнены.
В первой фазе подготовлены все ответвления. Таким образом, им говорит ТМ подготовиться передавать. Как правило, это означает каждый RM, который справляется, ответвление делает запись действий для ответвления в устойчивом хранении. Ответвления указывают, в состоянии ли они сделать это, и эти результаты используются для второй фазы.
В некоторых случаях глобальная транзакция могла бы использовать одну фазу передачи (1PC). Например, когда менеджер по транзакции находит, что глобальная транзакция состоит только из одного транзакционного ресурса (то есть, единственное ответвление), ресурсу можно сказать подготовить и передать в то же самое время.
Чтобы выполнить транзакции XA в MySQL, используйте следующие запросы:
XA {START|BEGIN}Дляxid
[JOIN|RESUME] XA ENDxid
[SUSPEND [FOR MIGRATE]] XA PREPARExid
XA COMMITxid
[ONE PHASE] XA ROLLBACKxid
XA RECOVER [CONVERT XID]
XA START
JOIN
и RESUME
не поддержаны.
Для XA END
SUSPEND [FOR MIGRATE]
не поддержан.
Каждый запрос XA начинается XA
и большинство из них требуют
значения xid
. xid
это
операционный идентификатор XA. Это указывает, к какой транзакции запрос
относится. xid
поставляются клиентом или произведены
сервером MySQL. xid
имеет от одной до трех частей:
xid
:gtrid
[,bqual
[,formatID
]]
gtrid
это глобальный операционный идентификатор,
bqual
спецификатор ответвления, и
formatID
число, которое идентифицирует формат,
используемый gtrid
и bqual
.
Как обозначено синтаксисом, bqual
и
formatID
являются дополнительными. Значение по
умолчанию bqual
''
, если не дано.
Значение по умолчанию formatID
1, если не дано.
gtrid
и bqual
должны быть строками, каждая до 64 байтов (не символов).
gtrid
и bqual
может быть определен несколькими способами. Вы можете использовать
заключенную в кавычки строку ('ab'
), шестнадцатеричную
строку (X'6162'
, 0x6162
) или битовое значение
(b'
).nnnn
'
formatID
unsigned integer.
gtrid
и bqual
интерпретируются в байтах основными подпрограммами поддержки XA сервера
MySQL. Однако, в то время, как запрос SQL, содержащмй запрос XA, разбирается,
сервер работает с некоторым определенным набором символов. Чтобы быть
безопасным, пишите gtrid
и
bqual
как шестнадцатеричные строки.
xid
, как правило, производятся менеджером по
транзакции. Значения, произведенные одним ТМ, должны отличаться от значений,
произведенных другими ТМ. Данный ТМ должен быть в состоянии признать свой
собственный xid
в списке значений, возвращенных
XA RECOVER
.
Для XA START
запускает транзакцию XA с данным
значением xid
xid
. У каждой транзакции XA должно быть
уникальное значение xid
,
таким образом, значение не должно в настоящее время использоваться другой
транзакцией XA. Уникальность оценена, используя gtrid
и
bqual
. Все последующие запросы XA для транзакции XA
должны быть определены, используя то же самое значение
XA START
.
Если Вы используете какое-либо из тех запросов, но определяете
xid
, которое не соответствует некоторой существующей
транзакции XA, ошибка происходит.
Одна или более транзакций XA могут быть частью той же самой глобальной
транзакции. Все транзакции XA в пределах данной глобальной транзакции должны
использовать то же самое значение gtrid
в
xid
. Поэтому значения gtrid
должны быть глобально уникальными так, чтобы не было никакой двусмысленности.
bqual
часть xid
должна отличаться для каждой транзакции XA в пределах глобальной транзакции.
Требование, что значения bqual
должны отличаться,
является ограничением текущего MySQL-выполнения XA.
Это не часть спецификации XA.
XA RECOVER
возвращает информацию для тех транзакций XA на сервере MySQL, которые
находятся в состоянии PREPARED
, см.
раздел 14.3.7.2.
Вывод включает строку для каждой такой транзакции XA на сервере, независимо
от того, который клиент запустил это.
XA RECOVER
выходные строки похожи на это (для примера
xid
состоит из частей
'abc'
, 'def'
и 7
):
mysql> XA RECOVER; +----------+--------------+--------------+--------+ | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+--------+ | 7 | 3 | 3 | abcdef | +----------+--------------+--------------+--------+У выходных столбцов есть следующие значения:
formatID
часть formatID
xid
транзакции.
gtrid_length
длина в байтах gtrid
.
bqual_length
длина в байтах bqual
.
data
конкатенация gtrid
и
bqual
.XID могут содержать непригодные для печати символы.
XA RECOVER
разрешает дополнительный параметр CONVERT XID
так, чтобы клиенты могли просить значения XID в шестнадцатеричном виде.
Транзакция XA прогрессирует через следующие состояния:
Используйте XA
START
, чтобы запустить транзакцию XA и
перевести в статус ACTIVE
.
ACTIVE
транзакций XA сделайте запросы SQL, которые
составляют транзакцию, а затем XA
END
. XA END
отправит транзакцию в состояние IDLE
.IDLE
транзакций XA Вы можете скомандовать
XA PREPARE
или
XA COMMIT ... ONE PHASE
:
XA PREPARE
отправит транзакцию в состояние PREPARED
.
XA RECOVER
будет включать xid
транзакции в его выводе, потому что
XA RECOVER
перечисляет все
транзакции XA, которые находятся в состоянии PREPARED
.
XA COMMIT ... ONE PHASE
готовит и передает транзакцию.
xid
не будет перечислено
XA RECOVER
потому что транзакция заканчивается.PREPARED
XA транзакций Вы можете
скомандовать XA COMMIT
,
чтобы передать и закончить транзакцию, или
XA ROLLBACK
для отката.
Вот простая транзакция XA, которая вставляет строку в таблицу как часть глобальной транзакции:
mysql> XA START 'xatest'; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO mytable (i) VALUES(10); Query OK, 1 row affected (0.04 sec) mysql> XA END 'xatest'; Query OK, 0 rows affected (0.00 sec) mysql> XA PREPARE 'xatest'; Query OK, 0 rows affected (0.00 sec) mysql> XA COMMIT 'xatest'; Query OK, 0 rows affected (0.00 sec)В пределах контекста данного соединения клиента транзакции XA и местные транзакции (не-XA) являются взаимоисключающими. Например, если
XA START
выпущен, чтобы начать транзакцию XA, местная транзакция не может быть
запущена, пока транзакция XA не была передана или отменена. Наоборот, если
местная транзакция была запущена с
START TRANSACTION
,
никакие запросы XA не могут использоваться, пока транзакция не была
передана или отменена.
Если транзакция XA находится в состоянии ACTIVE
,
Вы не можете сделать запросы, которые вызывают неявное закрытие
транзакции. Это нарушило бы контракт XA, потому что Вы не могли удалить
транзакцию XA. Вы получите следующую ошибку, если Вы попытаетесь
выполнить такой запрос:
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE stateЗапросы, к которым применяется предыдущее замечание, перечислены в разделе 14.3.3.
Репликацией можно управлять через интерфейс SQL, используя запросы, описанные в этом разделе. Запросы разделены на группу, которая управляет главными серверами, группу, которая управляет ведомыми серверами, и группу, которая может быть применена к любым серверам.
Этот раздел обсуждает запросы для основных серверов.
В дополнение к запросым, описанным здесь,
запросы SHOW
используются с главными серверами. Для информации об этих запросах см.
раздел 14.7.5.
PURGE { BINARY | MASTER } LOGS { TO 'Двоичный журнал это ряд файлов, которые содержат информацию о модификациях данных, сделанных сервером MySQL. Журнал состоит из ряда двоичных файлов системного журнала плюс индексный файл (см. раздел 6.4.4).log_name
' | BEFOREdatetime_expr
}
PURGE BINARY LOGS
удаляет все двоичные файлы системного журнала, перечисленные в индексном
файле журнала до указанного имени файла системного журнала или даты.
BINARY
и MASTER
синонимы.
Удаленные файлы системного журнала также удалены из списка,
зарегистрированного в индексном файле, так, чтобы данный файл системного
журнала стал первым в списке.
Этот запрос не имеет никакого эффекта, если сервер не был запущен с опцией
--log-bin
.
Примеры:
PURGE BINARY LOGS TO 'mysql-bin.010'; PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26';
BEFORE
разновидность параметра
datetime_expr
должен оцениваться к значению
DATETIME
(значение в формате
'YYYY-MM-DD hh:mm:ss'
).
Этот запрос безопасно выполнить, в то время как ведомые устройства копируют. Вы не должны остановить их. Если у Вас есть активное ведомое устройство, которое в настоящее время читает один из файлов системного журнала, которые Вы пытаетесь удалить, этот запрос ничего не делает и терпит неудачу с ошибкой. Однако, если ведомое устройство не будет соединено, и Вы производите чистку одного из файлов системного журнала, которые это должно все же считать, то ведомое устройство будет неспособно копировать после того, как повторно соединится.
Чтобы безопасно произвести чистку двоичных файлов системного журнала, следуйте за этой процедурой:
На каждом ведомом сервере надо использовать
SHOW SLAVE STATUS
,
чтобы проверить, какой файл системного журнала это читает.
SHOW BINARY LOGS
.Вы можете также установить
expire_logs_days
, чтобы двоичные файлы системного журнала автоматически удалялись после
данного числа дней (см. раздел
6.1.5). Если Вы используете репликацию, Вы должны установить переменную
не ниже, чем максимальное количество дней, на которое Ваши ведомые устройства
могли бы отстать от ведущего устройства.
PURGE BINARY LOGS TO
и PURGE BINARY LOGS BEFORE
оба терпят неудачу с ошибкой, когда двоичные файлы системного журнала,
перечисленные в файле .index
, были удалены из системы некоторыми
другими средствами (такими, как использование
rm в Linux) (Bug #18199, Bug #18453).
Чтобы обработать такие ошибки, редактируйте файл .index
(который является простым текстовым файлом) вручную, чтобы гарантировать, что
он перечисляет только двоичные файлы системного журнала, которые фактически
присутствуют, затем выполните снова
PURGE BINARY LOGS
.
RESET MASTERУдаляет все двоичные файлы системного журнала, перечисленные в индексном файле, сбрасывает двоичной индексный файл журнала и создает новый двоичной файл системного журнала.
RESET MASTER
также очищает значения
gtid_purged
так же как глобальное значение
gtid_executed
(но не ее значение сеанса), то есть, выполнение этого запроса устанавливает
каждое из этих значений к пустой строке (''
).
Этот запрос также очищает таблицу mysql.gtid_executed
(см.
mysql.gtid_executed Table).
Это запрос предназначен, чтобы использоваться только, когда ведущее устройство запущено впервые.
Эффекты RESET MASTER
отличаются от таковых в PURGE
BINARY LOGS
:
RESET MASTER
удаляет все двоичные файлы системного журнала,
которые перечислены в индексном файле, оставляя только единственный пустой
двоичной файл системного журнала с числовым суффиксом .000001
,
тогда как нумерация не сброшена
PURGE BINARY LOGS
.
RESET MASTER
не предназначен, чтобы использоваться, в то время
как любые ведомые устройства работают. Поведение
RESET MASTER
когда используется в то время, как ведомые устройства работают, неопределено
(и таким образом неподдержано), тогда как
PURGE BINARY LOGS
может безопасно использоваться в то время, как ведомые устройства работают.
См. раздел 14.4.1.1.
RESET MASTER
может оказаться полезным, когда Вы сначала настраиваете ведущее и ведомое
устройства, чтобы Вы могли проверить установку следующим образом:
Запустите ведущее и ведомое устройства и запустите репликацию (см. раздел 19.1.2).
STOP SLAVE
и
RESET SLAVE
на ведомом устройстве, затем проверьте, что любые нежелательные данные больше
не существуют на ведомом устройстве.RESET MASTER
на ведущем устройстве, чтобы очистить испытательные запросы.После подтверждения установки и избавления от файлов системного журнала, произведенных в ходе проверки, Вы можете запустить ведомое устройство и начать копировать.
SET sql_log_bin = {0|1}
sql_log_bin
управляет, сделано ли журналирование к двоичному журналу. Значение по
умолчанию 1 (сделано журналирование). Чтобы изменить журналирование для
текущего сеанса, измените значение этой переменной. Пользователь сеанса
должен иметь привилегию SUPER
, чтобы установить эту переменную. Установите эту переменную в 0 для
сеанса, чтобы временно отключить двоичное журналирование, производя изменения
в ведущем устройстве, которые Вы не хотите копировать к ведомому устройству.
С MySQL 5.5 sql_log_bin
может быть установлен как глобальная переменная или переменная
сеанса. Установка sql_log_bin
глобально обнаружена только, когда новый сеанс запущен. На любые
ранее работающие сеансы глобальная установка не воздействует.
Неправильное использование
sql_log_bin
с глобальными средствами контекста любые изменения,
произведенные в уже рабочем сеансе все еще
регистрируются в двоичном журнале и поэтому копируются. Это может
вызвать неожиданные результаты, включая отказ репликации.
В MySQL 5.7 невозможно установить
@@session.sql_log_bin
в пределах транзакции или подзапроса (Bug #53437).
В дополнение к запросам, описанным здесь,
SHOW SLAVE STATUS
и
SHOW RELAYLOG EVENTS
также используются с ведомыми устройствами ответа. Для информации об этих
запросах см. разделы 14.7.5.34 и
14.7.5.32.
CHANGE MASTER TOoption
[,option
] ... [channel_option
]option
: MASTER_BIND = 'interface_name
' | MASTER_HOST = 'host_name
' | MASTER_USER = 'user_name
' | MASTER_PASSWORD = 'password
' | MASTER_PORT =port_num
| MASTER_CONNECT_RETRY =interval
| MASTER_RETRY_COUNT =count
| MASTER_DELAY =interval
| MASTER_HEARTBEAT_PERIOD =interval
| MASTER_LOG_FILE = 'master_log_name
' | MASTER_LOG_POS =master_log_pos
| MASTER_AUTO_POSITION = {0|1} | RELAY_LOG_FILE = 'relay_log_name
' | RELAY_LOG_POS =relay_log_pos
| MASTER_SSL = {0|1} | MASTER_SSL_CA = 'ca_file_name
' | MASTER_SSL_CAPATH = 'ca_directory_name
' | MASTER_SSL_CERT = 'cert_file_name
' | MASTER_SSL_CRL = 'crl_file_name
' | MASTER_SSL_CRLPATH = 'crl_directory_name
' | MASTER_SSL_KEY = 'key_file_name
' | MASTER_SSL_CIPHER = 'cipher_list
' | MASTER_SSL_VERIFY_SERVER_CERT = {0|1} | MASTER_TLS_VERSION = 'protocol_list
' | IGNORE_SERVER_IDS = (server_id_list
)channel_option
: FOR CHANNELchannel
server_id_list
: [server_id
[,server_id
] ... ]
CHANGE MASTER TO
изменяет параметры, которые ведомый сервер использует для того, чтобы
соединиться с главным сервером, для того, чтобы считать основной двоичной
журнал и считать ведомый журнал. Это также обновляет содержание основной
информации и репозитариев информации журнала (см.
раздел 19.2.4).
Можно использовать CHANGE MASTER TO
запрос о рабочем ведомом устройстве без остановки этого, в зависимости от
статуса ведомого потока SQL и ведомого потока ввода/вывода. Правила,
управляющие таким использованием, обеспечены позже в этом разделе.
Используя мультипоточное ведомое устройство (другими словами,
slave_parallel_workers
больше 0), остановка ведомого устройства
может вызвать промежутки в последовательности
транзакций, которые были выполнены от журнала, независимо от того, было ли
ведомое устройство остановлено преднамеренно или нет. Когда такие промежутки
существуют, CHANGE MASTER TO
терпит неудачу. Решение в этой ситуации состоит в том, чтобы вызвать
START SLAVE UNTIL SQL_AFTER_MTS_GAPS
, который гарантирует, что разрывы преодолены.
FOR CHANNEL
позволяет Вам выбрать, к которому каналу ответа относится запрос. Если
никакой пункт не установлен, и никакие дополнительные каналы не существуют,
запрос относится к каналу значения по умолчанию и ведет себя как версии MySQL
до 5.7.6. Обеспечение channel
FOR CHANNEL
применяет channel
CHANGE MASTER TO
к определенному каналу ответа и
используется, чтобы добавить новый канал или изменить существующий канал.
Например, чтобы добавить новый канал, названный channel2:
CHANGE MASTER TO MASTER_NAME=host1, MASTER_PORT=3002 FOR CHANNEL channel2Используя многократные каналы ответа, если у
CHANGE MASTER TO
нет определенного использования канала FOR CHANNEL channel
, получите ошибку. См.
раздел 19.2.3.
Опции, не определенные, сохраняют свое значение, за исключением обозначенного в следующем обсуждении. Таким образом, в большинстве случаев нет никакой потребности определить опции, которые не изменяются.
MASTER_HOST
, MASTER_USER
,
MASTER_PASSWORD
и MASTER_PORT
предоставляют информацию ведомому устройству о том, как соединиться с
его ведущим устройством:
MASTER_HOST
и MASTER_PORT
имя хоста (или IP-адрес) основного узла и его порта TCP/IP.
Репликация не может использовать файлы сокета Unix. Вы должны быть в состоянии соединиться с сервером ведущего устройства, используя TCP/IP.
Если Вы определяете MASTER_HOST
или MASTER_PORT
,
ведомое устройство предполагает, что главный сервер отличается (даже если
значение опции то же самое, как текущее). В этом случае старые значения для
имени файла основного двоичного системного журнала и позиции больше не
считают применимыми, так, если Вы не определяете
MASTER_LOG_FILE
и MASTER_LOG_POS
в команде,
MASTER_LOG_FILE=''
и MASTER_LOG_POS=4
тихо приложены к этому.
Установка MASTER_HOST=''
(то есть, устанавливая его значение
явно в пустую строку) не то же самое, как не установка
MASTER_HOST
вообще. Начиная с MySQL 5.5, попытка установить
MASTER_HOST
к пустой строке терпит неудачу с ошибкой. Ранее
установка MASTER_HOST
к пустой строке вызывала впоследствии сбой
START SLAVE
(Bug #28796).
Значения, используемые для MASTER_HOST
и других опций
CHANGE MASTER TO
проверены на перевод строки (\n
или 0x0A
), присутствие таких символов в этих значениях
заставляет запрос терпеть неудачу с
ER_MASTER_INFO (Bug #11758581, Bug #50801).
MASTER_USER
и MASTER_PASSWORD
имя пользователя и пароль учетной записи, чтобы использовать для того, чтобы
соединиться с ведущим устройством.
MASTER_USER
не может быть сделан пустым, установка
MASTER_USER = ''
вызывает ошибку (Bug #13427949).
Пароль используется для ведомой учетной записи MySQL Replication
в CHANGE MASTER TO
ограничен 32 символами в длину,
попытка использовать пароль больше 32 символов приведет к сбою
CHANGE MASTER TO
.
До MySQL 5.7.5, если пароль был более длинным, запрос работал, но любые лишние символы было тихо усечены.
Текст выполнения CHANGE MASTER
TO
, включая значения для MASTER_USER
и
MASTER_PASSWORD
, может быть виден в выводе параллельного
SHOW PROCESSLIST
.
Полный текст START SLAVE
также видим в SHOW PROCESSLIST
.
Опции MASTER_SSL_
предоставляют информацию об использовании SSL для соединения. Они
соответствуют опциям xxx
--ssl-
, описанным
в разделах 7.4.5 и
19.3.9.
Эти опции могут быть изменены даже на ведомых устройствах, которые собраны
без поддержки SSL. Они сохранены к основному репозитарию информации, но
проигнорированы, если у ведомого устройства нет поддержки SSL.xxx
MASTER_SSL=1
является предписывающим, не консультативным.
Когда дано, соединение с ведущим устройством должно использовать SSL, или
попытка соединения терпит неудачу.
MASTER_TLS_VERSION
определяет протоколы шифрования,
разрешенные ведущим устройством для ведомых соединений. Значение походит на
это для tls_version
:
список разделенных запятой значений, содержащий одно или более имен
протокола. Протоколы, которые могут быть названы в этой опции, зависят от
библиотеки SSL, использовавшейся, чтобы собрать MySQL. Для деталей см.
раздел 7.4.3.
MASTER_CONNECT_RETRY
определяет, сколько секунд ждать между
повторениями соединения. Значение по умолчанию 60.
MASTER_RETRY_COUNT
ограничивает number
число попыток пересоединения и обновляет значение столбца
Master_Retry_Count
в выводе
SHOW SLAVE STATUS
.
Значение по умолчанию 24 * 3600 = 86400. MASTER_RETRY_COUNT
предназначена, чтобы заменить более старую опцию
--master-retry-count
и является теперь привилегированным методом
для того, чтобы установить этот предел. Лучше не использовать
--master-retry-count
в новых приложениях и, обновляясь до MySQL
8.0, обновить любые существующие приложения, которые полагаются на это, так,
чтобы они использовали CHANGE MASTER TO ... MASTER_RETRY_COUNT
.
MASTER_DELAY
определяет, на сколько секунд от ведущего
устройства ведомое устройство должно отстать. Событие от ведущего устройства
не запущено, по крайней мере, interval
секунд. Значение по умолчанию 0. Ошибка происходит, если
interval
не неотрицательное целое число в диапазоне
от 0 до 231-1. См.
раздел 19.3.11.
CHANGE MASTER TO
, использующий опцию
MASTER_DELAY
может быть выполнен на рабочем ведомом устройстве,
когда ведомый поток SQL остановлен.
MASTER_BIND
для использования на ведомых устройствах, имеющих
многократные сетевые интерфейсы, и определяет, какой из сетевых интерфейсов
ведомого устройства выбран для того, чтобы соединиться с ведущим устройством.
Адрес, сконфигурированный с этой опцией, если таковой вообще имеется,
может быть найден в столбце Master_Bind
вывода
SHOW SLAVE STATUS
.
Если Вы используете ведомые таблицы журнала состояния (сервер запускался с
--master-info-repository=TABLE
), значение может также быть найдено
как столбец Master_bind
таблицы mysql.slave_master_info
.
MASTER_HEARTBEAT_PERIOD
устанавливает интервал в секундах
между тактами репликации. Всякий раз, когда двоичной журнал ведущего
устройства обновлен, время ожидания для следующего такта сброшено.
interval
это десятичное значение, имеющее диапазон от 0
до 4294967 секунд и разрешение в миллисекунду, самое маленькое ненулевое
значение 0.001. Такты посылает ведущее устройство, только если нет никаких
непосланных событий в двоичном файле системного журнала в течение
периода дольше interval
.
Если Вы регистрируете основную информацию о соединении к таблицам,
MASTER_HEARTBEAT_PERIOD
может быть замечен как значение столбца
Heartbeat
таблицы mysql.slave_master_info
.
Установка interval
к 0 отключает такты вообще.
Значение по умолчанию для interval
равно значению
slave_net_timeout
, разделенному на 2.
Установка @@global.slave_net_timeout
к значению меньше текущего интервала приводит к предупреждению. Эффект
RESET SLAVE
на интервал должен сбросить это к значению по умолчанию.
MASTER_LOG_FILE
и MASTER_LOG_POS
координаты, в которых ведомый поток ввода/вывода должен начать читать от
ведущего устройства в следующий раз, когда поток запускается.
RELAY_LOG_FILE
и RELAY_LOG_POS
координаты, в которых ведомый поток SQL должен начать читать из журнала реле
в следующий раз, когда поток запускается. Если Вы определяете любой из
MASTER_LOG_FILE
или MASTER_LOG_POS
,
Вы не можете определить RELAY_LOG_FILE
или
RELAY_LOG_POS
. Если Вы определяете любой из
MASTER_LOG_FILE
или MASTER_LOG_POS
,
Вы также не можете определить MASTER_AUTO_POSITION = 1
(описан позже в этом разделе). Если ни один из MASTER_LOG_FILE
или MASTER_LOG_POS
не определен, ведомое устройство использует
последние координаты ведомого потока SQL перед
CHANGE MASTER TO
.
Это гарантирует, что нет никакой неоднородности в ответе, даже если ведомый
поток SQL был позже по сравнению с ведомым потоком ввода/вывода, когда Вы
просто хотите изменить, скажем, пароль.
CHANGE MASTER TO
, использующий опции
RELAY_LOG_FILE
, RELAY_LOG_POS
или обе сразу,
может быть выполнен на рабочем ведомом устройстве, когда ведомый
поток SQL остановлен.
Если MASTER_AUTO_POSITION = 1
с CHANGE MASTER TO
, ведомое устройство пытается соединиться с ведущим устройством,
использующим протокол GTID. Эта опция может использоваться
CHANGE MASTER TO
только, если ведомый SQL и ведомые потоки
ввода/вывода остановлены.
Используя GTID, ведомое устройство говорит ведущему устройству, какие
транзакции это уже приняло, выполнило или то и другое. Чтобы вычислить этот
набор, это читает глобальное значение
gtid_executed
и значение столбца Retrieved_gtid_set
из
SHOW SLAVE STATUS
.
Так как GTID последней переданной транзакции включен в
Retrieved_gtid_set
, даже если транзакция была только частично
передана, последний полученный GTID вычтен из этого набора. Таким образом,
ведомое устройство вычисляет следующий набор:
UNION(@@global.gtid_executed, Retrieved_gtid_set-last_received_GTID
)
Этот набор посылают ведущему устройству как часть начального квитирования,
а ведущее устройство отсылает назад все транзакции, которые выполнило, но
которые не являются частью набора. Если какая-либо из этих транзакций была
уже удалена из двоичного журнала ведущего устройства, ведущее устройство
посылает ошибку ER_MASTER_HAS_PURGED_REQUIRED_GTIDS, и
репликация не запускается.
Когда GTID-репликация используется, координаты, представленные
MASTER_LOG_FILE
и MASTER_LOG_POS
не используются, и глобальные операционные идентификаторы используются вместо
этого. Таким образом использование обеих опций вместе с
MASTER_AUTO_POSITION
будет ошибкой.
Вы можете видеть, работает ли ответ с автопозиционированием, проверяя
вывод SHOW SLAVE STATUS
.
gtid_mode
должен также быть включен перед CHANGE MASTER TO ...
MASTER_AUTO_POSITION = 1
. Иначе запрос терпит неудачу с ошибкой.
Чтобы вернуться к более старому основанному на файле протоколу после
использования GTID, Вы можете скомандовать CHANGE MASTER TO
,
который определяет MASTER_AUTO_POSITION = 0
,
так же как по крайней мере один из MASTER_LOG_FILE
или
MASTER_LOG_POSITION
.
Журналы реле сохранены, когда ни ведомый поток SQL, ни ведомый поток
ввода/вывода не остановлены, если оба потока остановлены, все файлы
системного журнала реле не удалены, если Вы указали по крайней мере одну из
опций RELAY_LOG_FILE
или RELAY_LOG_POS
.
RELAY_LOG_FILE
может использовать абсолютный или
относительный путь, и использует то же самое базовое имя, как
MASTER_LOG_FILE
(Bug #12190).
IGNORE_SERVER_IDS
берет список разделенных запятой значений
из 0 или больше ID сервера. События, происходящие из соответствующих
серверов, проигнорированы, за исключением событий ротации
и удаления журнала, которые все еще зарегистрированы в журнале реле.
В круговой репликации оригинальный сервер обычно действует как разделитель
его собственных событий, чтобы они не были применены не раз. Таким образом,
эта опция полезна в круговой рпликации, когда один из серверов удален.
Предположите, что у Вас есть круговая установка репликации с 4 серверами,
ID 1, 2, 3 и 4, а сервер 3 упал. Соединяя промежуток, запуская репликацию с
сервера 2 на сервер 4, Вы можете включить IGNORE_SERVER_IDS = (3)
в CHANGE MASTER TO
на сервере 4, чтобы сказать этому использовать сервер 2 в качестве его
ведущего устройства вместо сервера 3. Это причина проигнорировать, а не
размножить любые запросы, которые произошли с сервером, который больше
не находится в использовании.
Если CHANGE MASTER TO
без IGNORE_SERVER_IDS
, любой существующий список сохранен. Чтобы
очистить список проигнорированных серверов, необходимо использовать
опцию с пустым списком:
CHANGE MASTER TO IGNORE_SERVER_IDS = ();
RESET SLAVE ALL
очищает
IGNORE_SERVER_IDS
. До MySQL 5.7 это не сделано.
Если IGNORE_SERVER_IDS
содержит ID сервера, и сервер был
запущен с
--replicate-same-server-id
, будет ошибка.
В MySQL 8.0 основной репозитарий информации и вывод
SHOW SLAVE STATUS
обеспечивает список серверов, которые в настоящее время игнорируются. Для
получения дополнительной информации см. разделы
19.2.4.2 и
14.7.5.34.
В MySQL 8.0 вызов CHANGE
MASTER TO
вызывает запись предыдущих значений
MASTER_HOST
, MASTER_PORT
,
MASTER_LOG_FILE
и MASTER_LOG_POS
в журнал ошибок, наряду с другой информацией о статусе ведомого
устройства до выполнения.
В MySQL 8.0 CHANGE MASTER TO
неявно закрывает
продолжающиеся транзакции. См. раздел
14.3.3.
Строгое требование, чтобы выполнить
STOP SLAVE
до любого
CHANGE MASTER TO
(и START
SLAVE
позже) удалено. Вместо этого, в зависимости от того,
остановлено ли ведомое устройство, логика CHANGE MASTER TO
зависит от статуса ведомого потока SQL и ведомых потоков ввода/вывода, какой
из этих потоков остановлен или работает, теперь определяют опции, которые
могут или не могут использоваться с CHANGE MASTER TO
в данном моменте времени. Правила для того, чтобы сделать это
определение перечислены здесь:
Если поток SQL остановлен, Вы можете выполнить
CHANGE MASTER TO
с использованием любой комбинации, которая
допускается RELAY_LOG_FILE
, RELAY_LOG_POS
и
MASTER_DELAY
, даже если ведомый поток ввода/вывода работает.
Никакие другие опции не могут использоваться с этим запросом, когда поток
ввода/вывода работает.
CHANGE MASTER TO
с использованием любой из опций для этого
запросы (в любой позволенной комбинации) кроме
RELAY_LOG_FILE
, RELAY_LOG_POS
или
MASTER_DELAY
, даже когда поток SQL работает. Эти три опции не
могут использоваться, когда поток ввода/вывода работает.CHANGE MASTER TO
, который использует
MASTER_AUTO_POSITION = 1
.Вы можете проверить текущее состояние ведомого SQL и потоков
ввода/вывода с использованием
SHOW SLAVE STATUS
.
См. раздел 19.3.8.
Если Вы используете основанную на запросе репликацию
и временные таблицы, это возможно для CHANGE MASTER TO
после
STOP SLAVE
оставить позади временные таблицы на ведомом
устройстве. Предупреждение (ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO
) теперь выпущено всякий раз, когда это происходит. Вы можете избежать
этого удостоверяясь, что значение
Slave_open_temp_tables
= 0 до выполнения такого
CHANGE MASTER TO
.
CHANGE MASTER TO
полезно для установки ведомого устройства, когда Вы имеете снимок ведущего
устройства и сделали запись основных двоичных координат журнала,
соответствующих времени снимка. После загрузки снимка в ведомое устройство,
чтобы синхронизировать это с ведущим устройством, Вы можете выполнить
CHANGE MASTER TO MASTER_LOG_FILE='
на ведомом устройстве,
чтобы определить координаты, в которых ведомое устройство должно начать
читать основной двоичной журнал.log_name
',
MASTER_LOG_POS=log_pos
Следующий пример изменяет главный сервер, который использует ведомое устройство и устанавливает основные двоичные координаты журнала, из которых ведомое устройство начинает читать. Это используется, когда Вы хотите настроить ведомое устройство, чтобы копировать ведущее устройство:
CHANGE MASTER TO MASTER_HOST='master2.mycompany.com', MASTER_USER='replication', MASTER_PASSWORD='bigs3cret', MASTER_PORT=3306, MASTER_LOG_FILE='master2-bin.001', MASTER_LOG_POS=4, MASTER_CONNECT_RETRY=10;Следующий пример показывает работу, которая менее часто используется. Это используется, когда у ведомого устройства есть файлы системного журнала реле, которые Вы хотите, чтобы это выполнило снова по некоторым причинам. Вы должны использовать только
CHANGE
MASTER TO
и запустите поток SQL (START SLAVE SQL_THREAD
):
CHANGE MASTER TO RELAY_LOG_FILE='slave-relay-bin.006', RELAY_LOG_POS=4025;Вы можете даже использовать вторую операцию в установке без репликации с автономным, неведомым, сервером для восстановления после катастрофического отказа. Предположите, что Ваш сервер отказал, и Вы восстановили его из резервной копии. Вы хотите переиграть собственные двоичные файлы системного журнала сервера (не файлы системного журнала реле, а регулярные двоичные файлы системного журнала), названные (например)
myhost-bin.*
.
Во-первых, сделайте резервную копию этих двоичных файлов системного журнала в
некотором безопасном месте, в случае, если Вы точно не следуете за процедурой
ниже и случайно имеете чистку двоичного журнала сервера. Используйте
SET GLOBAL relay_log_purge=0
для дополнительной безопасности. Тогда запустите сервер без опции
--log-bin
,
вместо этого используйте
--replicate-same-server-id
,
--relay-log=myhost-bin
(чтобы заставить сервер полагать, что эти регулярные двоичные
файлы системного журнала это файлы системного журнала реле), и
--skip-slave-start
. После того, как сервер запускается,
сделайте эти запросы:
CHANGE MASTER TO RELAY_LOG_FILE='myhost-bin.153', RELAY_LOG_POS=410, MASTER_HOST='some_dummy_string'; START SLAVE SQL_THREAD;Сервер читает и выполняет свои собственные двоичные файлы системного журнала, таким образом достигая восстановления катастрофического отказа. Как только восстановление закончено, выполните
STOP SLAVE
,
закройте сервер, очистите основную информацию и репозитарии информации
журнала реле, и перезапустите сервер с его оригинальными опциями.
Определение MASTER_HOST
(даже с фиктивным значением) обязано
заставлять сервер думать, что это ведомое устройство.
Следующая таблица показывает максимальную допустимую длину строк опций.
Опция | Максимальная длина |
---|---|
MASTER_HOST | 60 |
MASTER_USER | 16 |
MASTER_PASSWORD | 32 |
MASTER_LOG_FILE | 255 |
RELAY_LOG_FILE | 255 |
MASTER_SSL_CA | 255 |
MASTER_SSL_CAPATH | 255 |
MASTER_SSL_CERT | 255 |
MASTER_SSL_CRL | 255 |
MASTER_SSL_CRLPATH | 255 |
MASTER_SSL_KEY | 255 |
MASTER_SSL_CIPHER | 511 |
CHANGE REPLICATION FILTERfilter
[,filter
][, ...]filter
: REPLICATE_DO_DB = (db_list
) | REPLICATE_IGNORE_DB = (db_list
) | REPLICATE_DO_TABLE = (tbl_list
) | REPLICATE_IGNORE_TABLE = (tbl_list
) | REPLICATE_WILD_DO_TABLE = (wild_tbl_list
) | REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list
) | REPLICATE_REWRITE_DB = (db_pair_list
)db_list
:db_name
[,db_name
][, ...]tbl_list
:db_name.table_name
[,db_table_name
][, ...]wild_tbl_list
: 'db_pattern.table_pattern
'[, 'db_pattern.table_pattern
'][, ...]db_pair_list
: (db_pair
)[, (db_pair
)][, ...]db_pair
:from_db
,to_db
CHANGE REPLICATION FILTER
определяет один или более фильтров на ведомом устройстве таким же образом,
как при запуске ведомого устройства
mysqld с опциями фильтрации
--replicate-do-db
или
--replicate-wild-ignore-table
.
В отличие от случая с параметрами сервера, этот запрос не требует перезапуска
сервера, чтобы вступить в силу, только чтобы ведомый поток SQL был
остановлен, используя STOP SLAVE
SQL_THREAD
(и перезапущен через
START SLAVE SQL_THREAD
).
Следующий список показывает опции CHANGE REPLICATION FILTER
,
и как они касаются параметров сервера --replicate-*
:
REPLICATE_DO_DB
: Включить обновления, основанные на
имени базы данных. Эквивалент
--replicate-do-db
.
REPLICATE_IGNORE_DB
: Исключить обновления, основанные на
имени базы данных. Эквивалент
--replicate-ignore-db
.REPLICATE_DO_TABLE
: Включить обновления, основанные на
имени таблицы. Эквивалент
--replicate-do-table
.REPLICATE_IGNORE_TABLE
: Исключить обновления, основанные на
имени таблицы. Эквивалент
--replicate-ignore-table
.REPLICATE_WILD_DO_TABLE
: Включить обновления, основанные на
на подстановочном образце, соответствующем имени таблицы. Эквивалент
--replicate-wild-do-table
.REPLICATE_WILD_IGNORE_TABLE
: Исключить обновления,
основанные на на подстановочном образце, соответствующем имени таблицы.
Эквивалент
--replicate-wild-ignore-table
.REPLICATE_REWRITE_DB
: Выполнить обновления на ведомом
устройстве после замены новым именем на ведомом устройстве для указанной базы
данных по ведущему устройству. Эквивалент
--replicate-rewrite-db
.Точные эффекты REPLICATE_DO_DB
и REPLICATE_IGNORE_DB
зависят от того, основана репликация на запросе или на строке в
действительности. См. раздел 19.2.5
.
Многократные правила фильтрации ответа могут быть созданы в одном запросе
CHANGE REPLICATION FILTER
, отделяя правила запятыми,
как показано здесь:
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (d1), REPLICATE_IGNORE_DB = (d2);Это эквивалентно запуску ведомого устройства mysqld с опциями
--replicate-do-db=d1
и
--replicate-ignore-db=d2
.
Если то же самое правило фильтрации определено многократно, только
последнее такое правило фактически используется.
Например, эти два запросы, показанные здесь, имеют точно тот же самый эффект,
потому что первое правило REPLICATE_DO_DB
в первом запросе проигнорировано:
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1, db2), REPLICATE_DO_DB = (db3, db4); CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db3,db4);
Это поведение отличается от поведения из опции фильтра
--replicate-*
, где определение той же самой опции много раз
вызывает создание многократных правил фильтра.
Названия таблиц и базы данных, не содержащих любых специальных
символов, не должны быть заключены в кавычки. Значения, используемые с
REPLICATION_WILD_TABLE
и
REPLICATION_WILD_IGNORE_TABLE
это
строковые выражения, возможно, содержащие (специальные) подстановочные
символы, и должны быть заключены в кавычки.
Это показывают в следующих запросах в качестве примера:
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.old%'); CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('db1.new%', 'db2.new%');Значения, используемые с
REPLICATE_REWRITE_DB
это
пары имен базы данных,
каждое такое значение должно быть приложено в круглых скобках. Следующий
запрос переписывает запросы, происходящие в базе данных
dbA
в базу данных dbB
:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2));Запрос содержит два набора круглых скобок, один включает пару имен базы данных, другой весь список. Это более легко видно в следующем примере, который создает два правила
rewrite-db
,
одно переписывает база данных dbA
в dbB
, второе
переписывает базу данных dbC
в dbD
:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((dbA, dbB), (dbC, dbD));Этот запрос оставляет любые существующие правила фильтрации неизменными, чтобы сбросить все фильтры данного типа, установите значение фильтра в явно пустой список, как показано в этом примере, который удаляет все существующие правила
REPLICATE_DO_DB
и REPLICATE_IGNORE_DB
:
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (), REPLICATE_IGNORE_DB = ();Установка фильтра таким образом удаляет все существующие правила, не создает новых и не восстанавливает набор правил при использовании запуска mysqld с опциями
--replicate-*
.
Значения, используемые с REPLICATE_WILD_DO_TABLE
и
REPLICATE_WILD_IGNORE_TABLE
, должны быть в формате
.
db_name
.tbl_name
См. раздел 19.2.5.
SELECT MASTER_POS_WAIT('Это фактически функция, не запрос. Это используется, чтобы гарантировать, что ведомое устройство считало и запустило события до данной позиции в двоичном журнале ведущего устройства. См. раздел 13.18.master_log_file
',master_log_pos
[,timeout
][,channel
])
RESET SLAVE [ALL] [channel_option
]channel_option
: FOR CHANNELchannel
RESET SLAVE
заставляет ведомое устройство забыть свою позицию в двоичном журнале ведущего
устройства. Этот запрос предназначается для чистого запуска: это очищает
основную информацию и репозитарии информации журнала реле, удаляет все файлы
системного журнала реле и запускает новый файл системного журнала реле. Это
также сбрасывает к 0 задержку, определенную опцией
MASTER_DELAY
в CHANGE MASTER TO
. Чтобы использовать
RESET SLAVE
, ведомые потоки
должны быть остановлены (с использованием
STOP SLAVE
в случае необходимости).
Все файлы системного журнала реле удалены, даже если они не были полностью
выполнены ведомым потоком SQL. Это условие, чтобы существовать на ведомом
устройстве ответа, если Вы выполнили STOP
SLAVE
или если ведомое устройство чрезвычайно загружено.
Опция FOR CHANNEL
позволяет Вам выбрать, к которому каналу ответа относится запрос. Если
никакой пункт не установлен, и никакие дополнительные каналы не существуют,
запрос относится к каналу по умолчанию и ведет себя как версии MySQL до
5.7.6. Обеспечение channel
FOR CHANNEL
применяет channel
RESET SLAVE
к определенному каналу. Объединение
FOR CHANNEL
с опцией
channel
ALL
удаляет указанный канал.
RESET SLAVE ALL
без FOR CHANNEL
, когда многократные каналы существуют,
удаляет все каналы и обновляет только канал по
умолчанию. См. раздел 19.2.3.
channel
RESET SLAVE
не изменяет параметров соединения, таких как основной узел, порт,
пользователь или пароль, которые сохранены в памяти. Это означает, что
START SLAVE
может быть выпущен, не требуя
CHANGE MASTER TO
с RESET SLAVE
.
Параметры соединения сброшены RESET SLAVE ALL
.
RESET SLAVE
сопровождаемый перезапуском
ведомого устройства mysqld
также делает это.
В MySQL 8.0 RESET SLAVE
неявно закрывает транзакции. См.
раздел 14.3.3.
Если ведомый поток SQL был в середине мультиплицирования временных таблиц,
когда это было остановлено, и
RESET SLAVE
выпущен, эти копируемые временные таблицы удалены на ведомом устройстве.
До MySQL 5.7.5 RESET SLAVE
также имеет эффект сброса обоих
периодов такта (
Slave_heartbeat_period
) и SSL_VERIFY_SERVER_CERT
. Эта
проблема исправлена в MySQL 5.7.5 и позже (Bug #18777899, Bug #18778485).
RESET SLAVE ALL
очищает список
IGNORE_SERVER_IDS
, установленный
CHANGE MASTER TO
.
SET GLOBAL sql_slave_skip_counter = N
Этот запрос пропускает следующие N
событий от ведущего устройства. Это полезно для восстановления от
остановок, вызванных запросом.
Этот запрос допустим только, когда ведомые потоки не работают. Иначе это производит ошибку.
Используя этот запрос, важно понять, что двоичной журнал фактически организован как последовательность групп, известных как группы событий. Каждая группа событий состоит из последовательности событий.
Для транзакционных таблиц группа событий соответствует транзакции.
Единственная транзакция может содержать изменения транзакционных и нетранзакционных таблиц.
Когда Вы используете
SET GLOBAL sql_slave_skip_counter
, чтобы пропускать события,
и результат находится в середине группы, ведомое устройство продолжает
пропускать события, пока это не достигает конца группы. Выполнение тогда
запускается со следующей группы событий.
START SLAVE [thread_types
] [until_option
] [connection_options
] [channel_option
]thread_types
: [thread_type
[,thread_type
] ... ]thread_type
: IO_THREAD | SQL_THREADuntil_option
: UNTIL {{SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS} =gtid_set
| MASTER_LOG_FILE = 'log_name
', MASTER_LOG_POS =log_pos
| RELAY_LOG_FILE = 'log_name
', RELAY_LOG_POS =log_pos
| SQL_AFTER_MTS_GAPS }connection_options
: [USER='user_name
'] [PASSWORD='user_pass
'] [DEFAULT_AUTH='plugin_name
'] [PLUGIN_DIR='plugin_dir
']channel_option
: FOR CHANNELchannel
gtid_set
:uuid_set
[,uuid_set
] ... | ''uuid_set
:uuid
:interval
[:interval
]...uuid
:hhhhhhhh
-hhhh
-hhhh
-hhhh
-hhhhhhhhhhhh
h
: [0-9,A-F]interval
:n
[-n
] (n
>= 1)
START SLAVE
без
thread_type
запускает оба ведомых потока.
Поток ввода/вывода читает события из главного сервера и хранит их в журнале
реле. Поток событий SQL читает из журнала реле и выполняет их.
START SLAVE
требует привилегии
SUPER
.
Если START SLAVE
преуспевает в том, чтобы запустить ведомые потоки, это возвращается без
ошибки. Однако, даже в этом случае, могло бы случиться так, что ведомые
потоки запускаются и затем останавливаются позже (например, потому что им не
удается соединиться с ведущим устройством или считать двоичной журнал).
START SLAVE
не предупреждает
Вас об этом. Вы должны проверить журнал ошибок ведомого устройства на
сообщения об ошибках, произведенные ведомыми потоками, или проверить, что они
работают удовлетворительно с помощью
SHOW SLAVE STATUS
.
START SLAVE
неявно передает продолжающиеся транзакции. См.
раздел 14.3.3.
gtid_next
должен быть установлен в AUTOMATIC
прежде, чем
сделать этот запрос.
FOR CHANNEL
позволяет Вам выбрать, к которому каналу ответа относится запрос. Если
не установлен, и никакие дополнительные каналы не существуют, запрос
относится к каналу по умолчанию и ведет себя как MySQL до 5.7.6. Обеспечение
channel
FOR CHANNEL
применяет
channel
START SLAVE
к определенному каналу. Если
START SLAVE
не определяли канал, используя многократные каналы,
это запрос запускает указанные потоки для всех каналов. Этот запрос отвергнут
для канала group_replication_recovery
. См.
раздел 19.2.3.
MySQL 8.0 поддерживает аутентификацию пользовательского пароля с
START SLAVE
с параметрами USER
,
PASSWORD
, DEFAULT_AUTH
и PLUGIN_DIR
,
как описано в следующем списке:
USER
: Имя пользователя. Не может быть установлено в
пустую строку, если использован PASSWORD
.
PASSWORD
: Пароль.DEFAULT_AUTH
: Имя плагина, по умолчанию это
встроенная аутентификация MySQL.PLUGIN_DIR
: Местонахождение плагина.Вы не можете использовать SQL_THREAD
, определяя любой из
параметров USER
, PASSWORD
,
DEFAULT_AUTH
или PLUGIN_DIR
, если
IO_THREAD
также предоставлена.
См. раздел 7.3.9.
Если опасное соединение используется с какими-либо этими опциями, сервер выдает предупреждение Sending passwords in plain text without SSL/TLS is extremely insecure.
START SLAVE ... UNTIL
поддерживает две дополнительных опции
для использования с глобальными операционными идентификаторами (GTID) (см.
раздел 19.1.3).
Каждая из них берет один или более глобальных операционных идентификаторов
gtid_set
как аргумент.
Когда не определен thread_type
,
START SLAVE UNTIL SQL_BEFORE_GTIDS
заставляет ведомый поток SQL обрабатывать транзакции, пока он не достигнет
первой транзакции, GTID которой перечислен в
gtid_set
. START SLAVE UNTIL SQL_AFTER_GTIDS
заставляет ведомые потоки обрабатывать все транзакции до
последней
транзакции в gtid_set
.
Другими словами, START SLAVE UNTIL SQL_BEFORE_GTIDS
заставляет ведомый поток SQL обрабатывать все транзакции, происходящие перед
первым GTID в gtid_set
, а
START SLAVE UNTIL SQL_AFTER_GTIDS
заставляет ведомые потоки
обрабатывать все транзакции, включая те, GTID которых найдены в
gtid_set
, пока не столкнутся с транзакцией, GTID
которой не часть набора. SQL_BEFORE_GTIDS
и
SQL_AFTER_GTIDS
поддерживают опции SQL_THREAD
и
IO_THREAD
, хотя использование IO_THREAD
с ними в
настоящее время не имеет никакого эффекта.
Например, START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS =
3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56
заставляет ведомый поток
SQL обрабатывать все транзакции, происходящие от ведущего устройства, чей
server_uuid
3E11FA47-71CA-11E1-9E33-C80AA9429562
, пока это не сталкивается
с транзакцией, имеющей порядковый номер 11, это тогда останавливается, не
обрабатывая эту транзакцию. Другими словами, все транзакции до и включая
транзакцию с порядковым номером 10 обработаны. Выполнение START SLAVE
SQL_THREAD UNTIL SQL_AFTER_GTIDS =
3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56
с другой стороны заставил
бы ведомый поток SQL получать все транзакции от ведущего устройства, включая
все транзакции, имеющие порядковые номера 11-56, а затем останавливаться, не
обрабатывая дополнительных транзакций, то есть, транзакция, имеющая
порядковый номер 56, была бы последней транзакцией, принесенной
ведомым потоком SQL.
Используя мультипоточное ведомое устройство, есть шанс промежутков в последовательности транзакций, которые выполнены от реле. Это следующие случаи:
Уничтожение потока координатора.
Используйте START SLAVE
UNTIL SQL_AFTER_MTS_GAPS
, чтобы заставить потоки мультипоточного
ведомого устройства работать только до промежутков в журнале реле, и затем
остановиться. Этот запрос может взять опцию SQL_THREAD
, но
эффект запроса остается неизменным. Это не имеет никакого эффекта на ведомый
поток ввода/вывода (и не может использоваться с IO_THREAD
).
START SLAVE
на мультипоточном ведомом устройстве с промежутками в последовательности
транзакций, выполненных от журнала, производит предупреждение.
В такой ситуации решение состоит в том, чтобы использовать
START SLAVE UNTIL
SQL_AFTER_MTS_GAPS
, затем
RESET SLAVE
, чтобы
удалить любые остающиеся журналы реле. См.
раздел
19.4.1.34.
Чтобы изменить неудавшееся мультипоточное ведомое устройство единственного дерева сообщений, Вы можете выпустить следующий ряд запросов в показанном порядке:
START SLAVE UNTIL SQL_AFTER_MTS_GAPS; SET @@GLOBAL.slave_parallel_workers = 0; START SLAVE SQL_THREAD;
Возможно рассмотреть весь текст выполнения START SLAVE ...
,
включая любые значения USER
или PASSWORD
, в выводе
SHOW PROCESSLIST
.
Это также верно для текста выполнения
CHANGE MASTER TO
,
включая любые значения MASTER_USER
или
MASTER_PASSWORD
.
START SLAVE
посылает
признание пользователю после того, как поток ввода/вывода и поток SQL
запустились. Однако, поток ввода/вывода еще, возможно, не соединился. Поэтому
успешный START SLAVE
показывает в SHOW SLAVE STATUS
Slave_SQL_Running=Yes
, но это не гарантирует, что
Slave_IO_Running=Yes
(поскольку
Slave_IO_Running=Yes
только, если поток ввода/вывода
работает и соединен). Для получения дополнительной
информации см. разделы 14.7.5.34 и
19.1.7.1.
Вы можете добавить опции IO_THREAD
и SQL_THREAD
,
чтобы назвать, который из потоков запустить. Опция SQL_THREAD
отвергнута, определяя любой из параметров
USER
, PASSWORD
, DEFAULT_AUTH
или
PLUGIN_DIR
, если опция IO_THREAD
задана.
UNTIL
(until_option
в предыдущей грамматике) может быть добавлен, чтобы определить, что ведомое
устройство должно запуститься и работать, пока поток SQL не достигает данной
точки в основном двоичном журнале, определенной опциями
MASTER_LOG_POS
и MASTER_LOG_FILE, или пункта в ведомом журнале
реле, обозначенного опциями RELAY_LOG_POS
и
RELAY_LOG_FILE
. Когда поток SQL достигает определенной точки,
это останавливается. Если опция SQL_THREAD
определена в запросе,
она запускает только поток SQL. Иначе, это запускает оба ведомых потока. Если
поток SQL работает, UNTIL
проигнорирован, и предупреждение
выпущено. Вы не можете использовать UNTIL
с
опцией IO_THREAD
.
Также возможно с START SLAVE UNTIL
определить остановку
относительно данного GTID или набора GTID с использованием одной из опций
SQL_BEFORE_GTIDS
или SQL_AFTER_GTIDS
,
как объяснено ранее в этом разделе. Используя одну из этих опций, Вы можете
определить SQL_THREAD
, IO_THREAD, оба из них, или ни один
из них. Если Вы определяете только
SQL_THREAD
,
тогда только ведомый поток SQL затронут запросом, если только
IO_THREAD
используется, тогда только ведомый поток ввода/вывода
затронут. Если используются оба SQL_THREAD
и IO_THREAD
, или если ни один из них не используется, то потоки SQL и
ввода/вывода затронуты запросом.
UNTIL
не поддержан для мультипоточных ведомых устройств кроме
тех случаев, когда также используется
SQL_AFTER_MTS_GAPS
.
Для UNTIL
Вы должны определить любое из следующего:
Имя файла системного журнала и позицию в этом файле.
SQL_BEFORE_GTIDS
или
SQL_AFTER_GTIDS
.SQL_AFTER_MTS_GAPS
Не смешивайте ведущее устройство и опции журнала реле. Не смешивайте опции файла системного журнала с опциями GTID.
Любое условие UNTIL
сброшено последующим
STOP SLAVE
,
START SLAVE
, который не
включает UNTIL
, или перезапуском сервера.
Определяя файл системного журнала и позицию, Вы можете использовать
IO_THREAD
с START SLAVE ... UNTIL
даже при том, что только поток SQL затронут этим запросом. Опция
IO_THREAD
проигнорирована в таких случаях. Предыдущее
ограничение не применяется, используя одну из опций GTID
(SQL_BEFORE_GTIDS
и SQL_AFTER_GTIDS
), опции GTID
поддерживают обоих SQL_THREAD
и IO_THREAD
,
как объяснено ранее в этом разделе.
UNTIL
может быть полезным для того, чтобы отладить
репликацию. Например, если неблагоразумный
DROP TABLE
был выполнен на ведущем устройстве, Вы можете использовать
UNTIL
, чтобы сказать ведомому устройству выполнять до того
пункта, но не дальше. Чтобы найти событие, используйте
mysqlbinlog
с основным двоичным журналом или ведомым журналом реле, или используйте
SHOW BINLOG EVENTS
.
Если Вы используете UNTIL
, чтобы
ведомый процесс копировал запросы в разделах, рекомендуется, чтобы Вы
запустили ведомое устройство с опцией
--skip-slave-start
, чтобы препятствовать тому, чтобы поток SQL работал, когда
ведомый сервер запускается. Вероятно, лучше использовать эту опцию в файле
опций, а не в командной строке, чтобы неожиданный перезапуск сервера не
заставил это забыть.
SHOW SLAVE STATUS
включает выходные поля, которые выводят на экран
текущее значение UNTIL
.
В очень старых версиях MySQL (перед 4.0.5) этот запрос назывался
SLAVE START
. В MySQL 8.0 этот синтаксис производит ошибку.
STOP SLAVE [Останавливает ведомые потоки.thread_types
]thread_types
: [thread_type
[,thread_type
] ... ]thread_type
: IO_THREAD | SQL_THREADchannel_option
: FOR CHANNELchannel
STOP
SLAVE
требует привилегию
SUPER
. Рекомендуемая практика должна выполнить
STOP SLAVE
на ведомом устройстве прежде, чем остановить ведомый
сервер (см. раздел 6.1.12.
Используя основанный на строке формат журналирования
: Вы должны выполнить STOP SLAVE
или STOP SLAVE
SQL_THREAD
на ведомом устройстве до закрытия ведомого сервера, если Вы
копируете какие-либо таблицы, которые используют
нетранзакционной механизм хранения.
Как START SLAVE
,
этот запрос может использоваться с IO_THREAD
и
SQL_THREAD
, чтобы назвать поток или потоки,
которые будут остановлены.
В MySQL 8.0 STOP SLAVE
неявно передает продолжающиеся
транзакции. См. раздел 14.3.3.
gtid_next
должен быть установлен в AUTOMATIC
прежде, чем сделать это запрос.
Вы можете управлять, сколько времени STOP SLAVE
ждет перед
синхронизацией, устанавливая
rpl_stop_slave_timeout
. Это может использоваться, чтобы избежать
тупиков между STOP SLAVE
и другими ведомыми запросами SQL,
используя различные соединения клиента с ведомым устройством.
Некоторые запросы CHANGE MASTER TO
позволены в то время, как
ведомое устройство работает, в зависимости от статуса ведомого SQL и потоков
ввода/вывода. Однако, использование STOP SLAVE
до выполнения
CHANGE MASTER TO
в таких случаях все еще поддержано. См. разделы
14.4.2.1 и
19.3.8.
FOR CHANNEL
позволяет Вам выбрать, к которому каналу относится запрос. Если никакой пункт
не установлен, и никакие дополнительные каналы не существуют, запрос
относится к каналу по умолчанию и ведет себя как версии MySQL до 5.7.
Обеспечение channel
FOR CHANNEL
применяет channel
STOP SLAVE
к определенному каналу. Если
STOP SLAVE
не определяли канал, используя многократные каналы,
этот запрос останавливает указанные потоки для всех каналов. Этот запрос не
может использоваться с каналом group_replication_recovery
. См.
раздел 19.2.3.
Используя основанную на запросе репликацию:
изменение ведущего устройства, в то время как у этого есть открытые временные
таблицы, потенциально опасно. Это одна из причин, почему основанная на
запросе репликация временных таблиц не рекомендуется. Вы можете узнать, есть
ли какие-либо временные таблицы на ведомом устройстве, проверяя значение
Slave_open_temp_tables
, используя основанную на запросе
репликацию, это значение должно быть 0 перед выполнением CHANGE MASTER
TO
. Если есть какие-либо временные таблицы, открытые на ведомом
устройстве, CHANGE MASTER TO
после STOP SLAVE
вызовет предупреждение ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO.
Используя мультипоточное ведомое устройство
(
slave_parallel_workers
не 0),
любые разрывы в последовательности транзакций, выполненных от журнала реле,
преодолены как часть остановки рабочего потока. Если ведомое устройство
неожиданно остановлено (например из-за ошибки в рабочем потоке)
в то время, как STOP SLAVE
выполняется, последовательность выполненных транзакций от журнала реле может
стать непоследовательной. См.
раздел
19.4.1.34.
В MySQL 8.0 STOP SLAVE
ждет, пока текущая группа событий, затрагивающая одну или
более нетранзакционных таблиц, не закончит выполняться (если есть какая-либо
такая группа) или не будет команды KILL QUERY
или KILL CONNECTION
(Bug #319, Bug #38205).
Этот раздел предоставляет информацию о запросах, используемых для того, чтобы управлять группами репликации.
START GROUP_REPLICATIONЗапускает группу репликации.
STOP GROUP_REPLICATIONОстанваливает группу репликации.
MySQL 8.0 оказывает поддержку для подготовленных запросов стороны сервера. Эта поддержка использует эффективный протокол двоичной синхронной передачи данных клиент-сервер. Использование готовые запросы с заполнителями для параметра значения обладает следующими преимуществами:
Меньше издержек, чтобы разобрать запрос каждый раз.
Как правило, приложения базы данных обрабатывают большие объемы почти
идентичных запросов только изменениями с переменных значений в таких пунктах,
как WHERE
для запросов и удалений и
VALUES
для вставок.
Вы можете использовать подготовленные запросы стороны сервера через
клиента, программирующего интерфейсы, включая
MySQL C API client library или
MySQL
Connector/C для C-программ,
MySQL
Connector/J для Java и
MySQL
Connector/Net для .NET. Например, C API обеспечивает ряд вызовов функций,
которые составляют готовый запрос API. См.
раздел 25.8.8.
Другие языковые интерфейсы могут оказать поддержку для готовых запросов,
которые используют протокол двоичной синхронной передачи данных в библиотеке
клиента C, один пример,
mysqli
extension, доступен в PHP 5.0 и выше.
Альтернативный интерфейс SQL к готовым запросам доступен. Этот интерфейс не столь же эффективен, как использование протокола двоичной синхронной передачи данных через готовый запрос, но не требует никакого программирования, потому что это доступно непосредственно на уровне SQL:
Вы можете использовать это, когда никакой программный интерфейс не доступен Вам.
Синтаксис SQL для готовых запросов предназначен, чтобы использоваться для ситуаций, таких как:
Проверить, как готовые запросы работают в Вашем приложении прежде, чем кодировать это.
Синтаксис SQL для готовых запросов основан на трех запросах SQL:
PREPARE
готовит запрос
к выполнению (см. раздел 14.5.1).
EXECUTE
выполняет готовый
запрос (см. раздел 14.5.2).DEALLOCATE PREPARE
освобождает готовый запрос (см. раздел
14.5.3).Следующие примеры показывают два эквивалентных способа подготовить запрос, который вычисляет гипотенузу треугольника, данного длинами двух сторон.
Первый пример показывает, как создать готовый запрос при использовании буквальной строки, чтобы поставлять текст запроса:
mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2)+POW(?,2)) AS hypotenuse'; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b; +------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql> DEALLOCATE PREPARE stmt1;Второй пример подобен, но поставляет текст запроса как пользовательскую переменную:
mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> PREPARE stmt2 FROM @s; mysql> SET @a = 6; mysql> SET @b = 8; mysql> EXECUTE stmt2 USING @a, @b; +------------+ | hypotenuse | +------------+ | 10 | +------------+ mysql> DEALLOCATE PREPARE stmt2;Вот дополнительный пример, который демонстрирует, как выбрать таблицу, на которой можно выполнить запрос во время выполнения, храня название таблицы как пользовательскую переменную:
mysql> USE test; mysql> CREATE TABLE t1 (a INT NOT NULL); mysql> INSERT INTO t1 VALUES (4), (8), (11), (32), (80); mysql> SET @table = 't1'; mysql> SET @s = CONCAT('SELECT * FROM ', @table); mysql> PREPARE stmt3 FROM @s; mysql> EXECUTE stmt3; +----+ | a | +----+ | 4 | | 8 | | 11 | | 32 | | 80 | +----+ mysql> DEALLOCATE PREPARE stmt3;Готовый запрос является определенным для сеанса, в котором он создавался. Если Вы заканчиваете сеанс, не освобождая ранее готовый запрос, сервер освобождает это автоматически.
Готовый запрос также глобален для сеанса. Если Вы создаете готовый запрос в пределах сохраненной подпрограммы, это не освобождено, когда сохраненная подпрограмма заканчивается.
Чтобы принять меры против слишком многих готовых запросов, создаваемых
одновременно, установите
max_prepared_stmt_count
. Чтобы предотвратить использование готовых
запросов, установите значение в 0.
Следующие запросы SQL могут использоваться в качестве подготовленных запросов:
ALTER TABLE ALTER USER ANALYZE TABLE CACHE INDEX CALL CHANGE MASTER CHECKSUM {TABLE | TABLES} COMMIT {CREATE | DROP} INDEX {CREATE | RENAME | DROP} DATABASE {CREATE | DROP} TABLE {CREATE | RENAME | DROP} USER {CREATE | DROP} VIEW DELETE DO FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES} GRANT INSERT INSTALL PLUGIN KILL LOAD INDEX INTO CACHE OPTIMIZE TABLE RENAME TABLE REPAIR TABLE REPLACE RESET {MASTER | SLAVE | QUERY CACHE} REVOKE SELECT SET SHOW {WARNINGS | ERRORS} SHOW BINLOG EVENTS SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW} SHOW {MASTER | BINARY} LOGS SHOW {MASTER | SLAVE} STATUS SLAVE {START | STOP} TRUNCATE TABLE UNINSTALL PLUGIN UPDATEДля согласия со стандартом SQL, который заявляет, что запросы диагностики не могут быть предварительно подготовленными, MySQL не поддерживает следующие запросы как подготовленные:
SHOW WARNINGS
, SHOW COUNT(*) WARNINGS
SHOW ERRORS
, SHOW COUNT(*) ERRORS
warning_count
или
error_count
.
Другие запросы не поддержаны в MySQL 8.0.
Вообще, запросы, не разрешенные в подготовленных запросах SQL, также не разрешены в сохраненных программах. Исключения отмечены в разделе C.1.
Изменения метаданных таблиц или представлений, упомянутых готовыми запросыми, обнаружены и вызывают автоматическую переподготовку запроса, когда это затем выполнено. Для получения дополнительной информации см. раздел 9.10.4.
Заполнители могут использоваться для параметров LIMIT
,
используя подготовленные запросы. См. раздел 14.2.9
.
В готовом CALL
, используемом с
PREPARE
и
EXECUTE
,
поддержка заполнителя параметров OUT
и INOUT
доступна, начиная с MySQL 8.0. См. раздел 14.2.1
для примера и обходного решения для более ранних версий. Заполнители могут
использоваться для IN
независимо от версии.
Синтаксис SQL для готовых запросов не может использоваться вложенным
способом. Таким образом, запрос для
PREPARE
не может самостоятельно
быть PREPARE
,
EXECUTE
или
DEALLOCATE PREPARE
.
Синтаксис SQL для готовых запросов отличен от использования готового
вызова API. Например, Вы не можете использовать C API
mysql_stmt_prepare()
, чтобы подготовить
PREPARE
,
EXECUTE
или
DEALLOCATE PREPARE
.
Синтаксис SQL для готовых запросов может использоваться в пределах
хранимых процедур, но не в сохраненных функциях или триггерах. Однако, курсор
не может использоваться для динамического запроса, который подготовлен и
ыполнен с PREPARE
и
EXECUTE
.
Запрос для курсора проверено во время создания курсора, таким образом, запрос
не может быть динамическим.
Синтаксис SQL для готовых запросов не поддерживает мультизапросы (то есть,
много запросов в пределах единственной строки, отделенных ;
).
Готовые запросы используют кэш запроса при условиях, описанных в described in разделе 9.10.3.1.
Чтобы писать программы на C, которые используют
CALL
, чтобы выполнить хранимые
процедуры, которые содержат готовые запросы, флаг
CLIENT_MULTI_RESULTS
должен быть включен. Это потому, что каждый
CALL
возвращает результат, чтобы
указать на состояние требования, в дополнение к любым наборам результатов,
которые могли бы быть возвращены запросами в пределах процедуры.
CLIENT_MULTI_RESULTS
может быть включен, когда Вы вызываете
mysql_real_connect()
, явно, передавая флаг CLIENT_MULTI_RESULTS
, или неявно,
передавая CLIENT_MULTI_STATEMENTS
(который также включает
CLIENT_MULTI_RESULTS
). См. раздел 14.2.1
.
PREPAREstmt_name
FROMpreparable_stmt
PREPARE
готовит запрос SQL и
назначает ему имя stmt_name
,
которым можно сослаться на запрос позже. Готовый запрос выполнен с
EXECUTE
и выпущен с
DEALLOCATE PREPARE
.
См. раздел 14.5.
Имена запросов не являются чувствительными к регистру.
preparable_stmt
буквальная строка или пользовательская
переменная, которая содержит текст запроса SQL. Текст должен представить
единственный запрос, не многократные запросы. В пределах запроса символы
?
могут использоваться в качестве маркеров параметра, чтобы
указать, где значения данных должны быть связаны с запросом позже, когда Вы
выполняете его. Символы ?
не должны быть приложены в пределах
кавычек, даже если Вы намереваетесь обязать их представлять значения в виде
строки. Маркеры параметра могут использоваться только там, где значения
данных должны появиться, не для ключевых слов SQL, идентификаторов и т.д.
Если готовый запрос с именем уже существует, это освобождено неявно прежде, чем новый запрос подготовлен. Это означает, что, если новый запрос содержит ошибку и не может быть подготовлен, ошибка возвращена и никакой запрос с именем не существует.
Контекст готового запроса это сеанс, в пределах которого он создается, это имеет несколько значений:
Готовый запрос, создаваемый в одном сеансе, недоступен другим сеансам.
EXECUTEПосле подготовки запроса сstmt_name
[USING @var_name
[, @var_name
] ...]
PREPARE
Вы выполняете это с EXECUTE
,
который относится к имени готового запроса. Если готовый запрос содержит
какие-либо маркеры параметра, Вы должны поставлять USING
,
который перечисляет пользовательские переменные, содержащие значения, которые
будут связаны с параметрами. Значения параметра могут поставляться только
пользовательскими переменными, и USING
должен назвать точно
столько переменных, как число маркеров параметра в запросе.
Вы можете выполнить данный подготовленный запрос многократно, передавая различные переменные или устанавливая переменные в различные значения перед каждым выполнением.
См. раздел 14.5.
{DEALLOCATE | DROP} PREPARE stmt_name
Чтобы освободить готовый запрос, произведенный с
PREPARE
, используйте
DEALLOCATE PREPARE
,
который относится к готовому имени запроса. Попытка выполнить готовый запрос
после освобождения приводит к ошибке. Если слишком много готовых запросов
создаются и не освобождаются DEALLOCATE PREPARE
или концом сеанса, Вы могли бы столкнуться с верхним пределом, проведенным в
жизнь
max_prepared_stmt_count
.
См. раздел 14.5.
Этот раздел описывает синтаксис для составного запроса
BEGIN ... END
и другие запросы, которые могут использоваться в теле сохраненных программ:
хранимые процедуры и функции, триггеры и события. Эти объекты определены с
точки зрения кода SQL, который сохранен на сервере для более позднего
неспешного потребления (см. главу 21).
Составной запрос это блок, который может содержать другие блоки, декларации переменных, обработчики условия и курсоров, и конструкции управления потоками, такие как циклы и условные тесты.
[begin_label
:] BEGIN [statement_list
] END [end_label
]
BEGIN ... END
используется для того, чтобы написать составные запросы, которые могут
появиться в пределах сохраненных программ (хранимые процедуры и функции,
триггеры и события). Составной запрос может содержать многократные запросы
в BEGIN
и END
. statement_list
представляет список из одного или более запросов, каждый закончен точкой с
запятой (;
). statement_list
непосредственно является дополнительным, таким образом, пустой составной
запрос (BEGIN END
) допустим.
BEGIN ... END
могут быть вложены.
Использование многократных запросов требует, чтобы клиент был в состоянии
послать строки запроса, содержащие разделитель ;
. В
mysql
это обработано командой delimiter
. Изменение разделителя конца
запроса ;
(например, на //
) позволяет
;
использоваться в теле программы. Для примера см.
раздел 21.1.
Блок BEGIN ... END
может быть маркирован. См. раздел 14.6.2
.
[NOT] ATOMIC
не поддержан. Это означает, что никакая
транзакционная точка восстановления не установлена в начале блока инструкций,
и BEGIN
, используемый в этом контексте, не имеет никакого
эффекта на текущую транзакцию.
В пределах всех сохраненных программ анализатор обрабатывает
BEGIN [WORK]
как начало
BEGIN ... END
.
Чтобы начать транзакцию в этом контексте, надо использовать
START TRANSACTION
.
[Для меток разрешаютbegin_label
:] BEGIN [statement_list
] END [end_label
] [begin_label
:] LOOPstatement_list
END LOOP [end_label
] [begin_label
:] REPEATstatement_list
UNTILsearch_condition
END REPEAT [end_label
] [begin_label
:] WHILEsearch_condition
DOstatement_list
END WHILE [end_label
]
BEGIN ... END
блоки, а также команды LOOP
,
REPEAT
и
WHILE
.
Использование метки для тех запросов следует этим правилам:
begin_label
должен сопровождаться двоеточием.
begin_label
можно дать без
end_label
. Если дано
end_label
, это должно быть то же самое, как
begin_label
.end_label
нельзя дать без
begin_label
.Чтобы обратиться к метке в пределах маркированной конструкции, используйте
ITERATE
или
LEAVE
.
Следующий пример использует те запросы, чтобы продолжить повторять
или заканчивать цикл:
CREATE PROCEDURE doiterate(p1 INT) BEGIN label1: LOOP SET p1 = p1 + 1; IF p1 < 10 THEN ITERATE label1; END IF; LEAVE label1; END LOOP label1; END;Контекст метки блока не включает код для обработчиков, объявленных в пределах блока. Для деталей см. раздел 14.6.7.2.
DECLARE
используется, чтобы определить различные элементы, местные для программы:
Местные переменные. См. раздел 14.6.4.
DECLARE
разрешен только внутри BEGIN ... END
и должен быть в его начале перед любыми другими запросыми.
Декларации должны следовать в определенном порядке. Декларации курсора должны появиться перед декларациями обработчика. Переменная и декларации условия должны появиться перед декларациями обработчика или курсором.
Системные переменные и определяемые пользователем переменные могут
использоваться в сохраненных программах, как они могут использоваться вне
контекста сохраненной программы. Кроме того, сохраненные программы могут
использовать DECLARE
, чтобы определить местные переменные, а
сохраненные подпрограммы (процедуры и функции) могут объявлять параметры,
которые сообщают значения между подпрограммой и ее вызывающим.
Чтобы объявить местные переменные, используйте
DECLARE
, как
описано в разделе 14.6.4.1.
SET
. См.
раздел 14.7.4.1.SELECT ... INTO var_list
или открывая курсор и используя
FETCH ... INTO var_list
. См. разделы 14.2.9.1 и
14.6.6.См. раздел 14.6.4.2.
Не разрешено назначить значение DEFAULT
местным переменным
в хранимой процедуре или функциональным параметрам (например, с SET
).
В MySQL 8.0 это приводит к синтаксической ошибке.var_name
= DEFAULT
DECLAREЭтот запрос объявляет местные переменные в пределах сохраненных программ. Чтобы обеспечить значение по умолчанию для переменной, включайтеvar_name
[,var_name
] ...type
[DEFAULTvalue
]
DEFAULT
. Значение может быть определено как выражение, это не
должна быть константа. Если DEFAULT
нет,
начальное значение NULL
.
Местные переменные обработаны как сохраненные обычные параметры относительно проверки переполнения и типа данных. См. раздел 14.1.13.
Переменные декларации должны появиться перед декларациями обработчика или курсора.
Местные имена переменной не являются чувствительными к регистру. Допустимые символы и правила заключения в кавычки те же самое, что касаются других идентификаторов, как описано в разделе 10.2.
Контекст местной переменной это блок
BEGIN ... END
в пределах которого это объявлено. Переменная может быть упомянута в блоках,
вложенных в пределах блока объявления, кроме тех блоков, которые объявляют
переменную с тем же самым именем.
См. раздел 14.6.4.2.
Контекст местной переменной это блок
BEGIN ... END
в пределах которого это объявлено. Переменная может быть упомянута в блоках,
вложенных в пределах блока объявления, кроме тех блоков, которые объявляют
переменную с тем же самым именем.
Поскольку местные переменные находятся в контексте только во время
выполнения сохраненной программы, ссылки на них не разрешены в готовых
запросах, создаваемых в пределах сохраненной программы.
Контекст готового запроса это текущий сеанс, а не сохраненная программа,
таким образом, запрос может быть выполнен после конца программы, а тогда
переменные больше не будут в контексте. Например,
SELECT ... INTO
не может использоваться в качестве готового запроса. Это ограничение также
относится к хранимой процедуре и функциональным параметрам. См.
раздел 14.5.1.local_var
У местной переменной не должно быть того же самого имени как у
столбца таблицы. Если запрос SQL, например,
SELECT ... INTO
,
содержит ссылку на столбец и заявленную местную переменную с тем же самым
именем, MySQL в настоящее время интерпретирует ссылку как название
переменной. Рассмотрите следующее определение процедуры:
CREATE PROCEDURE sp1 (x VARCHAR(5)) BEGIN DECLARE xname VARCHAR(5) DEFAULT 'bob'; DECLARE newname VARCHAR(5); DECLARE xid INT; SELECT xname, id INTO newname, xid FROM table1 WHERE xname = xname; SELECT newname; END;MySQL понимает
xname
в
SELECT
как ссылку на
переменную xname
, а не на
столбец xname
.
Следовательно, когда процедура sp1()
вызвана, переменная
newname
возвращает значение 'bob'
независимо от значения table1.xname
.
Точно так же определение курсора в следующей процедуре содержит
SELECT
, который относится к
xname
. MySQL интерпретирует это как ссылку на переменную,
а не на столбец.
CREATE PROCEDURE sp2 (x VARCHAR(5)) BEGIN DECLARE xname VARCHAR(5) DEFAULT 'bob'; DECLARE newname VARCHAR(5); DECLARE xid INT; DECLARE done TINYINT DEFAULT 0; DECLARE cur1 CURSOR FOR SELECT xname, id FROM table1; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; read_loop: LOOP FETCH FROM cur1 INTO newname, xid; IF done THEN LEAVE read_loop; END IF; SELECT newname; END LOOP; CLOSE cur1; END;См. раздел C.1.
MySQL поддерживает конструкции IF
,
CASE
,
ITERATE
,
LEAVE
LOOP
,
WHILE
и
REPEAT
для управления потоками в пределах сохраненных программ. Это также
поддерживает RETURN
в пределах сохраненных функций.
Многие из этих конструкций содержат другие запросы, как обозначено
техническими требованиями грамматики в следующих разделах. Такие конструкции
могут быть вложены. Например, IF
мог бы содержать WHILE
, который
непосредственно содержит CASE
.
MySQL не поддерживает циклы FOR
.
CASEИли:case_value
WHENwhen_value
THENstatement_list
[WHENwhen_value
THENstatement_list
] ... [ELSEstatement_list
] END CASE
CASE WHENsearch_condition
THENstatement_list
[WHENsearch_condition
THENstatement_list
] ... [ELSEstatement_list
] END CASE
CASE
для сохраненных программ
осуществляет сложную условную конструкцию.
Есть также CASE
expression, который отличается от
CASE
statement,
описанного здесь. См. раздел 13.4
. CASE
не может иметь
ELSE NULL
и это закончено с END CASE
вместо END
.
Для первого синтаксиса case_value
является
выражением. Это значение сравнивается с when_value
в каждом WHEN
до равенства одному из них. Когда равное
when_value
найдено, соответствующий
THEN
statement_list
выполнен. Если нет
равного when_value
, выполнен
ELSE
statement_list
, если есть. Если его
нет, то не выполнено ничего.
Этот синтаксис не может использоваться, чтобы проверить на равенство с
NULL
, так как NULL = NULL
будет false. См.
раздел 4.3.4.6.
Для второго синтаксиса каждый WHEN
search_condition
оценено, пока не истина, в какой
THEN
statement_list
передать выполнение.
Если нет равного when_value
, выполнен
ELSE
statement_list
, если есть. Если его
нет, то не выполнено ничего.
Если нет when_value
или
search_condition
, которое
соответствует проверенному значению, и
CASE
не содержит ELSE
,
будет ошибка Case not found for CASE statement.
Каждый statement_list
состоит из одного или более
запросов SQL, пустой statement_list
запрещен.
Чтобы обработать ситуации, где никакое значение не является
соответствующим WHEN
, используйте ELSE
, содержащий
пустой блок BEGIN ... END
.
DELIMITER | CREATE PROCEDURE p() BEGIN DECLARE v INT DEFAULT 1; CASE v WHEN 2 THEN SELECT v; WHEN 3 THEN SELECT 0; ELSE BEGIN END; END CASE; END; |
IFsearch_condition
THENstatement_list
[ELSEIFsearch_condition
THENstatement_list
] ... [ELSEstatement_list
] END IF
IF
для сохраненных программ осуществляет основную условную конструкцию.
Есть также функция
IF()
, которая отличается от запроса
IF
. См.
раздел 13.4. Запрос
IF
может иметь
THEN
, ELSE
и ELSEIF
,
и это закончено с END IF
.
Если search_condition
true, соответствующий
THEN
или ELSEIF
statement_list
выполняется. Если нет подходящего
search_condition
, выполнен ELSE
statement_list
.
Каждый statement_list
состоит из одного или более запросов SQL: пустой
statement_list
запрещен.
IF ... END IF
, как все другие блоки управления потоками,
используемые в пределах сохраненных программ, должен быть закончен точкой с
запятой, как показано в этом примере:
DELIMITER // CREATE FUNCTION SimpleCompare(n INT, m INT) RETURNS VARCHAR(20) BEGIN DECLARE s VARCHAR(20); IF n > m THEN SET s = '>'; ELSEIF n = m THEN SET s = '='; ELSE SET s = '<'; END IF; SET s = CONCAT(n, ' ', s, ' ', m); RETURN s; END // DELIMITER ;Как с другими конструкциями управления потоками, блоки
IF ... END IF
могут быть вложены в пределах других конструкций управления потоками,
включая другой запрос IF
. Каждый
IF
должен быть закончен его собственным
END IF
и точкой с запятой. Вы можете использовать углубление,
чтобы сделать вложенные блоки управления потоками более легко читаемыми
людьми (хотя это не требуется MySQL), как показано здесь:
DELIMITER // CREATE FUNCTION VerboseCompare (n INT, m INT) RETURNS VARCHAR(50) BEGIN DECLARE s VARCHAR(50); IF n = m THEN SET s = 'equals'; ELSE IF n > m THEN SET s = 'greater'; ELSE SET s = 'less'; END IF; SET s = CONCAT('is ', s, ' than'); END IF; SET s = CONCAT(n, ' ', s, ' ', m, '.'); RETURN s; END // DELIMITER ;В этом примере внутренний
IF
оценен только, если n
не равно m
.
ITERATE label
ITERATE
может появиться только в
пределах LOOP
,
REPEAT
и
WHILE
.
ITERATE
значит
запустить повтор цикла.
См. раздел 14.6.5.5.
LEAVE label
Этот запрос используется, чтобы выйти из конструкции управления потоками, у
которой есть данная метка. Если метка для наиболее удаленного сохраненного
блока программы, LEAVE
выходит из программы.
LEAVE
может использоваться в
пределах BEGIN ... END
или конструкции цикла (LOOP
,
REPEAT
,
WHILE
).
См. раздел 14.6.5.5.
[begin_label
:] LOOPstatement_list
END LOOP [end_label
]
LOOP
осуществляет простую конструкцию цикла, включая повторное выполнение списка
запросов, который состоит из одного или более запросов, каждый завершенный
точкой с запятой (;
). Ззапросы повторены, пока цикл не закончен.
Обычно это достигнуто с помощью LEAVE
. В пределах сохраненной функции RETURN
может также использоваться, чтобы выйти из функции полностью.
Если не включать запрос завершения цикла, цикл станет бесконечным.
LOOP
может быть маркирован.
Для правил относительно использования меток см.
раздел 14.6.2.
Пример:
CREATE PROCEDURE doiterate(p1 INT) BEGIN label1: LOOP SET p1 = p1 + 1; IF p1 < 10 THEN ITERATE label1; END IF; LEAVE label1; END LOOP label1; SET @x = p1; END;
[Список запросов в пределахbegin_label
:] REPEATstatement_list
UNTILsearch_condition
END REPEAT [end_label
]
REPEAT
повторено, пока выражение
search_condition
не станет истиной. Таким образом,
REPEAT
всегда вводит цикл, по
крайней мере, однажды. statement_list
состоит из одного
или более запросов, каждый закрыт точкой с запятой (;
).
REPEAT
может быть маркирован. Для правил относительно использования меток см.
раздел 14.6.2.
Пример:
mysql> delimiter // mysql> CREATE PROCEDURE dorepeat(p1 INT) -> BEGIN -> SET @x = 0; -> REPEAT -> SET @x = @x + 1; -> UNTIL @x > p1 END REPEAT; -> END -> // Query OK, 0 rows affected (0.00 sec) mysql> CALL dorepeat(1000)// Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x// +------+ | @x | +------+ | 1001 | +------+ 1 row in set (0.00 sec)
RETURN expr
RETURN
заканчивает выполнение сохраненной функции и возвращает значение
expr
вызвавшему. Должен быть по крайней мере один
RETURN
в сохраненной функции. Может быть больше, чем один, если у функции есть
много пунктов выхода.
Этот запрос не используется в хранимых процедурах, триггерах или событиях.
LEAVE
может использоваться, чтобы
выйти из сохраненной программы этих типов.
[Список запросов в пределахbegin_label
:] WHILEsearch_condition
DOstatement_list
END WHILE [end_label
]
WHILE
повторен, пока search_condition
true.
statement_list
состоит из одного или более запросов
SQL, каждый закончен точкой с запятой (;
).
WHILE
может быть маркирован.
Для правил относительно использования меток см.
раздел 14.6.2.
Пример:
CREATE PROCEDURE dowhile() BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO ... SET v1 = v1 - 1; END WHILE; END;
MySQL поддерживает курсоры в сохраненных программах. Синтаксис как во встроенном SQL. У курсоров есть эти свойства:
Asensitive: сервер может или, возможно, не делает копию своей таблицы результата.
Декларации курсора должны появиться перед декларациями обработчика и после деклараций условия и переменной.
Пример:
CREATE PROCEDURE curdemo() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE a CHAR(16); DECLARE b, c INT; DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur1; OPEN cur2; read_loop: LOOP FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF done THEN LEAVE read_loop; END IF; IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END LOOP; CLOSE cur1; CLOSE cur2; END;
CLOSE cursor_name
Закрывает ранее открытый курсор. Для примера см.
раздел 14.6.6.
Ошибка происходит, если курсор не открыт.
Если не закрыт явно, курсор закрыт в конце блока
BEGIN ... END
, в
котором это было объявлено.
DECLAREЭтот запрос объявляет курсор и связывает сcursor_name
CURSOR FORselect_statement
SELECT
,
который получает строки, которые будут пересечены курсором. Чтобы принести
строки позже, используйте FETCH
.
Число столбцов, полученных SELECT
,
должно соответствовать числу выходных переменных, определенных в
FETCH
.
SELECT
не может иметь INTO
.
Декларации курсора должны появиться перед декларациями обработчика и после деклараций условия и переменной.
Сохраненная программа может содержать многократные декларации курсора, но у каждого курсора, объявленного в данном блоке, должно быть уникальное имя. Для примера см. раздел 14.6.6.
Для информации, доступной через
SHOW
,
возможно во многих случаях получить эквивалентную информацию при
использовании курсора с таблицей INFORMATION_SCHEMA
.
FETCH [[NEXT] FROM]Этоn запрос приносит следующую строку дляcursor_name
INTOvar_name
[,var_name
] ...
SELECT
,
связанным с указанным курсором (который должен быть открыт) и обновляет
указатель курсора. Если строка существует, принесенные столбцы сохранены в
названных переменных. Число столбцов, полученных
SELECT
, должно соответствовать
числу выходных переменных, определенных в
FETCH
.
Если больше строк не доступно, происходит состояние No Data condition
с SQLSTATE value '02000'
. Чтобы обнаружить это условие, Вы
можете настроить обработчик для этого (или для условия NOT FOUND
). См. раздел 14.6.6.
Знайте, что другая работа, такая как
SELECT
или другой FETCH
,
может также заставить обработчик выполняться, поднимая то же самое условие.
Если необходимо различить, какая работа подняла условие, поместите работу в
пределах его собственного блока BEGIN ...
END
, чтобы это могло быть связано с собственным обработчиком.
OPEN cursor_name
Этот запрос открывает ранее заявленный курсор. Для примера см.
раздел 14.6.6.
Условия могут возникнуть во время сохраненного выполнения программы, которые требуют специальной обработки, например, выход из текущего блока программы или продолжения выполнения. Обработчики могут быть определены для общих условий, таких как предупреждения или исключения, или для особых условий, таких как особый код ошибки. Особым условиям можно назначить имена.
Чтобы назвать условие, используйте
DECLARE ... CONDITION
.
Чтобы объявить обработчик, используйте
DECLARE ... HANDLER
. См.
разделы 14.6.7.1 и
раздел 14.6.7.2.
Чтобы поднять условие, используйте
SIGNAL
.
Чтобы изменить информацию об условии в пределах обработчика условия, надо
использовать RESIGNAL
. См.
разделы 14.6.7.1 и
14.6.7.2.
Чтобы получить информацию из области диагностики, используйте
GET DIAGNOSTICS
(см.
раздел 14.6.7.3).
Для информации об области диагностики см.
раздел 14.6.7.7.
DECLAREcondition_name
CONDITION FORcondition_value
condition_value
:mysql_error_code
| SQLSTATE [VALUE]sqlstate_value
DECLARE ... CONDITION
объявляет названное состояние ошибки, связывая имя с условием, которое
нуждается в определенной обработке. Имя может быть упомянуто в последующем
DECLARE ... HANDLER
(см.
раздел 14.6.7.2).
Декларации условия должны появиться перед декларациями обработчика или курсором.
condition_value
для
DECLARE ... CONDITION
указывает на особое условие или класс условий, связанный с именем условия.
Это может принять следующие формы:
mysql_error_code
:
Целое число, указание на код ошибки MySQL.
Не используйте код ошибки MySQL 0, потому что это указывает на успех, а не состояние ошибки. Для списка кодов ошибок MySQL см. раздел B.3.
sqlstate_value
:
5-символьная строка, указание на значение SQLSTATE.
Не используйте значения SQLSTATE, которые начинаются на '00'
,
потому что те указывают на успех, а не на состояние ошибки. Для списка
значений SQLSTATE см. раздел B.3
.
Имена условия, упомянутые в
SIGNAL
или
RESIGNAL
,
должны быть связаны со значениями SQLSTATE, а не кодами ошибки MySQL.
Использование названия условий может помочь сделать код программы более ясным. Например, этот обработчик относится к попыткам удалить несуществующую таблицу, но это очевидно, только если Вы знаете, что 1051 это код ошибки MySQL для unknown table:
DECLARE CONTINUE HANDLER FOR 1051 BEGIN -- body of handler END;Объявляя название условия, цель обработчика замечена с большей точностью:
DECLARE no_such_table CONDITION FOR 1051; DECLARE CONTINUE HANDLER FOR no_such_table BEGIN -- body of handler END;Вот названное условие для того же самого условия, но основанное на соответствующем значении SQLSTATE, а не коде ошибки MySQL:
DECLARE no_such_table CONDITION FOR SQLSTATE '42S02'; DECLARE CONTINUE HANDLER FOR no_such_table BEGIN -- body of handler END;
DECLAREhandler_action
HANDLER FORcondition_value
[,condition_value
] ...statement
handler_action
: CONTINUE | EXIT | UNDOcondition_value
:mysql_error_code
| SQLSTATE [VALUE]sqlstate_value
|condition_name
| SQLWARNING | NOT FOUND | SQLEXCEPTION
DECLARE ... HANDLER
определяет обработчик, который имеет дело с одним или более условиями. Если
одно из этих условий происходит, указанный statement
выполнится. statement
может быть простым запросом
таким, как SET var_name
=
value
, или составным запросом из
BEGIN
и END
(см.
раздел 14.6.1).
Декларации обработчика должны появиться после деклараций условия или переменной.
handler_action
указывает на то, что обработчик
предпринимает после выполнения запроса обработчика:
CONTINUE
: Выполнение текущей программы продолжается.
EXIT
: Выполнение заканчивается для
BEGIN ... END
, в котором
объявлен обработчик. Это истина, даже если условие происходит
во внутреннем блоке.UNDO
: Не поддержано.condition_value
для
DECLARE ... HANDLER
указывает на особое условие или класс условий, который активирует обработчик.
Это может принять следующие формы:
mysql_error_code
:
Целое число, указание на код ошибки MySQL, такой как 1051, определяющий
unknown table:
DECLARE CONTINUE HANDLER FOR 1051 BEGIN -- body of handler END;Не используйте код ошибки MySQL 0, потому что это указывает на успех, а не на состояние ошибки. Для списка кодов ошибки MySQL см. раздел B.3.
sqlstate_value
:
5-символьная строка, указание на значение SQLSTATE, такое как
'42S01'
, определяющее unknown table:
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' BEGIN -- body of handler END;Не используйте значения SQLSTATE, которые начинаются с
'00'
,
потому что те указывают на успех, а не на состояние ошибки. Для списка
значений SQLSTATE см. раздел B.3
.condition_name
: Имя условия, ранее определенное с
DECLARE ... CONDITION
.
Имя условия может быть связано с кодом ошибки MySQL или значением SQLSTATE.
См. раздел 14.6.7.1.SQLWARNING
: Сокращение для класса значений
SQLSTATE, которые начинаются с '01'
.
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN -- body of handler END;
NOT FOUND
: Сокращение для класса значений SQLSTATE, которые
начинаются с '02'
. Это релевантно в пределах контекста курсоров
и используется, чтобы управлять тем, что происходит, когда курсор достигает
конца набора данных. Если больше строк не доступно, No Data condition
происходит со значением SQLSTATE '02000'
.
Чтобы обнаружить это условие, Вы можете настроить обработчик для этого или
для NOT FOUND
.
DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN -- body of handler END;См. раздел 14.6.6. Условие
NOT FOUND
также происходит для SELECT ... INTO var_list
, которые не получают строк.SQLEXCEPTION
: Сокращение для класса значений SQLSTATE,
которые НЕ начинаются с '00'
, '01'
или
'02'
.
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN -- body of handler END;
См. раздел 14.6.7.6.
Если условие происходит, для которого не был объявлен обработчик, предпринятые меры зависят от класса условия:
SQLEXCEPTION
: сохраненная программа заканчивается в
запросе, который поднял условие, как будто был EXIT
.
Если программу вызвала другая сохраненная программа, дескрипторы программы
запроса, условие относится к своим собственным обработчикам.
SQLWARNING
: программа продолжает выполняться, как
будто был CONTINUE
.NOT FOUND
: если условие поднимается обычным порядком,
действие CONTINUE
. Если условие поднимается
SIGNAL
или
RESIGNAL
,
то действие EXIT
.Следующий пример использует обработчик для SQLSTATE '23000'
,
который происходит для дублирования ключа:
mysql> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1)); Query OK, 0 rows affected (0.00 sec) mysql> delimiter // mysql> CREATE PROCEDURE handlerdemo () -> BEGIN -> DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; -> SET @x = 1; -> INSERT INTO test.t VALUES (1); -> SET @x = 2; -> INSERT INTO test.t VALUES (1); -> SET @x = 3; -> END; -> // Query OK, 0 rows affected (0.00 sec) mysql> CALL handlerdemo()// Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x// +----+ | @x | +----+ | 3 | +----+ 1 row in set (0.00 sec)Заметьте, что
@x
= 3
после того, как процедура
выполняется, что показывает, что выполнение продолжалось до конца процедуры
после ошибки. Если DECLARE ...
HANDLER
не присутствовало, MySQL предпримет меры по умолчанию
(EXIT
) после второго INSERT
неудавшегося из-за PRIMARY KEY
и SELECT @x
возвратил бы 2
.
Чтобы проигнорировать условие, объявите обработчик CONTINUE
для этого и свяжите его с пустым блоком. Например:
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;Контекст метки блока не включает код для обработчиков, объявленных в пределах блока. Поэтому, запрос, связанный с обработчиком, не может использовать
ITERATE
или
LEAVE
, чтобы обратиться к меткам для
блоков, которые прилагают декларацию обработчика. Рассмотрите следующий
пример, где у блока REPEAT
есть метка retry
:
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN ITERATE retry; # illegal END; IF i < 0 THEN LEAVE retry;# legal END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT; END;Метка
retry
находится в контексте
IF
в пределах блока. Это не находится в контексте для обработчика
CONTINUE
, таким образом, ссылка там
недопустима и приводит к ошибке:
ERROR 1308 (42000): LEAVE with no matching label: retryЧтобы избежать ссылок на внешние метки в обработчиках, используйте одну из этих стратегий:
Чтобы оставить блок, используйте EXIT
.
Если никакая уборка блока не требуется,
BEGIN ... END
может быть пустым:
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END;Иначе, поместите запросы уборки в обработчик:
DECLARE EXIT HANDLER FOR SQLWARNING
BEGIN
block cleanup statements
END;
CONTINUE
, который может быть проверен в блоке приложения, чтобы
определить, был ли обработчик вызван. Следующий пример использует переменную
done
с этой целью:
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; DECLARE done INT DEFAULT FALSE; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN SET done = TRUE; END; IF done OR i < 0 THEN LEAVE retry; END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT; END;
GET [CURRENT | STACKED] DIAGNOSTICS {Запросы SQL производят диагностическую информацию, которая заполняет область диагностики.statement_information_item
[,statement_information_item
] ... | CONDITIONcondition_number
condition_information_item
[,condition_information_item
] ... }statement_information_item
:target
=statement_information_item_name
condition_information_item
:target
=condition_information_item_name
statement_information_item_name
: NUMBER | ROW_COUNTcondition_information_item_name
: CLASS_ORIGIN | SUBCLASS_ORIGIN | RETURNED_SQLSTATE | MESSAGE_TEXT | MYSQL_ERRNO | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CATALOG_NAME | SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | CURSOR_NAMEcondition_number
,target
: (see following discussion)
GET DIAGNOSTICS
позволяет приложениям смотреть эту информацию. Вы можете также
использовать SHOW WARNINGS
или SHOW ERRORS
, чтобы
видеть условия или ошибки.
Никакие специальные привилегии не нужны для
GET DIAGNOSTICS
.
CURRENT
позволяет получить информацию из текущей области
диагностики. Ключевое слово STACKED
позволяет получить
информацию из второй области диагностики, которая доступна, только если
текущий контекст это обработчик условия. Если никакое ключевое слово не дано,
значение по умолчанию должно использовать текущую область диагностики.
GET DIAGNOSTICS
,
как правило, используется в обработчике в пределах сохраненной программы. Это
расширение MySQL, для GET [CURRENT]
DIAGNOSTICS
разрешен внешний контекст обработчика, чтобы проверить
выполнение любого запроса SQL. Например, если Вы вызываете
mysql,
Вы можете ввести эти запросы:
mysql> DROP TABLE test.no_such_table; ERROR 1051 (42S02): Unknown table 'test.no_such_table' mysql> GET DIAGNOSTICS CONDITION 1 -> @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT; mysql> SELECT @p1, @p2; +-------+------------------------------------+ | @p1 | @p2 | +-------+------------------------------------+ | 42S02 | Unknown table 'test.no_such_table' | +-------+------------------------------------+Это расширение применяется только к текущей области диагностики. Это не относится к второй области диагностики потому, что
GET STACKED DIAGNOSTICS
разрешен, только если текущий контекст
обработчик условия. Если это не так, происходит ошибка
GET STACKED DIAGNOSTICS when handler not active
.
См. раздел 14.6.7.7. Кратко, это содержит два вида информации:
Информация о запросе, такая как число условий или количество затронутых строк.
Для запроса, который производит три условия, область диагностики содержит запрос и информацию об условии:
Statement information: row count ... other statement information items ... Condition area list: Condition area 1: error code for condition 1 error message for condition 1 ... other condition information items ... Condition area 2: error code for condition 2: error message for condition 2 ... other condition information items ... Condition area 3: error code for condition 3 error message for condition 3 ... other condition information items ...
GET DIAGNOSTICS
может получить запрос или информацию об условии, но не обоих в том
же самом запросе:
Чтобы получить информацию о запросе, получите желаемые элементы
запросов в целевые переменные. Этот
GET DIAGNOSTICS
назначает число доступных условий и количество затронутых строк к
пользовательским переменным @p1
и @p2
:
GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;
GET DIAGNOSTICS
назначает значение SQLSTATE и сообщение об ошибке пользовательским переменным
@p3
и @p4
:
GET DIAGNOSTICS CONDITION 1 @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;
Список извлечения определяет один или больше
,
отделенных запятыми. Каждое назначение называет целевую переменную и любой
указатель target
= item_name
statement_information_item_name
или
condition_information_item_name
, в зависимости от того,
получает ли запрос информацию об условии или запрос.
Допустимые указатели target
для того, чтобы хранить
информацию элемента могут быть хранимой процедурой или функциональными
параметрами, местными переменными, объявленными с
DECLARE
, или
определяемыми пользователем переменными.
Допустимые указатели condition_number
могут быть хранимой процедурой или функциональными параметрами, местными
перемеными, объявленными с DECLARE
, определяемыми пользователем переменными, системными переменными или
литералами. Символьный литерал может включать
_charset
. Предупреждение происходит, если номер
условия не находится в диапазоне от 1 до числа областей условия, у которых
есть информация. В этом случае предупреждение добавлено к области
диагностики, не очищая ее.
Когда условие происходит, MySQL не заполняет все элементы условия,
признанные GET DIAGNOSTICS
:
mysql> GET DIAGNOSTICS CONDITION 1 -> @p5 = SCHEMA_NAME, @p6 = TABLE_NAME; mysql> SELECT @p5, @p6; +-----+-----+ | @p5 | @p6 | +-----+-----+ | | | +-----+-----+В стандартном SQL, если есть многократные условия, первое условие касается
SQLSTATE
для предыдущего запроса SQL. В MySQL это не
гарантируется. Чтобы получить основную ошибку, Вы не можете сделать этого:
GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;Вместо этого получите количество условий сначала, затем используйте это, чтобы определить, которое условие смотреть:
GET DIAGNOSTICS @cno = NUMBER; GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;См. раздел 14.6.7.7.2 .
Вот пример, который использует GET
DIAGNOSTICS
и обработчик исключения в контексте хранимой
процедуры, чтобы оценить результат работы вставки. Если вставка была успешна,
процедура использует GET DIAGNOSTICS
, чтобы получить количество затронутых строк. Это показывает, что
Вы можете использовать GET
DIAGNOSTICS
многократно, чтобы получить информацию о запросе, пока
текущая область диагностики не была очищена.
CREATE PROCEDURE do_insert(value INT) BEGIN -- Declare variables to hold diagnostics area information DECLARE code CHAR(5) DEFAULT '00000'; DECLARE msg TEXT; DECLARE rows INT; DECLARE result TEXT; -- Declare exception handler for failed insert DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT; END; -- Perform the insert INSERT INTO t1 (int_col) VALUES(value); -- Check whether the insert was successful IF code = '00000' THEN GET DIAGNOSTICS rows = ROW_COUNT; SET result = CONCAT('insert succeeded, row count = ',rows); ELSE SET result = CONCAT('insert failed, error = ',code,', message = ',msg); END IF; -- Say what happened SELECT result; END;Предположите, что
t1.int_col
столбец целого числа, который объявлен как NOT NULL
.
Процедура приводит к этим результатам когда вызвана, чтобы вставить значения
не-NULL
и NULL
, соответственно:
mysql> CALL do_insert(1); +---------------------------------+ | result | +---------------------------------+ | insert succeeded, row count = 1 | +---------------------------------+ mysql> CALL do_insert(NULL); +-------------------------------------------------------------------------+ | result | +-------------------------------------------------------------------------+ | insert failed, error = 23000, message = Column 'int_col' cannot be null | +-------------------------------------------------------------------------+Когда обработчик условия активируется, обращение к стеку области диагностики происходит:
Первая (текущая) область диагностики становится второй областью диагностики, и новая текущая область диагностики создается как копия этого.
GET [CURRENT] DIAGNOSTICS
и GET STACKED DIAGNOSTICS
может использоваться в пределах обработчика, чтобы получить доступ к
содержанию областей диагностики.Более надежный способ получить информацию об активирующем обработчик
условии состоит в том, чтобы использовать стековую область диагностики,
которая не может быть изменена выполнением запросов в пределах обработчика,
кроме RESIGNAL
. См.
раздел 14.6.7.7.
Следующий пример показывает как GET STACKED DIAGNOSTICS
может использоваться в пределах обработчика, чтобы получить информацию об
обработанном исключении, даже после того, как текущая область диагностики
была изменена запросами обработчика.
В пределах хранимой процедуры p()
мы пытаемся вставить два
значения в таблицу, которая содержит столбец TEXT NOT NULL
.
Первое значение не-NULL
строка, второе NULL
.
Столбец запрещает NULL
, таким образом, первая вставка
преуспевает, но вторая дает исключение. Процедура включает обработчик
исключения, который отображает попытки вставить NULL
:
DROP TABLE IF EXISTS t1; CREATE TABLE t1 (c1 TEXT NOT NULL); DROP PROCEDURE IF EXISTS p; delimiter // CREATE PROCEDURE p () BEGIN -- Declare variables to hold diagnostics area information DECLARE errcount INT; DECLARE errno INT; DECLARE msg TEXT; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Here the current DA is nonempty because no prior statements -- executing within the handler have cleared it GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA before mapped insert' AS op, errno, msg; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA before mapped insert' AS op, errno, msg; -- Map attempted NULL insert to empty string insert INSERT INTO t1 (c1) VALUES(''); -- Here the current DA should be empty (if the INSERT succeeded), -- so check whether there are conditions before attempting to -- obtain condition information GET CURRENT DIAGNOSTICS errcount = NUMBER; IF errcount = 0 THEN SELECT 'mapped insert succeeded, current DA is empty' AS op; ELSE GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA after mapped insert' AS op, errno, msg; END IF; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA after mapped insert' AS op, errno, msg; END; INSERT INTO t1 (c1) VALUES('string 1'); INSERT INTO t1 (c1) VALUES(NULL); END; // delimiter ; CALL p(); SELECT * FROM t1;Когда обработчик активируется, копия текущей области диагностики продвинута к стеку области диагностики. Обработчик показывает содержание текущей и стековой областей диагностики, которые являются тем же самым первоначально:
+---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | current DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+ +---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | stacked DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+Запросы, выполняющиеся после
GET
DIAGNOSTICS
, могут сбросить текущую область диагностики.
Например, обработчик отображает вставку NULL
к пустой строке, вставляет и выводит на экран результат. Новая вставка
следует и очищает текущую область диагностики, но стековая область
диагностики остается неизменной и все еще содержит информацию об условии,
которое активировало обработчик:
+----------------------------------------------+ | op | +----------------------------------------------+ | mapped insert succeeded, current DA is empty | +----------------------------------------------+ +--------------------------------+-------+----------------------------+ | op | errno | msg | +--------------------------------+-------+----------------------------+ | stacked DA after mapped insert | 1048 | Column 'c1' cannot be null | +--------------------------------+-------+----------------------------+Когда обработчик условия заканчивается, его текущая область диагностики убрана из стека, и стековая область диагностики становится текущей областью диагностики в хранимой процедуре.
После возвращений процедуры таблица содержит две строки. Пустая строка
следует из попытки вставить NULL
, что
было отображено на пустую строку:
+----------+ | c1 | +----------+ | string 1 | | | +----------+В предыдущем примере первые два
GET
DIAGNOSTICS
в пределах обработчика условия получают информацию из
текущей и стековой областей диагностики и возвращают те же самые значения.
Это не будет иметь место, если выполняются запросы, которые сбрасывают
текущую область диагностики ранее в пределах обработчика. Предположите, что
p()
переписана, чтобы поместить
DECLARE
в
пределах определения обработчика вместо того, чтобы предшествовать этому:
CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Declare variables to hold diagnostics area information DECLARE errcount INT; DECLARE errno INT; DECLARE msg TEXT; GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA before mapped insert' AS op, errno, msg; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA before mapped insert' AS op, errno, msg; ...В этом случае результат зависит от версии:
До MySQL 5.7.2 DECLARE
не изменяет текущую область диагностики, таким образом, первые два
GET DIAGNOSTICS
возвращают
тот же самый результат, так же, как в оригинальной версии p()
.
В MySQL 5.7.2 работа была сделана, чтобы гарантировать, что все
недиагностические запросы заполняют область диагностики по стандарту SQL.
DECLARE
один из них, таким
образом, в 5.7.2 и выше выполнение запросов
DECLARE
в начале обработчика очищает текущую область диагностики и
запросы GET DIAGNOSTICS
приводят к различным результатам:
+---------------------------------+-------+------+ | op | errno | msg | +---------------------------------+-------+------+ | current DA before mapped insert | NULL | NULL | +---------------------------------+-------+------+ +---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | stacked DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+
Чтобы избегать этой проблемы в пределах обработчика условия, стремясь получить информацию об условии, которое активировало обработчик, убедитесь, что получили доступ к стековой области диагностики, а не текущей области диагностики.
RESIGNAL [condition_value
] [SETsignal_information_item
[,signal_information_item
] ...]condition_value
: SQLSTATE [VALUE]sqlstate_value
|condition_name
signal_information_item
:condition_information_item_name
=simple_value_specification
condition_information_item_name
: CLASS_ORIGIN | SUBCLASS_ORIGIN | MESSAGE_TEXT | MYSQL_ERRNO | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CATALOG_NAME | SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | CURSOR_NAMEcondition_name
,simple_value_specification
: (see following discussion)
RESIGNAL
передает информацию о
состоянии ошибки, которая доступна во время выполнения обработчика условия в
пределах составного запроса в хранимой процедуре или функции, триггере или
событии. RESIGNAL
может изменить некоторую или всю информацию перед передачей этого.
RESIGNAL
связан с
SIGNAL
,
но вместо того, чтобы породить условие как
SIGNAL
,
RESIGNAL
передает
существующую информацию об условии, возможно после изменения этого.
RESIGNAL
позволяет обработать ошибку и возвратить информацию об ошибке. Иначе выполняя
запрос SQL в пределах обработчика, информация, которая вызвала активацию
обработчика, разрушена. RESIGNAL
также может сделать некоторые процедуры короче, если данный обработчик может
обработать часть ситуации, то передать условие к другому обработчику.
Никакие специальные привилегии не требуются для
RESIGNAL
.
Все формы RESIGNAL
требуют, чтобы текущий контекст был обработчиком условия. Иначе
RESIGNAL
будет ошибка
RESIGNAL when handler not active
.
См. разделы 14.6.7.3 и 14.6.7.7.
Для condition_value
и
signal_information_item
определения и правила как для
RESIGNAL
и
SIGNAL
. Например,
condition_value
может быть SQLSTATE
,
значение могут указать на ошибки, предупреждения или not found
. См. раздел 14.6.7.5.
RESIGNAL
берет
condition_value
и SET
, оба являются
дополнительными. Это приводит к нескольким возможным применениям:
RESIGNAL
один:
RESIGNAL;
RESIGNAL
с новой информацией о сигнале:
RESIGNAL SETsignal_information_item
[,signal_information_item
] ...;
RESIGNAL
со значением условия и возможно новой информацией о сигнале:
RESIGNALcondition_value
[SETsignal_information_item
[,signal_information_item
] ...];
Эти случаи использования изменяют области условия и диагностики:
Область диагностики содержит одну или более областей условия.
SQLSTATE
, MYSQL_ERRNO
или
MESSAGE_TEXT
.Есть стек областей диагностики. Когда обработчик берет на себя управление, он продвигает область диагностики к вершине стека, таким образом во время выполнения обработчика есть две области диагностики:
Первая (текущая) область диагностики, которая запускается как копия последней области диагностики, но будет перезаписана первым запросом в обработчике, который изменяет текущую область диагностики.
Максимальное количество областей условия в области диагностики определено
значением max_error_count
. См.
раздел 14.6.7.7.5.
Простой RESIGNAL
означает, что передает ошибку без изменений.
Это восстанавливает последнюю область диагностики и делает это текущей
областью диагностики. Таким образом, это помещает
области диагностики в стек.
В пределах обработчика условия, который ловит условие, использование
RESIGNAL
должно выполнить некоторые другие действия, и затем передать без изменения
оригинальную информацию об условии (информацию, которая существовала
перед входом в обработчик).
Пример:
DROP TABLE IF EXISTS xx; delimiter // CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET @error_count = @error_count + 1; IF @a = 0 THEN RESIGNAL; END IF; END; DROP TABLE xx; END// delimiter ; SET @error_count = 0; SET @a = 0; CALL p();Предположите, что запрос
DROP TABLE xx
терпит неудачу. Стек
области диагностики похож на это:
DA 1. ERROR 1051 (42S02): Unknown table 'xx'Тогда выполнение вызывает обработчик
EXIT
.
Это запускается, продвигая область диагностики к вершине стека, который
теперь похож на это:
DA 1. ERROR 1051 (42S02): Unknown table 'xx' DA 2. ERROR 1051 (42S02): Unknown table 'xx'В этом пункте содержание первых (текущих) и вторых областей диагностики то же самое. Первая область диагностики может быть изменена запросами, выполняющимися впоследствии в пределах обработчика.
Обычно запрос процедуры очищает первую область диагностики.
BEGIN
исключение, это не очищает, это ничего не делает.
SET
не исключение, это очищает, выполняет работу и приводит к
результату success. Стек области диагностики
теперь похож на это:
DA 1. ERROR 0000 (00000): Successful operation DA 2. ERROR 1051 (42S02): Unknown table 'xx'В этом пункте, если
@a = 0
,
RESIGNAL
помещает область диагностики в стек, который теперь похож на это:
DA 1. ERROR 1051 (42S02): Unknown table 'xx'И именно это видит вызывающий.
Если @a
не 0, обработчик просто заканчивается, что означает,
что нет больше использования для текущей области диагностики (все
обработано). Таким образом, это может быть выброшено, заставляя стековую
область диагностики стать текущей областью диагностики снова. Стек области
диагностики похож на это:
DA 1. ERROR 0000 (00000): Successful operationДетали заставляют это выглядеть сложным, но конечный результат довольно полезен: обработчики могут выполниться, не разрушая информацию об условии, которое вызвало активацию обработчика.
RESIGNAL
с SET
предоставляет новую информацию о сигнале, таким образом, запрос означает, что
ошибку передают с изменениями:
RESIGNAL SETКак сsignal_information_item
[,signal_information_item
] ...;
RESIGNAL
идея состоит в том, чтобы вытолкать стек области диагностики так, чтобы
оригинальная информация была снаружи. В отличие от простого
RESIGNAL
,
что-либо определенное в SET
вносит изменения.
Пример:
DROP TABLE IF EXISTS xx; delimiter // CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET @error_count = @error_count + 1; IF @a = 0 THEN RESIGNAL SET MYSQL_ERRNO = 5; END IF; END; DROP TABLE xx; END// delimiter ; SET @error_count = 0; SET @a = 0; CALL p();Помните из предыдущего обсуждения, что
RESIGNAL
результаты в области диагностики складывает как это:
DA 1. ERROR 1051 (42S02): Unknown table 'xx'
RESIGNAL SET MYSQL_ERRNO = 5
приводит к этому стеку:
DA 1. ERROR 5 (42S02): Unknown table 'xx'Другими словами, это изменяет код ошибки и ничто иное.
RESIGNAL
может изменить любые из единиц информации сигнала, заставляя первую область
условия области диагностики выглядеть очень отличающейся.
RESIGNAL
с условием
означает, что условие продвигают в текущую область диагностики
. Если есть SET
,
он также изменяет информацию об ошибке.
RESIGNALЭта формаcondition_value
[SETsignal_information_item
[,signal_information_item
] ...];
RESIGNAL
восстанавливает последнюю область диагностики и делает это текущей областью
диагностики. Таким образом, это поднимает
стек области диагностики, который является тем же самым, как в простом
RESIGNAL
.
Однако, это также изменяет область диагностики в зависимости от значения
условия или информации о сигнале.
Пример:
DROP TABLE IF EXISTS xx; delimiter // CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET @error_count = @error_count + 1; IF @a = 0 THEN RESIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=5; END IF; END; DROP TABLE xx; END// delimiter ; SET @error_count = 0; SET @a = 0; SET @@max_error_count = 2; CALL p(); SHOW ERRORS;Это подобно предыдущему примеру и эффекты те же самые, за исключением того, что если
RESIGNAL
происходит,
область текущего положения выглядит по-другому в конце. Причина: условие
добавляется, а не заменяет существующее значение условия.
RESIGNAL
включает значение условия (SQLSTATE '45000'
),
таким образом, это добавляет новую область условия, приводящую к стеку
области диагностики, который похож на это:
DA 1. (condition 2) ERROR 1051 (42S02): Unknown table 'xx' (condition 1) ERROR 5 (45000) Unknown table 'xx'Результат
CALL p()
и
SHOW ERRORS
:
mysql> CALL p(); ERROR 5 (45000): Unknown table 'xx' mysql> SHOW ERRORS; +-------+------+--------------------+ | Level | Code | Message | +-------+------+--------------------+ | Error | 1051 | Unknown table 'xx' | | Error | 5 | Unknown table 'xx' | +-------+------+--------------------+
Все формы RESIGNAL
требуют, чтобы текущий контекст был обработчиком условия. Иначе
RESIGNAL
происходит ошибка
RESIGNAL when handler not active
:
mysql> CREATE PROCEDURE p () RESIGNAL; Query OK, 0 rows affected (0.00 sec) mysql> CALL p(); ERROR 1645 (0K000): RESIGNAL when handler not activeHere is a more difficult example:
delimiter // CREATE FUNCTION f () RETURNS INT BEGIN RESIGNAL; RETURN 5; END// CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @a=f(); SIGNAL SQLSTATE '55555'; END// delimiter ; CALL p();
RESIGNAL
происходит в пределах сохраненной функции f()
. Хотя
f()
непосредственно вызван в пределах контекста обработчика
EXIT
, выполнение в пределах f()
имеет его
собственный контекст, который не является контекстом обработчика.
Таким образом, RESIGNAL
в пределах f()
приводит к
ошибке handler not active.
SIGNALcondition_value
[SETsignal_information_item
[,signal_information_item
] ...]condition_value
: SQLSTATE [VALUE]sqlstate_value
|condition_name
signal_information_item
:condition_information_item_name
=simple_value_specification
condition_information_item_name
: CLASS_ORIGIN | SUBCLASS_ORIGIN | MESSAGE_TEXT | MYSQL_ERRNO | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CATALOG_NAME | SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | CURSOR_NAMEcondition_name
,simple_value_specification
: (see following discussion)
SIGNAL
это способ
вернуть ошибку.
SIGNAL
предоставляет информацию об ошибке обработчику, внешней
части приложения или клиенту. Кроме того, это обеспечивает управление
характеристиками ошибки (код ошибки, SQLSTATE
, сообщение). Без
SIGNAL
необходимо обратиться к обходным решениям, таким как преднамеренное обращение
к несуществующей таблице, чтобы заставить подпрограмму возвращать ошибку.
condition_value
в
SIGNAL
указывает на ошибочное
значение, которое будет возвращено. Это может быть SQLSTATE
(5-символьная строка) или condition_name
, которое
обращается к названному условию, ранее определенному с
DECLARE ... CONDITION
(см. раздел 14.6.7.1).
SQLSTATE
может указать на ошибки, предупреждения или
not found. Первые два символа значения указывают на
его ошибочный класс, как обсуждено в
разделе 14.6.7.5.1.
Некоторый сигнал оценивает завершение запроса, см.
раздел 14.6.7.5.2.
SQLSTATE
для SIGNAL
не должно начинаться с '00'
потому, что такие значения указывают
на успех и недопустимы для того, чтобы сигнализировать ошибку. Это истина
для указания SQLSTATE
в
SIGNAL
или в названном условии, упомянутом в запросе. Если значение недопустимо,
будет ошибка Bad SQLSTATE
.
SIGNAL
произвольно включает
SET
, который содержит многократные элементы сигнала в списке
разделенных запятой значений
condition_information_item_name
=
simple_value_specification
.
Каждый condition_information_item_name
может быть определен только однажды в SET
. Иначе будет ошибка
Duplicate condition information item
.
Допустимые указатели simple_value_specification
могут быть определены, используя хранимую процедуру или функциональные
параметры, местные переменные, объявленные с
DECLARE
,
определяемые пользователем переменные, системные переменные или литералы.
Символьный литерал может включать _charset
.
См. раздел 14.6.7.5.1 .
Следующая процедура сигнализирует ошибку или предупреждение в зависимости
от значения pval
:
CREATE PROCEDURE p (pval INT) BEGIN DECLARE specialty CONDITION FOR SQLSTATE '45000'; IF pval = 0 THEN SIGNAL SQLSTATE '01000'; ELSEIF pval = 1 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'An error occurred'; ELSEIF pval = 2 THEN SIGNAL specialty SET MESSAGE_TEXT = 'An error occurred'; ELSE SIGNAL SQLSTATE '01000' SET MESSAGE_TEXT = 'A warning occurred', MYSQL_ERRNO = 1000; SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'An error occurred', MYSQL_ERRNO = 1001; END IF; END;Если
pval
= 0, p()
сигнализирует предупреждение,
потому что значения SQLSTATE
, которые начинаются с
'01'
это сигналы в классе предупреждения. Предупреждение не
заканчивает процедуру, и может быть замечено с
SHOW WARNINGS
после завершения процедуры.
Если pval
= 1, p()
сигнализирует ошибку и устанавливает MESSAGE_TEXT
. Ошибка
заканчивает процедуру, и текст возвращен с информацией об ошибке.
Если pval
= 2, та же самая ошибка сообщена, хотя значение
SQLSTATE
определено, используя названное условие в этом случае.
Если pval
что-то другое, p()
сначала выдает предупреждение и ставит текст сообщения с кодом ошибки. Это
предупреждение не заканчивает процедуру, таким образом, выполнение
продолжается и p()
сигнализирует ошибку. Ошибка действительно
заканчивает процедуру. Текст сообщения и код ошибки, установленный
предупреждением, заменены значениями, установленными ошибкой, которые
возвращены с информацией об ошибке.
SIGNAL
, как правило,
используется в пределах сохраненных программ, но это расширение MySQL, потому
что этому разрешают внешний контекст обработчика. Например, если Вы вызываете
mysql, Вы
можете ввести любой из этих запросов при подсказке:
mysql> SIGNAL SQLSTATE '77777'; mysql> CREATE TRIGGER t_bi BEFORE INSERT ON t -> FOR EACH ROW SIGNAL SQLSTATE '77777'; mysql> CREATE EVENT e ON SCHEDULE EVERY 1 SECOND -> DO SIGNAL SQLSTATE '77777';
SIGNAL
выполняет согласно следующим правилам:
Если SIGNAL
указывает на SQLSTATE
, то значение используется, чтобы
сигнализировать определенное условие. Пример:
CREATE PROCEDURE p (divisor INT) BEGIN IF divisor = 0 THEN SIGNAL SQLSTATE '22012'; END IF; END;Если
SIGNAL
использует названное
условие, это условие должно быть объявлено в некотором контексте, который
относится к SIGNAL
,
и должно быть определено, используя значение SQLSTATE
, а не код
ошибки MySQL. Пример:
CREATE PROCEDURE p (divisor INT) BEGIN DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012'; IF divisor = 0 THEN SIGNAL divide_by_zero; END IF; END;Если названное условие не существует в пределах
SIGNAL
, будет
ошибка Undefined CONDITION
.
Если SIGNAL
обращается к названному условию, которое определено с кодом ошибки MySQL, а
не значением SQLSTATE
, будет ошибка SIGNAL/RESIGNAL
can only use a CONDITION defined with SQLSTATE
.
Следующие запросы вызывают эту ошибку, потому что названное условие связано с
кодом ошибки MySQL:
DECLARE no_such_table CONDITION FOR 1051; SIGNAL no_such_table;Если условие с именем объявлено многократно в различных контекстах, декларация с самым местным контекстом применяется. Рассмотрите следующую процедуру:
CREATE PROCEDURE p (divisor INT) BEGIN DECLARE my_error CONDITION FOR SQLSTATE '45000'; IF divisor = 0 THEN BEGIN DECLARE my_error CONDITION FOR SQLSTATE '22012'; SIGNAL my_error; END; END IF; SIGNAL my_error; END;Если
divisor
= 0, первый
SIGNAL
выполняется. Самая внутренняя декларация условия my_error
применяется, поднимая SQLSTATE
'22012'
.
Если divisor
не 0, второй
SIGNAL
выполняется.
Наиболее удаленная декларация условия my_error
применяется,
поднимая SQLSTATE
'45000'
.
См. раздел 14.6.7.6.
Сигналы могут быть подняты в пределах обработчиков исключения:
CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SIGNAL SQLSTATE VALUE '99999' SET MESSAGE_TEXT = 'An error occurred'; END; DROP TABLE no_such_table; END;
CALL p()
достигает DROP TABLE
. Нет никакой таблицы no_such_table
, таким образом,
ошибочный обработчик активирован. Ошибочный обработчик разрушает оригинальную
ошибку (no such table) и делает новую ошибку с
SQLSTATE
'99999'
и сообщением
An error occurred
.
Следующая таблица приводит названия единиц информации условия области
диагностики, которые могут быть установлены в
SIGNAL
(или
RESIGNAL
).
Все элементы стандартный SQL кроме MYSQL_ERRNO
,
который является расширением MySQL. Для получения дополнительной информации
об этих элементах см. раздел 14.6.7.7.
Item Name Definition --------- ---------- CLASS_ORIGIN VARCHAR(64) SUBCLASS_ORIGIN VARCHAR(64) CONSTRAINT_CATALOG VARCHAR(64) CONSTRAINT_SCHEMA VARCHAR(64) CONSTRAINT_NAME VARCHAR(64) CATALOG_NAME VARCHAR(64) SCHEMA_NAME VARCHAR(64) TABLE_NAME VARCHAR(64) COLUMN_NAME VARCHAR(64) CURSOR_NAME VARCHAR(64) MESSAGE_TEXT VARCHAR(128) MYSQL_ERRNO SMALLINT UNSIGNEDНабор символов для символьных элементов UTF-8.
Незаконно назначить NULL
к единице информации условия в
SIGNAL
.
SIGNAL
всегда определяет
SQLSTATE
, непосредственно или косвенно, обращаясь к названному
условию, определенному с SQLSTATE
.
Первые два символа SQLSTATE
это его класс, он определяет
значение по умолчанию для единиц информации условия:
Class = '00'
(success)
Незаконный. SQLSTATE
, которые начинаются с
'00'
указывают на успех и недопустимы для
SIGNAL
.
'01'
(warning)
MESSAGE_TEXT = 'Unhandled user-defined warning condition';
MYSQL_ERRNO = ER_SIGNAL_WARN
'02'
(not found)
MESSAGE_TEXT = 'Unhandled user-defined not found condition';
MYSQL_ERRNO = ER_SIGNAL_NOT_FOUND
'02'
(exception)
MESSAGE_TEXT = 'Unhandled user-defined exception condition';
MYSQL_ERRNO = ER_SIGNAL_EXCEPTION
Для допустимых классов другие единицы информации условия установлены следующим образом:
CLASS_ORIGIN = SUBCLASS_ORIGIN = ''; CONSTRAINT_CATALOG = CONSTRAINT_SCHEMA = CONSTRAINT_NAME = ''; CATALOG_NAME = SCHEMA_NAME = TABLE_NAME = COLUMN_NAME = ''; CURSOR_NAME = '';Ошибочные значения, которые доступны после выполнения
SIGNAL
передают значение
SQLSTATE
, поднятое SIGNAL
и его элементы MESSAGE_TEXT
и MYSQL_ERRNO
.
Эти значения доступны из C API:
SQLSTATE
: вызывает
mysql_sqlstate()
.
MYSQL_ERRNO
: вызывает
mysql_errno()
.MESSAGE_TEXT
: вызывает
mysql_error()
.
Из SQL вывод SHOW WARNINGS
и SHOW ERRORS
указывает значения MYSQL_ERRNO
и MESSAGE_TEXT
в
столбцах Code
и Message
.
Чтобы получить информацию из области диагностики, используйте
GET DIAGNOSTICS
(см.
раздел 14.6.7.3).
Сигналы имеют различные эффекты на выполнение запросов в зависимости от
класса сигнала. Класс определяет, насколько серьезна ошибка. MySQL игнорирует
значение sql_mode
,
в частности, строгий режим SQL не имеет значения. MySQL также игнорирует
IGNORE
: SIGNAL
должен
поднять произведенную пользователем ошибку явно, таким образом, сигнал
никогда не игнорируется.
В следующих описаниях unhandled значит, что
никакой обработчик для сообщенного SQLSTATE
не было определен с
DECLARE ... HANDLER
.
Class = '00'
(success)
Незаконный. SQLSTATE
, которые начинаются с '00'
,
указывают на успех и недопустимы для SIGNAL
.
'01'
(warning)
Значение warning_count
увеличивается. SHOW
WARNINGS
показывает сигнал. SQLWARNING
ловит сигнал.
Если сигнал не обработан в функции, запросы не заканчиваются.
'02'
(not found)
NOT FOUND
ловит сигнал. Нет никакого эффекта на курсоры. Если
сигнал не обработан в функции, запрос закончен.
'02'
(exception)
SQLEXCEPTION
ловит сигнал.
Если сигнал не обработан в функции, запрос закончен.
'40'
Обработан как обычное исключение.
Пример:
mysql> delimiter // mysql> CREATE FUNCTION f () RETURNS INT -> BEGIN -> SIGNAL SQLSTATE '01234'; -- signal a warning -> RETURN 5; -> END// mysql> delimiter ; mysql> CREATE TABLE t (s1 INT); mysql> INSERT INTO t VALUES (f());Результат состоит в том, что строка, содержащая 5, вставлена в таблицу
t
. Предупреждение, которое сообщено, может быть рассмотрено с
SHOW WARNINGS
.
Сохраненная программа может включать обработчики, которые будут вызваны, когда определенные условия происходят в пределах программы. Применимость каждого обработчика зависит от его местоположения в пределах определения программы и условий, которые это обрабатывает:
Обработчик, объявленный в BEGIN
... END
, находится в контексте только для запросов SQL после
деклараций обработчика в блоке. Если сам обработчик поднимает условие, он не
может обработать условие, не могут и любые другие обработчики, объявленные
в блоке. В следующем примере обработчики
H1
и H2
находятся в контексте для условий, поднятых запросами
stmt1
и stmt2
. Но ни один из
H1
и H2
не находятся в контексте для условий,
поднятых в теле H1
или H2
.
BEGIN -- outer block DECLARE EXIT HANDLER FOR ...; -- handler H1 DECLARE EXIT HANDLER FOR ...; -- handler H2stmt1
;stmt2
; END;
H1
находится в контексте
для stmt1
во внутреннем блоке, но не для
stmt2
во внешнем блоке:
BEGIN -- outer block BEGIN -- inner block DECLARE EXIT HANDLER FOR ...; -- handler H1stmt1
; END;stmt2
; END;
SQLSTATE
или имени условия. Общий
обработчик для условия в классе SQLWARNING
,
SQLEXCEPTION
или NOT FOUND
. Специфика условия
связана с приоритетом условия, как описано позже.Многократные обработчики могут быть объявлены в различных контекстах и с
различными спецификами. Например, мог бы быть определенный обработчик кода
ошибки MySQL во внешнем блоке и общий обработчик SQLWARNING
во внутреннем блоке. Или могли бы быть обработчики для определенного кода
ошибки MySQL и общий для класса SQLWARNING
в том же самом блоке.
Активирован ли обработчик, зависит не только от его собственного контекста
и значения условия, но и от того, что присутствуют другие обработчики. Когда
условие происходит в сохраненной программе, сервер ищет применимые
обработчики в текущем контексте (текущем блоке
BEGIN ... END
). Если нет никаких применимых обработчиков,
поиск продолжается направленный наружу с обработчиками в каждом
последовательном контексте (блоке). Когда сервер находит один или более
применимых обработчиков в данном контексте, он выбирает среди них,
исходя из приоритета:
Обработчик кода ошибки MySQL имеет
приоритет перед SQLSTATE
.
SQLSTATE
имеет приоритет перед общим
обработчиком SQLWARNING
, SQLEXCEPTION
или NOT FOUND
.SQLEXCEPTION
имеет приоритет перед
SQLWARNING
.Одно значение правил выбора обработчика: если многократные применимые обработчики происходят в различных контекстах, обработчики с самым местным контекстом имеют приоритет перед обработчикам во внешних контекстах, даже для более особых условий.
Если нет никакого соответствующего обработчика, когда условие происходит, предпринятые меры зависят от класса условия:
SQLEXCEPTION
: сохраненная программа заканчивается на
запросе, который поднял условие, как будто был EXIT
.
Если программу вызвала другая сохраненная программа, условие, используя
правила выбора обработчика, относится к своим собственным обработчикам.
SQLWARNING
: программа продолжает выполняться, как
будто был CONTINUE
.NOT FOUND
: если условие обычно поднималось, действие
CONTINUE
. Если это было поднято
SIGNAL
или
RESIGNAL
, действие EXIT
.Следующие примеры демонстрируют, как MySQL применяет правила выбора обработчика.
Эта процедура содержит два обработчика, один для определенного значения
SQLSTATE
('42S02'
) происходит для попыток удалить
несуществующую таблицу, и один для общего класса SQLEXCEPTION
:
CREATE PROCEDURE p1() BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DROP TABLE test.t; END;Оба обработчика объявлены в том же самом блоке и имеют тот же самый контекст. Однако,
SQLSTATE
имеет приоритет над SQLEXCEPTION
,
так что, если таблица t
не существует,
DROP TABLE
поднимает условие, которое активируется SQLSTATE
:
mysql> CALL p1(); +--------------------------------+ | msg | +--------------------------------+ | SQLSTATE handler was activated | +--------------------------------+Эта процедура содержит те же самые два обработчика. Но на сей раз,
DROP TABLE
и
SQLEXCEPTION
находятся во внутреннем
блоке относительно SQLSTATE
:
CREATE PROCEDURE p2() BEGIN -- outer block DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DROP TABLE test.t; -- occurs within inner block END; END;В этом случае обработчик, который является более местным, где условие происходит, имеет приоритет.
SQLEXCEPTION
активируется, даже при
том, что это является более общим, чем SQLSTATE
:
mysql> CALL p2(); +------------------------------------+ | msg | +------------------------------------+ | SQLEXCEPTION handler was activated | +------------------------------------+В этой процедуре один из обработчиков объявлен в блоке, внутреннем к контексту
DROP TABLE
:
CREATE PROCEDURE p3() BEGIN -- outer block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; END; DROP TABLE test.t; -- occurs within outer block END;Только
SQLEXCEPTION
применяется, потому что другой не находится
в контексте для условия, поднятого
DROP TABLE
:
mysql> CALL p3(); +------------------------------------+ | msg | +------------------------------------+ | SQLEXCEPTION handler was activated | +------------------------------------+В этой процедуре оба обработчика объявлены в блоке, внутреннем к контексту
DROP TABLE
:
CREATE PROCEDURE p4() BEGIN -- outer block BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; END; DROP TABLE test.t; -- occurs within outer block END;Никакой обработчик не применяется, потому что они не находятся в контексте для
DROP TABLE
. Условие,
поднятое запросом, идет необработанное и заканчивает процедуру с ошибкой:
mysql> CALL p4(); ERROR 1051 (42S02): Unknown table 'test.t'
Запросы SQL производят диагностическую информацию, которая заполняет
область диагностики. У стандартного SQL есть стек области диагностики,
содержащий область диагностики для каждого вложенного контекста выполнения.
Стандартный SQL также поддерживает GET STACKED DIAGNOSTICS
для того, чтобы обратиться к второй области диагностики во время выполнения
обработчика условия. MySQL поддерживает STACKED
с MySQL 5.7.
Этот раздел описывает структуру области диагностики в MySQL, единицы информации, признанные MySQL, как запросы, устанавливает область диагностики и то, как области диагностики продвинуты в стек.
Область диагностики содержит два вида информации:
Информация о запросе, такая как число условий, которые произошли, или количество затронутых строк.
Для запроса, который производит три условия, область диагностики содержит запрос и информацию об условиях:
Statement information: row count ... other statement information items ... Condition area list: Condition area 1: error code for condition 1 error message for condition 1 ... other condition information items ... Condition area 2: error code for condition 2: error message for condition 2 ... other condition information items ... Condition area 3: error code for condition 3 error message for condition 3 ... other condition information items ...
Область диагностики содержит единицы информации условия и запрос. Числовые
элементы это целые числа. Набор символов для символьных элементов UTF-8.
Никакой элемент не может быть NULL
.
Если элемент запросы или условия не установлены запросом, который заполняет
область диагностики, ее значение 0 или пустая строка, в зависимости от
типа данных элемента.
Часть информации о запросе области диагностики содержит эти элементы:
NUMBER
: Целое число, указывающее на число областей
условия, у которых есть информация.
ROW_COUNT
: Целое число, указывающее на число строк,
затронутых запросом. ROW_COUNT
имеет то же самое значение, как
функция ROW_COUNT()
(см. раздел 13.14).
Часть информации об условии области диагностики содержит область условия
для каждого условия. Области условия пронумерованы от 1 до значения
NUMBER
. Если NUMBER
= 0,
нет никаких областей условия.
Каждая область условия содержит элементы в следующем списке. Все элементы
из стандарта SQL, кроме MYSQL_ERRNO
, который является
расширением MySQL. Определения просят условия, произведенные не сигналом
(то есть, SIGNAL
или
RESIGNAL
).
Для условий не от сигнала MySQL заполняет только те элементы условия,
которые не описаны как всегда пустые. Эффекты сигналов на области
условия описаны позже.
CLASS_ORIGIN
: Строка, содержащая класс значения
RETURNED_SQLSTATE
. Если RETURNED_SQLSTATE
начинается со значения класса, определенного в SQL ISO 9075-2 (раздел 24.1),
CLASS_ORIGIN
= 'ISO 9075'
. Иначе
CLASS_ORIGIN
= 'MySQL'
.
SUBCLASS_ORIGIN
: Строка, содержащая подкласс
RETURNED_SQLSTATE
. Если CLASS_ORIGIN
=
'ISO 9075'
или RETURNED_SQLSTATE
заканчивается на
'000'
, SUBCLASS_ORIGIN
= 'ISO 9075'
.
Иначе SUBCLASS_ORIGIN
= 'MySQL'
.RETURNED_SQLSTATE
: Строка, которая указывает значение
SQLSTATE
для условия.MESSAGE_TEXT
: Строка, которая указывает на сообщение об
ошибке для условия.MYSQL_ERRNO
: Целое число, которое указывает на код ошибки
MySQL для условия.CONSTRAINT_CATALOG
, CONSTRAINT_SCHEMA
,
CONSTRAINT_NAME
: Строки, которые указывают на каталог, схему и
название нарушенного ограничения. Они всегда пусты.CATALOG_NAME
, SCHEMA_NAME
,
TABLE_NAME
, COLUMN_NAME
:
Строки, которые указывают на каталог, схему, таблицу и столбец, связанные с
условием. Они всегда пусты.CURSOR_NAME
: Строка, которая указывает на имя курсора.
Это всегда пусто.Для RETURNED_SQLSTATE
, MESSAGE_TEXT
и
MYSQL_ERRNO
для особых ошибок см.
раздел B.3.
Если SIGNAL
(или
RESIGNAL
)
заполняет область диагностики, SET
может назначить любую единицу
информации условия, кроме RETURNED_SQLSTATE
.
SIGNAL
также ставит
RETURNED_SQLSTATE
, но не непосредственно в SET
.
То значение прибывает из параметра SQLSTATE
SIGNAL
.
SIGNAL
также ставит единицы информации запроса. Если number
= 1, то
ROW_COUNT
= -1 для ошибок и 0 иначе.
Недиагностические запросы SQL заполняют область диагностики автоматически,
ее содержание может быть установлено явно с
SIGNAL
и
RESIGNAL
.
Область диагностики может быть исследована с
GET DIAGNOSTICS
, чтобы
извлечь определенные элементы, или с
SHOW WARNINGS
или
SHOW ERRORS
, чтобы
видеть условия или ошибки.
Запросы SQL определяют область диагностики следующим образом:
Когда сервер начинает выполнять запрос после парсинга, это очищает
область диагностики для недиагностических запросов. Диагностические запросы
не очищают область диагностики (SHOW
WARNINGS
, SHOW ERRORS
, GET DIAGNOSTICS
).
GET DIAGNOSTICS
и
RESIGNAL
добавлены к области диагностики, не очищая ее.Таким образом, даже запрос, который обычно не очищает область диагностики, когда начинает выполняться, очищает ее, если запрос поднимает условие.
Следующий пример показывает эффект различных запросов в области
диагностики, используя SHOW WARNINGS
, чтобы вывести на экран информацию об условиях, сохраненных там.
DROP TABLE
очищает область
диагностики и заполняет ее, когда условие происходит:
mysql> DROP TABLE IF EXISTS test.no_such_table; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> SHOW WARNINGS; +-------+------+------------------------------------+ | Level | Code | Message | +-------+------+------------------------------------+ | Note | 1051 | Unknown table 'test.no_such_table' | +-------+------+------------------------------------+ 1 row in set (0.00 sec)
SET
производит ошибку, таким
образом, очищает и заполняет область диагностики:
mysql> SET @x = @@x; ERROR 1193 (HY000): Unknown system variable 'x' mysql> SHOW WARNINGS; +-------+------+-----------------------------+ | Level | Code | Message | +-------+------+-----------------------------+ | Error | 1193 | Unknown system variable 'x' | +-------+------+-----------------------------+ 1 row in set (0.00 sec)
SET
произвел единственное условие, таким образом, 1 это единственное допустимое
число условий для GET DIAGNOSTICS
. Следующий запрос использует число условия 2, которое производит
предупреждение, добавленное к области диагностики, не очищая ее:
mysql> GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS; +-------+------+------------------------------+ | Level | Code | Message | +-------+------+------------------------------+ | Error | 1193 | Unknown system variable 'xx' | | Error | 1753 | Invalid condition number | +-------+------+------------------------------+ 2 rows in set (0.00 sec)Теперь есть два условия в области диагностики, таким образом, тот же самый
GET DIAGNOSTICS
работает:
mysql> GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @p; +--------------------------+ | @p | +--------------------------+ | Invalid condition number | +--------------------------+ 1 row in set (0.01 sec)
Когда происходит помещение области диагностики в стек, первая (текущая) область диагностики становится второй областью диагностики, и новая текущая область диагностики создается как копия этого. Области диагностики продвинуты в стек и извлечены из стека при следующих обстоятельствах:
Выполнение сохраненной программы.
Помещение происходит прежде, чем программа выполняется, а выталкивание
происходит позже. Если сохраненная программа заканчивается в то время, как
обработчики выполняются, может быть больше, чем одна область диагностики:
это происходит из-за исключения, для которого нет никаких соответствующих
обработчиков, или из-за
RETURN
в обработчике.
Любое предупреждение или ошибка во время выполнения сохраненной программы добавлены к текущей области диагностики, за исключением того, что для триггеров добавлены только ошибки. Когда сохраненная программа заканчивается, вызывающий видит эти условия в ее текущей области диагностики.
Когда помещение в стек происходит в результате активации обработчика
условия, стековая область диагностики это область, которая была актуальна в
пределах сохраненной программы до того. Новая теперь текущая область
диагностики эир текущая область диагностики обработчика.
GET [CURRENT] DIAGNOSTICS
и GET STACKED DIAGNOSTICS
может использоваться в пределах обработчика, чтобы получить доступ к
содержанию текущей (обработчик) и стековой (сохраненная программа) области
диагностики. Первоначально они возвращают тот же самый результат, но
выполнение запросов в пределах обработчика изменяет текущую область
диагностики, очищаяя и устанавливая ее содержание согласно нормальным
правилам (см. раздел 14.6.7.7.3
). Стековая область диагностики не может быть изменена выполнением
запросов в пределах обработчика, кроме
RESIGNAL
.
Если обработчик выполняется успешно, текущая (обработчик), область диагностики возвращена, а стековая (сохраненная программа) область диагностики снова становится текущей областью диагностики. Условия, добавленные к области диагностики обработчика во время выполнения обработчика, добавлены к текущей области диагностики.
RESIGNAL
.
RESIGNAL
передает информацию о
состоянии ошибки, которая доступна во время выполнения обработчика условия в
пределах составного запроса в сохраненной программе.
RESIGNAL
может изменить некоторую или всю информацию перед передачей, изменяя стек
диагностики, как описано в раздел 14.6.7.4.
Определенные системные переменные управляют или связаны с некоторыми аспектами области диагностики:
max_error_count
управляет числом областей условия в области диагностики. Если
больше условий происходит, MySQL тихо отказывается от информации для лишних
условий. Условия, добавленные RESIGNAL
, всегда добавляются с удалением более старых условий по мере
необходимости, чтобы создать место.
warning_count
указывает на число условий, которые произошли. Это включает ошибки,
предупреждения и примечания. Обычно NUMBER
и
warning_count
равны. Однако, поскольку число произведенных условий превышает
max_error_count
,
значение warning_count
продолжает повышаться тогда, как NUMBER
остается равным
max_error_count
,
потому что никакие дополнительные условия не сохранены в области диагностики.
error_count
указывает на число ошибок, которые произошли. Это значение включает
not found
и условия исключения, но исключает предупреждения и примечания. Как
warning_count
, это
значение может превысить
max_error_count
.
sql_notes
=0,
примечания не сохранены и не увеличивают
warning_count
.
Пример: Если
max_error_count
= 10, область диагностики может содержать максимум
10 областей условия. Предположите, что запрос поднимает 20 условий, 12 из
которых являются ошибками. В этом случае область диагностики содержит первые
10 условий, NUMBER
= 10,
warning_count
=
20, error_count
=
12.
Изменения
max_error_count
не имеют никакого эффекта до следующей попытки
изменить область диагностики. Если область диагностики содержит 10 областей
условия и max_error_count
= 5, это не имеет никакого непосредственного эффекта на размер
или контент области диагностики.
Информация учетной записи MySQL хранится в таблицах базы данных
mysql
. Эта база данных и система управления доступом обсуждены в
главе 6.
Некоторые выпуски MySQL вводят изменения структуры таблиц, чтобы добавить новые привилегии или особенности. Чтобы гарантировать, что Вы можете использовать любые новые способности, обновите свои таблицы, чтобы иметь текущую структуру всякий раз, когда Вы обновляете к новой версии MySQL. См. раздел 5.4.5.
Когда read_only
включена, запросы управления требуют привилегии
SUPER
в дополнение к
любым другим необходимым привилегиям. Это потому, что они изменяют таблицы в
базе данных mysql
.
ALTER USER [IF EXISTS]user_specification
[,user_specification
] ... [REQUIRE {NONE |tls_option
[[AND]tls_option
] ...}] [WITHresource_option
[resource_option
] ...] [password_option
|lock_option
] ... ALTER USER [IF EXISTS] USER() IDENTIFIED BY 'auth_string
' ALTER USER [IF EXISTS]user
DEFAULT ROLE {NONE | ALL |role
[,role
] ...}user_specification
:user
[auth_option
]auth_option
: { IDENTIFIED BY 'auth_string
' | IDENTIFIED WITHauth_plugin
| IDENTIFIED WITHauth_plugin
BY 'auth_string
' | IDENTIFIED WITHauth_plugin
AS 'hash_string
' }tls_option
: { SSL | X509 | CIPHER 'cipher
' | ISSUER 'issuer
' | SUBJECT 'subject
' }resource_option
: { MAX_QUERIES_PER_HOURcount
| MAX_UPDATES_PER_HOURcount
| MAX_CONNECTIONS_PER_HOURcount
| MAX_USER_CONNECTIONScount
}password_option
: { PASSWORD EXPIRE | PASSWORD EXPIRE DEFAULT | PASSWORD EXPIRE NEVER | PASSWORD EXPIRE INTERVALN
DAY }lock_option
: { ACCOUNT LOCK | ACCOUNT UNLOCK }
ALTER USER
изменяет учетные записи MySQL. Это позволяет аутентификации, SSL/TLS, пределу
ресурсов и свойствам пароля быть измененными для существующих учетных
записей и включает блокировку учетной записи.
За исключением DEFAULT ROLE
,
ALTER USER
требует глобальной
привилегии CREATE USER
или UPDATE
для базы данных mysql
. Для
DEFAULT ROLE
ALTER USER
требует этих привилегий:
Установить роль по умолчанию для другого пользователя: глобальная
CREATE USER
или UPDATE
для
mysql.default_roles
.
Когда включена read_only
, ALTER USER
требует
привилегию SUPER
.
Ошибка происходит, если Вы пытаетесь изменить учетную запись, которая не
существует. IF EXISTS
заставляет запрос производить
предупреждение для каждой названной учетной записи, которая не
существует, а не ошибку.
ALTER USER
меняет строку
таблицы mysql.user
для каждой затронутой учетной записи согласно
опциям, определенным в запросе. Неуказанные свойства сохраняют
свое текущее значение.
Пример 1: Измените пароль учетной записи. В результате пользователь должен соединиться с названным паролем и выбрать новый в следующем соединении:
ALTER USER 'jeffrey'@'localhost'
IDENTIFIED BY 'new_password
' PASSWORD EXPIRE;
Пример 2: Измените учетную запись для применения ее плагина аутентификации
sha256_password
и данного пароля. Потребуйте, чтобы новый пароль
был выбран каждые 180 дней:
ALTER USER 'jeffrey'@'localhost'
IDENTIFIED WITH sha256_password BY 'new_password
'
PASSWORD EXPIRE INTERVAL 180 DAY;
Пример 3: Заблокируйте или разблокируйте учетную запись:
ALTER USER 'jeffrey'@'localhost' ACCOUNT LOCK; ALTER USER 'jeffrey'@'localhost' ACCOUNT UNLOCK;Пример 4: Потребуйте, чтобы учетная запись использовала SSL и установите предел 20 соединений в час:
ALTER USER 'jeffrey'@'localhost' REQUIRE SSL WITH MAX_CONNECTIONS_PER_HOUR 20;
При некоторых обстоятельствах ALTER
USER
может быть зарегистрирован в журналах сервера или на стороне
клиента в файле истории, например, в ~/.mysql_history
,
что означает, что пароли открытого текста могут быть считаны любым имеющим
доступ к этой информации. Для информации об условиях, при которых это
происходит для журналов сервера и как управлять этим см.
раздел 7.1.2.3.
Для подобной информации о клиентском журналировании см.
раздел 5.5.1.3.
Каждое имя учетной записи использует формат, описанный в
разделе 7.2.3.
Если Вы определяете только часть имени пользователя имени учетной записи,
часть имени хоста '%'
. Также возможно определить
CURRENT_USER
или
CURRENT_USER()
,
чтобы ссылаться на учетную запись, связанную с текущим сеансом.
Для одного синтаксиса учетная запись может быть определена с помощью
USER()
:
ALTER USER USER() IDENTIFIED BY 'auth_string
';
Этот синтаксис позволяет изменить Ваш собственный пароль, не называя Вашу
учетную запись буквально.
Каждый параметр user_specification
состоит из имени учетной записи и дополнительного
auth_option
, которое определяет, как учетная запись
подтверждает подлинность. Эти значения позволяют плагинам аутентификации
учетной записи быть определенными. Каждый
auth_option
применяется только к
пользователю, названному перед этим.
После пользовательских технических требований запрос может включать опции для SSL/TLS, предела ресурса, истечения пароля и свойств блокировки. Все эти опции глобальны для запроса и относятся ко всем названным пользователям.
Пример: Это запрос изменяет пароль для jeffrey
, но не для
jeanne
. Для обеих учетных записей соединения обязаны
использовать SSL, и каждая учетная запись может использоваться максимум для
двух одновременных соединений:
ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'new_password
',
'jeanne'@'localhost' REQUIRE SSL WITH MAX_USER_CONNECTIONS 2;
В отсутствие особого типа опции учетная запись остается неизменной в этом
отношении. Например, без опции блокировки, статус блокировки учетной
записи не изменен.
Есть несколько аспектов ALTER
USER
, описанных в этом разделе:
Имя учетной записи может сопровождаться опцией аутентификации, которая определяет плагин аутентификации учетной записи:
auth_plugin
называет плагин аутентификации. Имя может быть заключенной в кавычки
буквальной строкой или именем. Имена сохранены в столбце
plugin
таблицы mysql.user
.
'auth_string
'
или
'hash_string
'
указывает пароль как открытый текст или хешированный в формате, ожидаемом
плагином аутентификации, соответственно. Данные сохранены в столбец
authentication_string
таблицы mysql.user
.
ALTER USER
разрешает такие форматы auth_option
:
IDENTIFIED BY '
auth_string
'
Устанавливает плагин аутентификации учетной записи в плагин по умолчанию,
хеширует открытый текст '
и
и хранит результат в строке auth_string
'mysql.user
учетной записи.
IDENTIFIED WITH auth_plugin
Устанавливает плагин аутентификации учетной записи в
auth_plugin
, очищает пароль к пустой строке (пароль
связан со старым плагином аутентификации, а не новым) и хранит результат в
строке mysql.user
учетной записи.
Кроме того, пароль отмечен как истекший. Пользователь должен выбрать новый, соединяясь.
IDENTIFIED WITH auth_plugin
BY
'auth_string
'
Устанавливает плагин аутентификации учетной записи в
auth_plugin
, хеширует открытый текст
'
и хранит результат в строке auth_string
'mysql.user
учетной записи.
IDENTIFIED WITH auth_plugin
AS
'hash_string
'
Устанавливает плагин аутентификации учетной записи в
auth_plugin
, берет хешированный пароль
'
как есть
и хранит результат в строке hash_string
'mysql.user
учетной записи. Строка
пароля, как предполагается, уже хеширована в формате, требуемом плагином.
Плагин по умолчанию mysql_native_password
, если переменная
default_authentication_plugin
не установлена иначе. Для описаний
каждого плагина см. раздел
7.5.1.
Пример 1: Определите пароль как открытый текст, плагин по умолчанию используется:
ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';Пример 2: Определите плагин аутентификации, наряду со значением пароля открытого текста:
ALTER USER 'jeffrey'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mypass';Пример 3: Определите плагин аутентификации, наряду с хешированным значением пароля:
ALTER USER 'jeffrey'@'localhost' IDENTIFIED WITH mysql_native_password AS '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';
MySQL может проверить признаки сертификата X509 в дополнение к обычной аутентификации, которая основана на имени пользователя и пароле. Для вводной информации об использовании SSL с MySQL см. раздел 7.4.
Чтобы определить опции SSL для учетной записи MySQL, используйте
REQUIRE
, который определяет одну или
больше tls_option
.
ALTER USER
разрешает
значения tls_option
:
NONE
Указывает, что у учетной записи нет никакого SSL или требований X509. Незашифрованные соединения разрешены, если имя пользователя и пароль допустимы. Однако, зашифрованные соединения могут также использоваться в опции клиента, если у клиента есть надлежащий сертификат и ключевые файлы.
Клиент должен определить только опцию
--ssl-mode=REQUIRED
, чтобы получить зашифрованное соединение.
Попытка соединения терпит неудачу, если SSL недоступен.
SSL
Говорит серверу разрешать только зашифрованные соединения для учетной записи.
ALTER USER 'jeffrey'@'localhost' REQUIRE SSL;Клиент должен определить только
--ssl-mode=REQUIRED
, чтобы получить зашифрованное соединение. Попытка соединения
терпит неудачу, если SSL недоступен.X509
Требует, чтобы у клиента был допустимый сертификат, но точный сертификат,
выпускающий и объект не имеют значения. Единственное требование: должно быть
возможно проверить свою подпись с одним из сертификатов CA. Использование
сертификатов X509 всегда подразумевает шифрование, таким образом, опция
SSL
является ненужной в этом случае.
ALTER USER 'jeffrey'@'localhost' REQUIRE X509;Клиент должен определить опции
--ssl-key
и
--ssl-cert
,
чтобы соединиться. Это рекомендуется, но не требуется:
--ssl-ca
также будет определена, чтобы публичный сертификат сервера
мог быть проверен. Это истина для ISSUER
и SUBJECT
,
так как опции REQUIRE
подразумевают требования
X509
.ISSUER 'issuer
'
Устанавливает ограничение для попыток соединения, которыми клиент должен
представить допустимый сертификат X509, выпущенн CA
'
.
Если клиент представляет сертификат, который допустим, но имеет иного
выпускающего, сервер отклоняет соединение. Использование серптификатов X509
всегда подразумевает шифрование, таким образом, опция
issuer
'SSL
не нужна.
Так как ISSUER
подразумевает требования X509
,
клиент должен определить
--ssl-key
и
--ssl-cert
.
Это рекомендуется, но не требуется:
--ssl-ca
также будет определена, чтобы публичный сертификат сервера мог быть проверен.
ALTER USER 'jeffrey'@'localhost' REQUIRE ISSUER '/C=SE/ST=Stockholm/L=Stockholm/ O=MySQL/CN=CA/emailAddress=ca@example.com';
SUBJECT 'subject
'
Устанавливает ограничение для попыток соединения, что клиент должен
представить допустимый сертификат X509, содержащий subject
. Если клиент представляет сертификат, который допустим, но имеет иной
subject, сервер отклоняет соединение. Использование сертификатов X509 всегда
подразумевает шифрование, таким образом, опция SSL
является
ненужной в этом случае.
Поскольку SUBJECT
подразумевает требования X509
,
клиент должен определить
--ssl-key
и
--ssl-cert
--ssl-ca
также будет определена, чтобы публичный сертификат сервера мог быть проверен.
ALTER USER 'jeffrey'@'localhost' REQUIRE SUBJECT '/C=SE/ST=Stockholm/L=Stockholm/ O=MySQL demo client certificate/ CN=client/emailAddress=client@example.com';MySQL делает простое строковое сравнение
'subject
'
со значением в сертификате, таким образом, регистр символов и порядок
составляющих должны быть даны точно как существующие в сертификате.
Относительно emailAddress
см. примечание в
описании REQUIRE ISSUER
.
CIPHER 'cipher
'
Просит определенный метод шифра для соединений. Эта опция необходима, чтобы гарантировать, что шифры и длины ключа достаточной силы используются. Сам SSL может быть слабым, если используются старые алгоритмы, использующие короткие ключи шифрования.
ALTER USER 'jeffrey'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
SUBJECT
, ISSUER
и CIPHER
могут быть объединены в REQUIRE
:
ALTER USER 'jeffrey'@'localhost' REQUIRE SUBJECT '/C=SE/ST=Stockholm/L=Stockholm/ O=MySQL demo client certificate/ CN=client/emailAddress=client@example.com' AND ISSUER '/C=SE/ST=Stockholm/L=Stockholm/ O=MySQL/CN=CA/emailAddress=ca@example.com' AND CIPHER 'EDH-RSA-DES-CBC3-SHA';Порядок опций не имеет значения, но никакая опция не может быть определена дважды.
AND
является дополнительным
между опциями REQUIRE
.
Возможно установить границы использования ресурсов сервера учетной
записью, как обсуждено в разделе
7.3.5. Чтобы сделать так, используйте WITH
, который
определяет одно или больше значений resource_option
:
ALTER USER
допускает такие
значения resource_option
:
MAX_QUERIES_PER_HOUR
,
count
MAX_UPDATES_PER_HOUR
,
count
MAX_CONNECTIONS_PER_HOUR
count
Эти опции ограничивают число запросов, обновлений и соединений с сервером,
разрешенных этой учетной записи во время любого данного одночасового периода.
Запросы, для которых результаты поданы от кэша запроса, не считаются.
Если count
= 0
(по умолчанию), это
означает, что нет никакого ограничения для учетной записи.
MAX_USER_CONNECTIONS count
Ограничивает максимальное количество одновременных соединений с сервером
для учетной записи. Отличное от нуля count
определяет предел для учетной записи явно. Если
count
= 0
(по умолчанию),
сервер определяет число одновременных соединений для учетной записи от
глобального значения
max_user_connections
. Если
max_user_connections
тоже 0, нет никакого предела для учетной записи.
Пример:
ALTER USER 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 500 MAX_UPDATES_PER_HOUR 100;Если данный предел ресурса определен многократно, последний случай имеет приоритет.
ALTER USER
поддерживает несколько password_option
для управления истечением пароля, чтобы истечь пароль учетной записи или
установить его логику. Стратегические опции не истекают
пароль, вместо этого они определяют, как сервер применяет автоматическое
истечение к учетной записи (см.
раздел 7.3.7).
Время жизни пароля оценено с даты и времени последнего изменения.
ALTER USER
позволяет
эти значения password_option
:
PASSWORD EXPIRE
Истекает пароль учетной записи.
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
PASSWORD EXPIRE DEFAULT
Устанавливает учетную запись так, чтобы глобальная политика истечения
применилась, как определено
default_password_lifetime
.
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
PASSWORD EXPIRE NEVER
Отключает истечение пароля для учетной записи так, чтобы ее пароль никогда не истек.
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
PASSWORD EXPIRE INTERVAL N
DAY
Устанавливает жизнь пароля учетной записи в N
дней.
Этот запрос требует, чтобы пароль был изменен каждые 180 дней:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 180 DAY;
Если многократные опции истечения пароля определены, последняя имеет приоритет.
Сеанс клиента работает в ограниченном режиме, если пароль учетной записи истек вручную или автоматически. В ограниченном режиме операции в пределах сеанса приводят к ошибке, пока пользователь не устанавливает новый пароль учетной записи. См. раздел 7.3.7.
Возможно сбросить, устанавливая это в его текущее значение. Предпочтительно выбрать иной пароль.
MySQL поддерживает блокировку учетной записи через
ACCOUNT LOCK
и ACCOUNT UNLOCK
,
которые определяют статус блокировки для учетной записи. Для дополнительного
обсуждения см. раздел 7.3.11.
Если многократные блокирующие учетную запись опции определены, последняя имеет приоритет.
ALTER USER ... DEFAULT ROLE
определяет, какие роли становятся активными, когда запрос
SET ROLE DEFAULT
выполнен во время сеанса для данного пользователя. После успешной
пользовательской аутентификации сервер неявно выполняет
SET ROLE DEFAULT
.
Следующий запрос назначает 'joe'@'10.0.0.1'
роли по умолчанию administrator
и developer
:
ALTER USER 'joe'@'10.0.0.1' DEFAULT ROLE administrator, developer;
CREATE ROLE [IF NOT EXISTS]role
[,role
] ...
CREATE ROLE
создает одну или более ролей, которые называют наборами привилегий. Чтобы
использовать это запрос, у Вас должна быть глобальная привилегия
CREATE ROLE
или
CREATE USER
.
Ошибка происходит, если Вы пытаетесь создать роль, которая уже существует.
IF NOT EXISTS
заменяет ошибку предупреждением.
Если CREATE ROLE
называет многократные роли, это преуспевает для всех названных ролей или
откатывается и не имеет никакого эффекта, если ошибка происходит.
Роль при создании заблокирована, не имеет никакого пароля, и ей назначен плагин аутентификации по умолчанию.
Для ролевых примеров использования см. раздел 7.3.4.
CREATE USER [IF NOT EXISTS]user_specification
[,user_specification
] ... [REQUIRE {NONE |tls_option
[[AND]tls_option
] ...}] [WITHresource_option
[resource_option
] ...] [password_option
|lock_option
] ...user_specification
:user
[auth_option
]auth_option
: { IDENTIFIED BY 'auth_string
' | IDENTIFIED BY PASSWORD 'hash_string
' | IDENTIFIED WITHauth_plugin
| IDENTIFIED WITHauth_plugin
BY 'auth_string
' | IDENTIFIED WITHauth_plugin
AS 'hash_string
' }tls_option
: { SSL | X509 | CIPHER 'cipher
' | ISSUER 'issuer
' | SUBJECT 'subject
' }resource_option
: { MAX_QUERIES_PER_HOURcount
| MAX_UPDATES_PER_HOURcount
| MAX_CONNECTIONS_PER_HOURcount
| MAX_USER_CONNECTIONScount
}password_option
: { PASSWORD EXPIRE | PASSWORD EXPIRE DEFAULT | PASSWORD EXPIRE NEVER | PASSWORD EXPIRE INTERVALN
DAY }lock_option
: { ACCOUNT LOCK | ACCOUNT UNLOCK }
CREATE USER
создает новые учетные записи MySQL. Это позволяет аутентификации, SSL/TLS,
пределу ресурса и свойствам истечения пароля быть установленными для новых
учетных записей, а также управляет, заблокированы ли учетные записи
первоначально или нет.
У учетной записи когда создается нет никаких привилегий и роль
по умолчанию NONE
.
Чтобы использовать CREATE USER
, Вы должны иметь глобальную привилегию
CREATE USER
или
привилегию INSERT
для базы данных mysql
. При включенной переменной
read_only
CREATE USER
дополнительно
требует SUPER
.
Ошибка происходит, если Вы пытаетесь создать учетную запись, которая уже
существует. IF NOT EXISTS
превращает ошибку в предупреждение.
Для каждой учетной записи CREATE USER
создает новую строку в таблице mysql.user
.
Строка отражает свойства, определенные в запросе. Неуказанные свойства
установлены в их значения по умолчанию.
Пример 1: Создайте учетную запись, которая использует плагин аутентификации по умолчанию и данный пароль. Отметьте пароль как истекший, чтобы пользователь выбрал новый в первом соединении с сервером:
CREATE USER 'jeffrey'@'localhost'
IDENTIFIED BY 'new_password
' PASSWORD EXPIRE;
Пример 2: Создайте учетную запись, которая использует
плагин аутентификации sha256_password
и данный пароль. Потребуйте, чтобы новый пароль был выбран каждые 180 дней:
CREATE USER 'jeffrey'@'localhost'
IDENTIFIED WITH sha256_password BY 'new_password
'
PASSWORD EXPIRE INTERVAL 180 DAY;
При некоторых обстоятельствах CREATE
USER
может быть зарегистрирован в журналах сервера или на стороне
клиента в файле истории ~/.mysql_history
, что означает, что
пароли открытого текста могут быть считаны любым имеющим доступ к этой
информации. Для информации об условиях, при которых это происходит для
журналов сервера и как управлять ею, см.
раздел 7.1.2.3.
Каждое имя учетной записи использует формат, описанный в разделе 7.2.3:
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';Если Вы определяете только часть имени пользователя имени учетной записи, часть имени хоста
'%'
.
Каждый user_specification
состоит из имени учетной записи и дополнительного значения
auth_option
, которое определяет, как учетная запись
подтверждает подлинность. Эти значения позволяют плагинам аутентификации
учетной записи быть определенными. Каждое значение
auth_option
применяется только
к пользователю, названному перед этим.
После пользовательских технических требований запрос может включать опции для SSL/TLS, предела ресурса, истечения пароля и свойств блокировки. Все эти опции глобальны для запроса и относятся ко всем названным пользователям.
Пример: этот запрос создает две учетных записи, каждую с плагином аутентификации по умолчанию и паролем. Для обеих учетных записей соединения должны быть сделаны, используя допустимый сертификат X509, и разрешены до 60 запросов в час. Обе учетных записи заблокированы первоначально и не могут использоваться, пока администратор не разблокирует их:
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'Для опущенных опций используются эти значения по умолчанию:new_password1
', 'jeanne'@'localhost' IDENTIFIED BY 'new_password2
' REQUIRE X509 WITH MAX_QUERIES_PER_HOUR 60 ACCOUNT LOCK;
Аутентификация: плагин аутентификации, определенный
default_authentication_plugin
и пустой пароль.
NONE
.PASSWORD EXPIRE DEFAULT
.ACCOUNT UNLOCK
.Есть несколько аспектов
CREATE USER
:
Опции аутентификации
Все они в целом аналогичны описанным для команды
ALTER USER
.
DROP ROLE [IF EXISTS]role
[,role
] ...
DROP ROLE
удаляет одну или более ролей (наборов привилегий). Чтобы использовать этот
запрос, у Вас должна быть глобальная привилегия
DROP ROLE
или
привилегия CREATE USER
.
Ошибка происходит, если Вы пытаетесь удалить роль, которая не существует.
IF EXISTS
заставляет запрос производить предупреждение, а не
ошибку для каждой названной роли, которая не существует.
Если DROP ROLE
названо много ролей, это преуспевает для всех названных ролей или
откатывается и не имеет никакого эффекта, если ошибка происходит.
Удаленная роль автоматически отменяется от любой учетной записи пользователя, которой включали роль. Привилегии для любого текущего сеанса для такой учетной записи скорректированы для следующего запроса, выполненного в пределах сеанса.
DROP USER [IF EXISTS]user
[,user
] ...
DROP USER
удаляет одну или более учетных записей MySQL и их привилегии.
Это удаляет строки привилегии для учетной записи из всех таблиц.
Для применения DROP USER
Вы должны иметь глобальную привилегию
CREATE USER
или привилегию DELETE
для базы данных mysql
. При включенной опции
read_only
DROP USER
дополнительно
требует привилегию SUPER
.
Ошибка происходит, если Вы пытаетесь удалить учетную запись, которая не
существует. IF EXISTS
превращает ошибку в предупреждение.
Каждое имя учетной записи использует формат, описанный в разделе 7.2.3:
DROP USER 'jeffrey'@'localhost';Если Вы определяете только часть имени пользователя имени учетной записи, часть имени хоста
'%'
.
DROP USER
автоматически не закрывает открытых пользовательских сеансов. Когда
пользователь с открытым сеансом удален, запрос не вступает в силу до закрытия
сеанса пользователя. Как только сеанс закрыт, пользователь удален, и
следующая попытка пользователя войти в систему потерпит неудачу.
DROP USER
автоматически не удаляет базы данных или объекты в их пределах, которых
создал старый пользователь. Это включает сохраненные программы или
представления, для которых DEFINER
это удаленный пользователь.
Попытки получить доступ к таким объектам могут произвести ошибку, если они
выполняются в контексте безопасности определителя.
Для информации о контексте безопасности см.
раздел 21.6.
GRANTpriv_type
[(column_list
)] [,priv_type
[(column_list
)]] ... ON [object_type
]priv_level
TOuser_specification
[,user_specification
] ... [REQUIRE {NONE |tls_option
[[AND]tls_option
] ...}] [WITH {GRANT OPTION |resource_option
} ...] GRANT PROXY ONuser_specification
TOuser_specification
[,user_specification
] ... [WITH GRANT OPTION] GRANTrole
[,role
] ... TOuser
[,user
] ... [WITH ADMIN OPTION]object_type
: { TABLE | FUNCTION | PROCEDURE }priv_level
: { * | *.* |db_name
.* |db_name.tbl_name
|tbl_name
|db_name
.routine_name
}user_specification
:user
[auth_option
]auth_option
: { IDENTIFIED BY 'auth_string
' | IDENTIFIED BY PASSWORD 'hash_string
' | IDENTIFIED WITHauth_plugin
| IDENTIFIED WITHauth_plugin
BY 'auth_string
' | IDENTIFIED WITHauth_plugin
AS 'hash_string
' }tls_option
: { SSL | X509 | CIPHER 'cipher
' | ISSUER 'issuer
' | SUBJECT 'subject
' }resource_option
: { | MAX_QUERIES_PER_HOURcount
| MAX_UPDATES_PER_HOURcount
| MAX_CONNECTIONS_PER_HOURcount
| MAX_USER_CONNECTIONScount
}
GRANT
позволяет системным
администраторам предоставить привилегии и роли, которые они могут
предоставить учетным записям пользователя и ролям.
Эти ограничения синтаксиса применяются:
GRANT
не может смешать предоставление привилегий и ролей в том же самом запросе.
Данный GRANT
должен предоставить
привилегии или роли.
ON
различает, предоставляет ли запрос привилегии или роли:
С ON
запрос предоставляет привилегии.
ON
запрос предоставляет роли.Разрешено назначить привилегии и роли учетной записи, но Вы должны
использовать отдельные запросы GRANT
для ролей и привилегий.
Чтобы использовать GRANT
Вы
должны иметь привилегию GRANT
OPTION
и у Вас должны быть привилегии, которые Вы предоставляете.
Когда включена переменная
read_only
, GRANT
дополнительно требует привилегию
SUPER
.
REVOKE
связан с
GRANT
и позволяет администраторам
удалить привилегии учетной записи. См.
раздел 14.7.1.8.
Обычно администратор базы данных сначала использует
CREATE USER
, чтобы
создать учетную запись и определить такие ее характеристики, как пароль,
использует ли это безопасные соединения и ограничения на доступ к ресурсам
сервера, затем использует GRANT
,
чтобы определить привилегии. ALTER USER
может использоваться, чтобы изменить характеристики существующих
учетных записей. Например:
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass'; GRANT ALL ON db1.* TO 'jeffrey'@'localhost'; GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost'; ALTER USER 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;
Примеры, показанные здесь, не включают IDENTIFIED
.
Предполагается, что Вы устанавливаете пароли с
CREATE USER
во время создания
учетной записи, чтобы избежать создавать опасные учетные записи.
Если учетную запись называют в GRANT
, но она не существует, GRANT
может создать это при условиях, описанных позже в обсуждении режима SQL
NO_AUTO_CREATE_USER
. Также возможно использовать GRANT
, чтобы определить такие характеристики, как использует ли
учетная запись безопасные соединения и пределы доступа к ресурсам сервера.
Однако, использование GRANT
,
чтобы создать учетные записи или определить характеристики устарело. Вместо
этого выполните эти задачи с использованием
CREATE USER
или ALTER
USER
.
Из mysql
GRANT
отвечает
Query OK, 0 rows affected
, когда выполнен успешно. Чтобы
определить, какие привилегии даны, надо использовать
SHOW GRANTS
. См.
раздел 14.7.5.21.
Есть несколько аспектов
GRANT
:
GRANT
понимает имена хоста до 60 символов в длину.
База данных, таблица, столбец и имена подпрограмм могут быть до 64 символов.
Имена пользователей могут быть до 32 символов.
Допустимая длина для имен пользователя не может быть изменена,
изменяя mysql.user
. Попытка сделать так приведет к
непредсказуемому поведении, которое может даже лишить возможности
пользователей входить в систему. Вы никогда не должны изменять
структуру таблиц в базе данных mysql
в любой манере вообще,
кроме процедуры, описанной в
разделе 5.4.5.
Следующая таблица суммирует допустимые типы привилегии
priv_type
, которые могут быть определены для
GRANT
и
REVOKE
,
и уровни, на которых можно предоставить каждую привилегию.
Для дополнительной информации об этих привилегиях см.
раздел 7.2.1.
Таблица 14.3. Допустимые привилегии для GRANT и REVOKE
Привилегия | Значение и уровни |
---|---|
ALL [PRIVILEGES] | Предоставить все привилегии на
указанном уровне доступа, кроме
GRANT OPTION |
ALTER
| Включает использование ALTER
TABLE . Уровни: глобальный, база данных, таблица. |
ALTER
ROUTINE | Позволяет сохраненным подпрограммам быть измененными или удаленными. Уровни: глобальный, база данных, процедура. |
CREATE
| Включает создание таблиц и баз данных. Уровни: глобальный, база данных, таблица. |
CREATE
ROUTINE | Включает создание сохраненных подпрограмм. Уровни: глобальный, база данных. |
CREATE TABLESPACE | Позволяет создавать, изменять или удалять табличные пространства и группы файлов системного журнала. Уровень: глобальный. |
CREATE TEMPORARY TABLES | Разрешает использовать
CREATE TEMPORARY TABLE .
Уровни: глобальный, база данных. |
CREATE
USER | Позволяет использование
CREATE USER ,
DROP USER ,
RENAME USER и
REVOKE ALL PRIVILEGES .
Уровень: глобальный. |
CREATE
VIEW | Позволяет создавать или изменять представления. Уровни: глобальный, база данных, таблица. |
DELETE
| Разрешает использовать DELETE
. Уровни: глобальный, база данных, таблица. |
DROP
| Позволяет удалять базы данных, таблицы и представления. Уровни: глобальный, база данных, таблица. |
EVENT
| Включает использование событий для Event Scheduler. Уровни: глобальный, база данных. |
EXECUTE
| Позволяет пользователю выполнить сохраненные подпрограммы. Уровни: глобальный, база данных, таблица. |
FILE
| Позволяет пользователю заставить сервер читать или писать файлы. Уровень: глобальный. |
GRANT
OPTION | Позволяет предоставлять или удалять привилегии из других учетных записей. Уровни: глобальный, база данных, таблица, процедура, proxy. |
INDEX
| Включает создание или удаление индекса. Уровни: глобальный, база данных, таблица. |
INSERT
| Разрешает INSERT .
Уровни: глобальный, база данных, таблица, столбец. |
LOCK
TABLES | Включить использование
LOCK TABLES
на таблицах, для которых Вы имеете привилегию
SELECT .
Уровни: глобальный, база данных. |
PROCESS
| Позволяет пользователю видеть все процессы с
SHOW PROCESSLIST .
Уровень: глобальный. |
PROXY
| Включает пользователю proxying. Уровень: От пользователя пользователю. |
REFERENCES
| Включает создание внешнего ключа. Уровни: глобальный, база данных, таблица, столбец. |
RELOAD
| Включает использование FLUSH
. Уровень: глобальный. |
REPLICATION CLIENT | Позволяет пользователю запросить основные или ведомые серверы. Уровень: глобальный. |
REPLICATION SLAVE | Позволяет ведомым устройствам читать двоичные события журнала с ведущего устройства. Уровень: глобальный. |
SELECT
| Включает использование SELECT
. Уровни: глобальный, база данных, таблица, столбец. |
SHOW
DATABASES | Позволяет
SHOW DATABASES показать все базы данных.
Уровень: Глобальный. |
SHOW VIEW
| Позволяет SHOW
CREATE VIEW . Уровни: глобальный, база данных, таблица. |
SHUTDOWN
| Позволяет mysqladmin shutdown. Уровень: Глобальный. |
SUPER
| Позволяет использование других административных задач:
CHANGE MASTER TO ,
KILL ,
PURGE BINARY LOGS ,
SET GLOBAL и
mysqladmin debug
. Уровень: Глобальный. |
TRIGGER
| Включить работу с триггерами. Уровни: глобальный, база данных, таблица. |
UPDATE
| Разрешает UPDATE .
Уровни: глобальный, база данных, таблица, столбец. |
USAGE
| Синоним для no privileges. |
Триггер связан с таблицей, так что, чтобы создать или удалить триггер, Вы
должны иметь привилегию TRIGGER
для таблицы, а не триггера.
В GRANT
ALL [PRIVILEGES]
или
PROXY
привилегию нужно назвать отдельно, она не может быть определена наряду с
другими привилегиями. ALL
[PRIVILEGES]
синоним для всех привилегий, доступных для уровня, на
котором привилегии предоставлены, за исключением
GRANT OPTION
и
PROXY
.
USAGE
может быть определен, чтобы создать пользователя, у которого нет никаких
привилегий, или определить REQUIRE
или WITH
для учетной записи, не изменяя ее существующие привилегии. Однако,
использование GRANT
, чтобы
определить такие характеристики устарело в MySQL 5.7.6. Используйте
CREATE USER
или
ALTER USER
.
Информация учетной записи MySQL хранится в таблицах базы данных
mysql
. Подробности в
разделе 7.2.
Если таблицы содержат строки привилегии, которые содержат имена базы
данных или имена таблиц смешанного регистра и
lower_case_table_names
не 0, REVOKE
не может использоваться, чтобы отменить эти привилегии. Будет
необходимо управлять таблицами непосредственно. (
GRANT
не будет создавать такие строки, когда установлена
lower_case_table_names
, но такие строки, возможно, были созданы до
установки этой переменной.
Привилегии можно предоставить на нескольких уровнях, в зависимости от
синтаксиса, используемого для ON
. Для
REVOKE
ON
определяет, которые привилегии удалить.
Для уровней глобального, базы данных, таблицы и подпрограммы
GRANT ALL
назначает только привилегии, которые существуют на уровне, который Вы
предоставляете. Например, GRANT ALL ON
на уровне базы данных, таким образом, это не предоставляет
специфических глобальных привилегий, например,
db_name
.*FILE
. Предоставление
ALL
не назначает
GRANT OPTION
или
PROXY
.
object_type
, если есть, должен быть определен как
TABLE
, FUNCTION
или PROCEDURE
,
когда следующий объект это таблица, сохраненная функция
или хранимая процедура.
Привилегии для базы данных, таблицы, столбца или подпрограммы сформированы
совокупно как логическое OR
из привилегий на каждом из уровней. Например, если у пользователя есть
глобальный SELECT
,
привилегия не может отрицаться отсутствием привилегии на уровне базы данных,
таблицы или столбца. Детали проверяющей привилегию процедуры представлены в
разделе 7.2.6.
Если Вы используете привилегии таблицы, столбца или подпрограммы даже для одного пользователя, сервер исследует привилегии таблицы, столбца и подпрограммы для всех пользователей, а это немного замедляет MySQL. Точно так же, если Вы ограничиваете число запросов, обновлений или соединений для каких-либо пользователей, сервер должен контролировать эти значения.
MySQL позволяет Вам предоставить привилегии на базах данных или таблицах,
которые не существуют. Для таблиц привилегии, которые будут предоставлены,
должны включать CREATE
.
Это поведение проектируется, предназначено, чтобы
позволить администратору базы данных подготовить учетные записи пользователя
и привилегии для баз данных или таблиц, которые должны быть составлены в
более позднее время.
MySQL автоматически не отменяет привилегий, когда Вы удаляете базу данных или таблицу. Однако, если Вы удаляете подпрограмму, любые привилегии, предоставленные для этой подпрограммы, отменяются.
Глобальные привилегии являются административными или относятся ко всем
базам данных по данному серверу. Чтобы назначить глобальные привилегии,
надо использовать ON *.*
:
GRANT ALL ON *.* TO 'someuser'@'somehost'; GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';
CREATE TABLESPACE
, CREATE USER
,
FILE
,
PROCESS
,
RELOAD
,
REPLICATION CLIENT
, REPLICATION
SLAVE
, SHOW
DATABASES
, SHUTDOWN
и SUPER
являются административными и могут быть предоставлены только глобально.
Другие привилегии можно предоставить глобально или на более определенных уровнях.
MySQL хранит глобальные привилегии в таблице mysql.user
.
Привилегии базы данных относятся ко всем объектам в данной базе данных.
Чтобы назначить привилегии на уровне базы данных, надо использовать
ON
:
db_name
.*
GRANT ALL ON mydb.* TO 'someuser'@'somehost'; GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';Если Вы используете
ON *
(вместо ON *.*
)
и Вы выбрали базу данных по умолчанию, привилегии назначены на уровне базы
данных для базы данных по умолчанию. Ошибка происходит, если нет никакой базы
данных по умолчанию.
CREATE
,
DROP
,
EVENT
,
GRANT OPTION
,
LOCK TABLES
и
REFERENCES
могут быть определены на уровне базы данных. Привилегии таблицы или
подпрограммы также могут быть определены на уровне базы данных, когда они
относятся ко всем таблицам или подпрограммам в базе данных.
MySQL хранит привилегии базы данных в таблице mysql.db
.
Табличные привилегии относятся ко всем столбцам в данной таблице.
Чтобы назначить привилегии на уровне таблицы, надо использовать
ON
:
db_name.tbl_name
GRANT ALL ON mydb.mytbl TO 'someuser'@'somehost'; GRANT SELECT, INSERT ON mydb.mytbl TO 'someuser'@'somehost';Если Вы определяете
tbl_name
вместо
db_name.tbl_name
, запрос относится к
tbl_name
в базе данных по умолчанию. Ошибка происходит,
если нет никакой базы данных по умолчанию.
Допустимые значения priv_type
на табличном уровне:
ALTER
,
CREATE VIEW
,
CREATE
,
DELETE
,
DROP
,
GRANT OPTION
,
INDEX
,
INSERT
,
REFERENCES
,
SELECT
,
SHOW VIEW
,
TRIGGER
и
UPDATE
.
MySQL хранит табличные привилегии в таблице
mysql.tables_priv
.
Привилегии столбца относятся к единственному столбцу в данной таблице. Каждая привилегия, которая будет предоставлена на уровне столбца, должна сопровождаться столбцом или столбцами, приложенными в круглых скобках.
GRANT SELECT (col1), INSERT (col1,col2) ON mydb.mytbl TO 'someuser'@'somehost';Допустимые значения
priv_type
для столбца (то есть, когда Вы используете
column_list
):
INSERT
,
REFERENCES
,
SELECT
и
UPDATE
.
MySQL хранит привилегии столбца в таблице mysql.columns_priv
.
ALTER ROUTINE
,
CREATE ROUTINE
,
EXECUTE
и
GRANT OPTION
относятся к сохраненным подпрограммам (процедуры и функции). Их можно
предоставить на глобальных уровнях и уровнях базы данных. За исключением
CREATE ROUTINE
,
эти привилегии можно предоставить для отдельных подпрограмм.
GRANT CREATE ROUTINE ON mydb.* TO 'someuser'@'somehost'; GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'someuser'@'somehost';Допустимые
priv_type
на уровне подпрограмм:
ALTER ROUTINE
,
EXECUTE
и
GRANT OPTION
.
CREATE ROUTINE
не привилегия на обычном уровне, потому что у Вас должна быть эта
привилегия, чтобы создать подпрограмму
MySQL хранит привилегии для подпрограмм в таблице
mysql.procs_priv
.
PROXY
позволяет одному пользователю быть полномочием для другого. Пользователь
является олицетворением или берет личность proxy-пользователя.
GRANT PROXY ON 'localuser'@'localhost' TO 'externaluser'@'somehost';Когда
PROXY
предоставлена, это должна быть единственная привилегия, названная в
GRANT
, REQUIRE
не может быть дан, и разрешен единственный параметр
WITH
: WITH GRANT OPTION
.
Это требует, чтобы пользователь по доверенности подтвердил подлинность
через плагин, который возвращает имя proxied пользователя к серверу, когда
пользователь по доверенности соединяется, и что пользователь по доверенности
имеет привилегию PROXY
. Подробности в
разделе 7.3.10.
MySQL хранит привилегии proxy в таблице mysql.proxies_priv
.
user_specification
называет пользователя и
произвольно предоставляет информацию об аутентификации, такую как пароль.
user
указывает на учетную запись MySQL, к которой
GRANT
применяется. Чтобы
приспособить предоставление прав пользователям от произвольных узлов, MySQL
поддерживает определение user
в формате
.
Если user_name
@host_name
user_name
или host_name
является законным как идентификатор, Вы не должны заключить его в кавычки.
Однако, кавычки необходимы, чтобы определить
user_name
, содержащее специальные символы (например,
-
) или если host_name
содержит специальные или подстановочные символы (например, %
).
Заключите в кавычки имя пользователя и имя хоста отдельно.
Вы можете определить подстановочные знаки в имени хоста. Например,
относится к user_name
@'%.example.com'user_name
для любого узла в домене
example.com
, а
относится к user_name
@'192.168.1.%'
user_name
для любого узла в
подсети 192.168.1
класса C.
Простая форма user_name
это синоним для
.user_name
@'%'
MySQL не поддерживает подстановочные знаки в именах
пользователей. Чтобы обратиться к анонимному пользователю,
определите учетную запись с пустым именем пользователя с помощью
GRANT
:
GRANT ALL ON test.* TO ''@'localhost' ...;В этом случае, любому пользователю, который соединяется от местного узла с правильным паролем для анонимного пользователя, разрешат доступ с привилегиями, связанными с анонимной учетной записью пользователя.
См. раздел 7.2.3.
Чтобы определить заключенные в кавычки значения, заключите в кавычки базу данных, таблицу или столбец как идентификаторы. Имена пользователя и хоста берутся в кавычки как идентификаторы или как строки. Пароли берутся в кавычки как строки. Для заключения в кавычки строк и идентификаторов см. разделы 10.1.1 и 10.2.
_
и %
разрешены, определяя имена базы данных в
GRANT
, которые предоставляют
привилегии на уровне базы данных. Это означает, например, что, если Вы хотите
использовать _
как часть имени базы данных, Вы должны определить
это как \_
в GRANT
,
чтобы предотвратить возможность доступа к дополнительным базам данных,
соответствующих подстановочному образцу, например, GRANT ... ON
`foo\_bar`.* TO ...
.
Если Вы разрешаете анонимным пользователям соединяться с сервером MySQL,
Вы должны также предоставить привилегии всем местным пользователям как
.
Иначе анонимная учетная запись пользователя для user_name
@localhostlocalhost
в
таблице mysql.user
(создаваемая во время установки MySQL)
используется, когда названный пользователь пытается войти в систему MySQL
с местной машины. Для деталей см.
раздел 7.2.5.
Чтобы определить, относится ли предыдущее предупреждение к Вам, выполните следующий запрос, который перечисляет любых анонимных пользователей:
SELECT Host, User FROM mysql.user WHERE User='';Чтобы избежать этой проблемы, удалите местную анонимную учетную запись пользователя, используя этот запрос:
DROP USER ''@'localhost';
Чтобы указать, как пользователь должен подтвердить подлинность, соединяясь
с сервером, значение user_specification
может включать
IDENTIFIED
, чтобы определить плагин аутентификации, пароль или
обоих. Синтаксис пользовательской спецификации тот же самый, что в
CREATE USER
. См.
раздел 14.7.1.3.
Если задан IDENTIFIED BY
и у Вас есть глобальная привилегия
(GRANT OPTION
),
пароль становится новым паролем для учетной записи, даже если учетная запись
существует и уже имеет пароль. Без IDENTIFIED BY
пароль учетной записи остается неизменным.
Если учетную запись называют в GRANT
, но она не существует, предпринятые меры зависят от значения режима SQL
NO_AUTO_CREATE_USER
:
Если
NO_AUTO_CREATE_USER
выключен, GRANT
создает учетную запись. Это очень опасно,
если Вы не определяете непустой пароль через IDENTIFIED BY
.
NO_AUTO_CREATE_USER
, GRANT
не создает учетную запись, если Вы не определяете непустой пароль
через IDENTIFIED BY
или плагин аутентификации
через IDENTIFIED WITH
.Если учетная запись уже существует, IDENTIFIED WITH
запрещен, потому что это предназначено только для использования, создавая
новые учетные записи.
MySQL может проверить признаки сертификата X509 в дополнение к обычной аутентификации, которая основана на имени пользователя. Для вводной информации об использовании SSL с MySQL см. раздел 7.4.
REQUIRE
определяет опции SSL для учетной записи MySQL.
Синтаксис тот же самый, что и в CREATE
USER
, см. раздел 14.7.1.3.
WITH
используется в этих целях:
Позволять пользователю предоставить привилегии другим пользователям.
WITH GRANT OPTION
дает пользователю способность дать другим
пользователям любые привилегии, которые пользователь имеет на
указанном уровне привилегии.
Чтобы предоставить GRANT
OPTION
учетной записи, иначе не изменяя ее
привилегии, сделайте это:
GRANT USAGE ON *.* TO 'someuser'@'somehost' WITH GRANT OPTION;Два пользователя с различными привилегиями могут быть в состоянии объединить привилегии!
Вы не можете предоставить другому пользователю привилегию, которую сами
не имеете, GRANT OPTION
позволяет Вам назначить только те привилегии, которыми
Вы обладаете сами.
Знайте что, когда Вы предоставляете пользователю
GRANT OPTION
на особом уровне привилегии, любые привилегии, которыми пользователь обладает
(или может получить в будущем) на этом уровне, могут быть предоставлены им
другим пользователям. Предположите, что Вы предоставляете пользователю
привилегию INSERT
на базе данных. Если Вы потом предоставляете привилегию
SELECT
на базе данных
м указываете WITH GRANT OPTION
,
тот пользователь может дать другим пользователям не только
SELECT
, но и
INSERT
.
Если Вы позже предоставляете UPDATE
на базе данных, пользователь может предоставить
INSERT
,
SELECT
и
UPDATE
.
Для неадминистративного пользователя Вы не должны предоставить
ALTER
глобально или для базы данных mysql
. Если Вы делаете это,
пользователь может попытаться ниспровергать систему
привилегий, переименовывая таблицы!
См. раздел 7.2.1.
Возможно установить границы использования ресурсов сервера учетной
записью, как обсуждено в разделе
7.3.5. Используйте WITH
с параметром
resource_option
. Не определенные пределы сохраняют свое
текущее значение. Синтаксис тот же самый, что в
CREATE USER
, см.
раздел 14.7.1.3.
Самые большие различия между MySQL и стандартными версиями SQL
GRANT
:
MySQL связывает привилегии с комбинацией имени хоста и имени пользователя а не только с именем пользователя.
UNDER
.DROP USER
, см.
раздел 14.7.1.5.DROP USER
или
REVOKE
.INSERT
только для некоторых столбцов в таблице. В этом случае Вы можете
все еще выполнить INSERT
на
таблице, при условии, что Вы вставляете значения только для тех столбцов, для
которых Вы имеете привилегию INSERT
. Опущенные столбцы установлены в их неявные значения по
умолчанию, если строгий режим SQL не включен. В строгом режиме запрос
отклонен, если у какого-либо из опущенных столбцов нет никакого значения по
умолчанию. Стандартный SQL требует, чтобы Вы имели привилегию
INSERT
на всех столбцах. Для информации о строгом режиме SQL и неявных значениях по
умолчанию см. разделы 6.1.8 и
12.7.RENAME USERold_user
TOnew_user
[,old_user
TOnew_user
] ...
RENAME USER
переименовывает существующие учетные записи MySQL. Ошибка происходит для
старых учетных записей, которые не существуют, или новых учетных записей,
которые уже существуют.
Чтобы использовать RENAME USER
, у Вас должна быть глобальная привилегия
CREATE USER
или
привилегия UPDATE
для
базы данных mysql
. Если включена
read_only
,
RENAME USER
требует привилегии
SUPER
.
Каждое имя учетной записи использует формат, описанный в разделе 7.2.3:
RENAME USER 'jeffrey'@'localhost' TO 'jeff'@'127.0.0.1';Если Вы определяете только часть имени пользователя имени учетной записи, используется часть имени хоста
'%'
.
RENAME USER
копирует
привилегии старого пользователя новому. Однако,
RENAME USER
автоматически не удаляет базы данных или объекты, которые создал старый
пользователь. Это включает сохраненные программы или представления, для
которых DEFINER
это старый пользователь.
Попытки получить доступ к таким объектам могут произвести ошибку, если
они выполняют в контексте безопасности определителя (см.
раздел 21.6).
Изменения привилегий вступают в силу как обозначено в разделе 7.2.7.
REVOKEpriv_type
[(column_list
)] [,priv_type
[(column_list
)]] ... ON [object_type
]priv_level
FROMuser
[,user
] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROMuser
[,user
] ... REVOKE PROXY ONuser
FROMuser
[,user
] ... REVOKErole
[,role
] ... FROMuser
[,user
] ...
REVOKE
позволяет системным
администраторам отменить привилегии и роли, которые он
может отменить от учетных записей пользователя и ролей.
При включенной переменной
read_only
REVOKE
требует привилегии SUPER
.
Каждое имя учетной записи использует формат, описанный в разделе 7.2.3:
REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost';Если Вы определяете только часть имени пользователя имени учетной записи, часть имени хоста
'%'
.
Для деталей об уровнях, на которых привилегии существуют, допустимых
значениях priv_type
,
priv_level
и object_type
см. раздел 14.7.1.6.
Чтобы использовать первый вариант
REVOKE
, Вы должны иметь привилегию
GRANT OPTION
, и у
Вас должны быть привилегии, которые Вы отменяете.
Чтобы отменить все привилегии, используйте второй синтаксис, который удаляет все привилегии глобальные, базы данных, таблицы и столбца для названного пользователя или пользователей: named user or users:
REVOKE ALL PRIVILEGES, GRANT OPTION FROMЧтобы использовать этот вариантuser
[,user
] ...
REVOKE
, у Вас должна быть глобальная привилегия
CREATE USER
или привилегия UPDATE
на базе данных mysql
.
REVOKE ALL PRIVILEGES, GRANT OPTION FROM
не отменяет ролей.user
REVOKE
удаляет привилегии, но не удаляет записи таблицы mysql.user
.
Чтобы удалить учетную запись пользователя полностью, надо использовать
DROP USER
(см.
раздел 14.7.1.5) или
DELETE
.
Если таблицы содержат строки привилегии, которые содержат имена базы
данных или имена таблиц в смешанном регистре и
lower_case_table_names
не 0,
REVOKE
не может использоваться, чтобы отменить эти привилегии. Будет необходимо
управлять таблицами непосредственно.
GRANT
не будет создавать такие строки, когда
lower_case_table_names
установлена, но такие строки, возможно,
были созданы до установки переменной.
Когда успешно выполнено из
mysql, REVOKE
отвечает Query OK, 0 rows affected
. Чтобы определить результат
команды, используйте SHOW GRANTS
. См. раздел 14.7.5.21.
REVOKE ROLE {Это раздел образца.auth_id
[,auth_id
] ... | ALL ROLES } FROMauth_id
[,auth_id
] ...auth_id
:user_name
[@host_name
]
SET DEFAULT ROLE {NONE | ALL |Этот запрос альтернативный синтаксис дляrole
[,role
] ...} TOrole
[,role
] ...
ALTER USER ... DEFAULT ROLE
(см. раздел 14.7.1.1).
Это определяет, какие роли становятся активными, когда
SET ROLE DEFAULT
выполнен во время сеанса для каждой role
немедленно после TO
.
DEFAULT ROLE
может иметь эти значения:
NONE
: Роль по умолчанию NONE
.
ALL
: Значение по умолчанию: все роли,
предоставленные учетной записи.role
[,
role
] ...
: Значение по умолчанию:
все названные роли.SET PASSWORD [FORuser
] =password_option
password_option
: { PASSWORD('auth_string
') | 'auth_string
' }
SET PASSWORD
назначает пароль на учетную запись пользователя MySQL, определенный как
открытый текст (не зашифрован) или как зашифрованное значение:
'
представляет пароль открытого текста.auth_string
'
'hash_string
'
представляет зашифрованный пароль.SET PASSWORD ... =
PASSWORD('
устарел в
MySQL 5.7.6 и будет удален в будущем выпуске MySQL.auth_string
')
SET PASSWORD
... = 'auth_string
'
не устарел, но
ALTER USER
теперь привилегированное запрос для того, чтобы назначить пароли. Например:
ALTER USERuser
IDENTIFIED BY 'auth_string
';
SET PASSWORD
может
использоваться с или без явно названной учетной записи пользователя:
С FOR
запрос устанавливает пароль для названной учетной записи,
которая должна существовать:
user
SET PASSWORD FOR 'jeffrey'@'localhost' = password_option
;
В этом случае Вы должны иметь привилегию
UPDATE
на базе данных mysql
.FOR user
запрос устанавливает пароль для текущего пользователя:
SET PASSWORD = password_option
;
Любой клиент, который соединяется с сервером, используя неанонимную учетную
запись, может изменить пароль для той учетной записи. Чтобы видеть, какая
учетная запись подтверждала Вашу подлинность, вызовите функцию
CURRENT_USER()
:
SELECT CURRENT_USER();
При включенной опции read_only
SET PASSWORD
требует привилегию SUPER
.
Если FOR
дан, имя учетной записи использует формат, описанный в
разделе 7.2.3.
user
user
должно быть дано как
'
, где user_name
'@'host_name
'
'
и
user_name
''
точно как перечислены в столбцах host_name
'User
и Host
строки таблицы mysql.user
.
Если Вы определяете только имя пользователя, имя хоста '%'
.
Например, чтобы установить пароль для учетной записи с
User
и Host
соответственно 'bob'
и
'%.example.org'
:
SET PASSWORD FOR 'bob'@'%.example.org' = PASSWORD('auth_string
');
Пароль может быть определен этими способами:
Используя функцию
PASSWORD()
(устарел с MySQL 5.7.6).
Функциональный параметр '
открытый текст (незашифрованный) пароль.
auth_string
'PASSWORD()
хеширует пароль и возвращает зашифрованную строку пароля для хранения в
строке mysql.user
.
Функция PASSWORD()
хеширует пароль, используя хеширующий метод, определенный значением
old_passwords
.
Если SET PASSWORD
отклоняет хешированное значение пароля, возвращенное
PASSWORD()
как не заданное в правильном формате, может быть необходимо изменить
old_passwords
,
чтобы изменить хеширующий метод. Например, если учетная запись использует
плагин mysql_native_password
, значение
old_passwords
должно быть равно 0:
SET old_passwords = 0; SET PASSWORD FOR 'jeffrey'@'localhost' = PASSWORD('mypass');Если
old_passwords
отличается от требуемого плагином аутентификации, хешированное значение
пароля, возвращенное PASSWORD()
не является приемлемым для этого плагина, и попытка установить
пароль, производит ошибку. Разрешенные значения
old_passwords
описаны позже в этом разделе.PASSWORD()
.
SET PASSWORD
интерпретирует строку как строку открытого текста и хеширует это
соответственно для плагина аутентификации учетной записи прежде, чем
сохранить это в строке таблицы mysql.user
.
См. раздел 7.3.6.
Следующая таблица показывает разрешенные значения
old_passwords
,
метод хеширования пароля для каждого значения, и какие плагины аутентификации
используют пароли, хешированные с каждым методом.
Значение | Метод хеширования пароля | Связанный плагин аутентификации |
---|---|---|
0 | MySQL 4.1 native | mysql_native_password |
2 | SHA-256 | sha256_password |
Если Вы используете MySQL Replication, в настоящее время,
пароль, используемый ведомым устройством в качестве части
CHANGE MASTER TO
ограничен 32 символами в длину, если пароль больше, любые лишние символы
усечены. Это не происходит ни из-за какого предела, наложенного сервером
MySQL вообще, а скорее является проблемой, определенной для MySQL
Replication (см. Bug #43439).
SET ROLE { DEFAULT | NONE | ALL | ALL EXCEPTrole
[,role
] ... |role
[,role
] ... }
SET ROLE
изменяет эффективные
привилегии текущего пользователя. Запрос разрешает эти ролевые спецификаторы:
DEFAULT
:
Установить текущую роль в роль по умолчанию для пользователя.
NONE
: Установить текущую роль в NONE
.ALL
: Установить текущую роль во все роли,
предоставленные учетной записи.ALL EXCEPT role_list
:
Установить текущую роль во все роли, предоставленные учетной
записи, кроме названных.role
[,
role
] ...
:
Установить текущую роль в названные роли.ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLEtbl_name
[,tbl_name
] ...
ANALYZE TABLE
анализирует и хранит ключевое распределение для
таблицы. Во время анализа таблица заблокирована с блокировкой чтения для
InnoDB
и MyISAM
. Этот запрос работает с
InnoDB
, NDB
и MyISAM
. Для
MyISAM
этот запрос эквивалентен использованию
myisamchk --analyze
. Этот запрос не работает с представлениями.
Для получения дополнительной информации о том, как анализ работает в
пределах InnoDB
см. разделы
16.6.10.1,
16.6.10.3 и
16.8.7. В частности, когда Вы
включаете опцию
innodb_stats_persistent
, Вы должны выполнить
ANALYZE TABLE
после загрузки существенных данных в
InnoDB
или создания нового индекса.
MySQL использует сохраненное ключевое распределение, чтобы понять порядок, в котором нужно присоединиться к таблицам, когда Вы выполняете соединение на чем-то другом, чем константа. Кроме того, ключевые распределения могут использоваться, решая, который индекс использовать для определенной таблицы в пределах запроса.
Это запрос требует привилегии
SELECT
и
INSERT
на таблице.
ANALYZE TABLE
поддержан для разделенных таблиц, и Вы можете
использовать ALTER TABLE ... ANALYZE PARTITION
, чтобы
проанализировать один или более раздела, для получения дополнительной
информации см. разделы 14.1.7 и
20.3.4.
ANALYZE TABLE
возвращает набор результатов
со следующими столбцами.
Столбец | Значение |
---|---|
Table | Имя таблицы |
Op | Всегда analyze |
Msg_type | status ,
error , info , note или
warning |
Msg_text |
Соответствующее информационное сообщение |
Вы можете проверить сохраненное ключевое распределение с
SHOW INDEX
, см.
раздел 14.7.5.22.
Если таблица не изменилась, начиная с последнего ANALYZE
TABLE
, она не проанализирована снова.
По умолчанию сервер пишет ANALYZE
TABLE
в двоичный журнал, чтобы они копировались к ведомым
устройствам репликации. Чтобы подавить журналирование, определите
дополнительное ключевое слово NO_WRITE_TO_BINLOG
или его псевдоним LOCAL
.
CHECK TABLEtbl_name
[,tbl_name
] ... [option
] ...option
= { FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED }
CHECK TABLE
проверяет таблицу или таблицы на ошибки.
CHECK TABLE
работает для
таблиц InnoDB
,
MyISAM
,
ARCHIVE
и
CSV
. Для
MyISAM
ключевые статистические данные обновлены также.
Перед выполнением CHECK TABLE
на InnoDB
см. здесь
.
Чтобы проверить таблицу, у Вас должна быть некоторая привилегия для этого.
CHECK TABLE
может также проверить представления на проблемы,
такие как таблицы, на которые ссылаются в определении представления, которые
больше не существуют.
CHECK TABLE
поддержан для разделенных таблиц, и Вы можете
использовать ALTER TABLE ... CHECK PARTITION
, чтобы
проверять один или более разделов, для получения дополнительной информации
см. разделы 14.1.7 и
20.3.4.
CHECK TABLE
игнорирует произведенные виртуальные столбцы,
которые не индексированы.
CHECK TABLE
возвращает набор результатов
со следующими столбцами.
Столбец | Значение |
---|---|
Table | Имя таблицы |
Op | Всегда check |
Msg_type | status ,
error , info , note или
warning |
Msg_text | Соответствующее информационное сообщение |
Запрос может произвести много строк информации для каждой проверенной
таблицы. У последней строки есть Msg_type
status
и
Msg_text
обычно должен быть OK
. Если это не
OK
или Table is already up to date
для
MyISAM
, Вы должны обычно выполнять ремонт таблицы. См.
раздел 8.6. Table is
already up to date
сообщает, что механизм хранения для таблицы указал,
что не было никакой потребности проверить таблицу.
FOR UPGRADE
проверяет, совместимы ли названные таблицы с
текущей версией MySQL. С FOR UPGRADE
сервер проверяет каждую
таблицу, чтобы определить, были ли какие-либо несовместимые изменения в
каком-либо из типов данных таблицы или индексе после того, как таблица была
составлена. Если есть возможная несовместимость, сервер осуществляет полную
проверку таблицы (которая может занять время).
Несовместимости могли бы произойти, потому что формат хранения для типа данных изменился или потому что его порядок сортировки изменился. Наша цель состоит в том, чтобы избежать этих изменений, но иногда они необходимы, чтобы исправить проблемы, которые были бы хуже чем несовместимость между выпусками.
FOR UPGRADE
обнаруживает эти несовместимости:
Порядок индексации в столбцах
TEXT
для
InnoDB
и MyISAM
изменился между MySQL 4.1 и 5.0.
DECIMAL
изменился между MySQL 5.0.3 и 5.0.5.FOR UPGRADE
их найдет, см.
раздел 2.10.3.
YEAR(2)
, разрешенный в более старых версиях MySQL. Для таблиц,
содержащих столбцы YEAR(2)
,
CHECK TABLE
рекомендует
REPAIR TABLE
, который
конвертирует YEAR(2)
в
YEAR(4)
.Следующая таблица показывает другие варианты проверки, которые могут быть даны. Эти опции передают к механизму хранения, который может использовать их или нет.
Тип | Смысл |
---|---|
QUICK | Не просматривать
строки, чтобы проверить на неправильные ссылки. Относится к таблицам
InnoDB и MyISAM и представлениям. |
FAST | Проверить только таблицы,
которые не были закрыты должным образом. Применяется только к
MyISAM таблицам и представлениям, проигнорирован для
InnoDB . |
CHANGED | Проверка только таблиц,
которые были изменены, начиная с последней проверки или не были закрыты
должным образом. Применяется только к MyISAM таблицам и
представлениям, проигнорирован для InnoDB . |
MEDIUM | Сканировать строки, чтобы
проверить, которые удаленные ссылки допустимы. Это также вычисляет ключевую
контрольную сумму для строк и проверяет это с расчетной контрольной суммой
для ключей. Применяется только к MyISAM , проигнорирован для
InnoDB . |
EXTENDED | Сделать полный ключевой
поиск для всех ключей для каждой строки. Это гарантирует, что таблица на 100%
последовательна, но занимает много времени. Применяется только к
MyISAM , проигнорирован для InnoDB .
|
Если ни одна из опций QUICK
,
MEDIUM
или EXTENDED
не определены, тип проверки
по умолчанию для динамического формата MyISAM
MEDIUM
. У этого есть тот же самый результат, как у
myisamchk
--medium-check tbl_name
.
Тип проверки по умолчанию также MEDIUM
для статического формата
MyISAM
, если CHANGED
или FAST
заданы.
В этом случае значение по умолчанию QUICK
. Просмотр строки
пропущен для CHANGED
и FAST
, так как
строки очень редко повреждаются.
Вы можете объединить опции проверки, как в следующем примере, который делает быструю проверку на таблице, чтобы определить, было ли это закрыто должным образом:
CHECK TABLE test_table FAST QUICK;
Если CHECK TABLE
не находит проблем с таблицей, которая отмечена как
corrupted или not closed properly
, CHECK TABLE
может удалить метку.
Если таблица повреждена, проблема наиболее вероятна в индексировании, а не в части данных. Все предыдущие типы проверки проверяют индексирование полностью и должны таким образом найти большинство ошибок.
Если Вы только хотите проверить таблицу, которую Вы считаете нормальной,
Вы не должны использовать опции проверки или QUICK
.
Последняя должна использоваться, когда Вы спешите и можете взять на себя
очень маленький риск, что QUICK
не находит ошибку в файле с
данными. В большинстве случаев при нормальном использовании MySQL должен
найти любую ошибку в файле с данными. Если это происходит, таблица отмечена
как corrupted и не может использоваться, пока
она не восстановлена.
FAST
и CHANGED
главным образом предназначены,
чтобы использоваться из скрипта (например, из cron
), если Вы хотите проверить таблицы время от времени. В большинстве
случаев FAST
должен быть предпочтен CHANGED
.
Единственный случай, когда это не так, это когда Вы подозреваете, что нашли
ошибку в коде MyISAM
.
EXTENDED
должен использоваться только после того, как Вы
осуществили нормальную проверку, но все еще получаете странные ошибки от
таблицы, когда MySQL пытается обновить строку или найти строку ключом.
Это очень маловероятно, если нормальная проверка преуспела.
Использование CHECK TABLE
... EXTENDED
может влиять на план
выполнения, произведенный оптимизатором.
Некоторые проблемы, сообщенные CHECK
TABLE
не могут быть исправлены автоматически:
Found row where the auto_increment column has the value 0
.
Это означает, что есть строка в таблице, где столбец
AUTO_INCREMENT
содержит значение 0. Возможно создать строку, где
AUTO_INCREMENT
= 0, явно устанавливая столбец в 0 с помощью
UPDATE
.
Это не ошибка само по себе, но может доставить неприятности, если Вы
решаете вывести таблицу в дамп и восстановить ее или сделать
ALTER TABLE
. В этом случае
AUTO_INCREMENT
изменяет значение согласно правилам
AUTO_INCREMENT
, которые могли вызвать проблемы, такие как
ошибка дублирования ключа.
Чтобы избавиться от предупреждения, выполните
UPDATE
, чтобы установить
столбец в некоторое значение кроме 0.
Следующие примечания относятся к таблицам
InnoDB
:
Если CHECK TABLE
сталкивается с поврежденной страницей, сервер останавливается, чтобы
предотвратить распространение ошибки (Bug #10132). Если повреждение
происходит во вторичном индексе, но табличные данные читаемы, запуск
CHECK TABLE
может все еще вызвать выход сервера.
CHECK TABLE
сталкивается с поврежденным полем DB_TRX_ID
или
DB_ROLL_PTR
в кластеризируемом индексе,
CHECK TABLE
может вызвать доступ InnoDB
к недопустимой записи журнала
отмены, приводящей к сбою сервера, связанному с
MVCC.CHECK TABLE
находит ошибки в таблицах или индексах InnoDB
,
это сообщает об ошибке и обычно отмечает индекс и иногда таблицу как
поврежденные, предотвращая дальнейшее использование индекса или таблицы.
Такие ошибки включают неправильное число записей во вторичном индексе
или неправильные ссылки.CHECK TABLE
находит неправильное число записей во вторичном индексе, он сообщает об
ошибке, но не вызывает выход сервера или запрет доступа к файлу.CHECK TABLE
рассматривает структуру индексной страницы, затем рассматривает каждую
запись ключа. Это не проверяет ключевой указатель на кластеризируемую запись
или следует по пути для указателей на
BLOB
.InnoDB
сохранена в ее собственном
файле .ibd, первые 3
страницы файла .ibd
содержит информацию о заголовке, а не таблицу или данные индекса. CHECK
TABLE
не обнаруживает несогласованности, которые затрагивают только
данные о заголовке. Чтобы проверить все содержание файла .ibd
,
использщуйте innochecksum
.CHECK TABLE
на больших таблицах
InnoDB
, другие потоки могут быть заблокированы во время
CHECK TABLE
. Чтобы избежать тайм-аутов, порог ожидания (600
секунд) расширен на 2 часа (7200 секунд) для CHECK TABLE
. Если
InnoDB
обнаруживает семафор, который ждет 240 секунд или больше,
он начинает выводить монитор InnoDB
в журнал ошибок.
Если запрос блокировки простирается вне порога ожидания семафора,
прерывает процесс. Чтобы избежать возможности семафора ждать тайм-аут
полностью, Вы можете выполнить CHECK TABLE QUICK
вместо CHECK TABLE
.CHECK TABLE
функциональность для
InnoDB
индексов SPATIAL
включает проверку достоверности R-дерева и проверку, чтобы гарантировать,
что количество строк R-дерева соответствует кластеризируемому индексу.CHECK TABLE
поддерживает вторичные индексы
на произведенных виртуальных столбцах. InnoDB
имеет поддержку вторичного индекса на произведенных виртуальных столбцах.
CHECKSUM TABLEtbl_name
[,tbl_name
] ... [ QUICK | EXTENDED ]
CHECKSUM TABLE
сообщает контрольную сумму
для содержания таблицы. Во время работы контрольной суммы таблица
заблокирована с блокировкой чтения для InnoDB
и
MyISAM
. Вы можете использовать этот запрос, чтобы проверить, что
содержание то же самое прежде и после резервного копирования, отката или
другой работы, которая предназначена, чтобы привести данные в известный
статус. Это запрос требует привилегии
SELECT
для таблицы.
Этот запрос не поддержано для представлений. Если Вы выполняете
CHECKSUM TABLE
на представлении, значение
Checksum
всегда NULL
и будет предупреждение.
По умолчанию, вся таблица читается построчно, и контрольная сумма
вычислена. Для больших таблиц это может занять много времени, таким образом,
Вы будете только иногда выполнять эту работу. Это вычисление аналогично тому,
что Вы получаете с EXTENDED
в InnoDB
и всех других механизмах хранения, кроме MyISAM
, а также
таблицах MyISAM
, не созданных с CHECKSUM=1
.
Для таблиц MyISAM
, созданных с
CHECKSUM=1
, CHECKSUM TABLE
или
CHECKSUM TABLE ... QUICK
вернет
текущую контрольную сумму таблицы,
которая может быть возвращена очень быстро. Если таблица не удовлетворяет
всем этим условиям, QUICK
возвращает NULL
. См.
раздел 14.1.15.
Для несуществующей таблицы CHECKSUM
TABLE
вернет NULL
и предупреждение.
Значение контрольной суммы зависит от формата строки таблицы. Если формат
строки изменяется, контрольная сумма также изменяется. Например, формат
хранения для таких временных типов, как
TIME
,
DATETIME
и
TIMESTAMP
изменен в MySQL 5.6,
так что при обновлении таблиц с 5.5 до 5.6 значение контрольной
суммы может измениться.
Если контрольные суммы для двух таблиц отличаются, то почти бесспорно, что
таблицы отличаются в некотором роде. Однако, потому что хеширующая функция,
используемая CHECKSUM TABLE
, не гарантирована от столкновения, есть небольшой шанс, что две таблицы,
которые не идентичны, могут произвести ту же самую контрольную сумму.
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLEРеорганизует физическое хранение табличных данных и связанных индексных данных, чтобы уменьшить место для хранения и улучшить эффективность ввода/вывода, получая доступ к таблице. Точные изменения, произведенные в каждой таблице, зависят от механизма хранения, используемого этой таблицей. Этот запрос не работает с представлениями.tbl_name
[,tbl_name
] ...
Используйте OPTIMIZE TABLE
в этих случаях, в зависимости от типа таблицы:
После выполнения существенной вставки, обновления или удаления
на InnoDB
, у которой есть ее собственный
файл .ibd, потому что она
создавалась с опцией
innodb_file_per_table
. Таблица и индекс реорганизованы, и дисковое
пространство может быть освобождено для использования операционной системой.
FULLTEXT
в
InnoDB
. Установите опцию
innodb_optimize_fulltext_only=1
.
Чтобы сохранить период обслуживания индекса к соответствующему времени,
установите
innodb_ft_num_word_optimize
, чтобы определить, сколько слов
обновить в поисковом индексе, и выполняйте последовательность OPTIMIZE
TABLE
до полного обновления поискового индекса.MyISAM
или
ARCHIVE
или внесения значительных изменений в таблицы
MyISAM
или ARCHIVE
со строками переменной длины
(таблицы, которые имеют столбцы
VARCHAR
,
VARBINARY
,
BLOB
или
TEXT
).
Удаленные строки поддержаны в связанном списке и последующие
INSERT
повторно используют старые позиции строки. Вы можете использовать
OPTIMIZE TABLE
, чтобы
восстановить неиспользуемое место и для дефрагментации файла с данными. После
обширных изменений таблицы этот запрос может также улучшить исполнение
запросов, которые используют таблицу, иногда значительно.Этот запрос требует табличных привилегий
SELECT
и
INSERT
.
OPTIMIZE TABLE
также поддержан для разделенных таблиц. Для информации об использовании этого
запроса с разделенными таблицами см.
раздел 20.3.4.
OPTIMIZE TABLE
работает с таблицами InnoDB
,
MyISAM
и
ARCHIVE
.
По умолчанию OPTIMIZE TABLE
не работает для других механизмов хранения
и возвращает результат, указывающий на это. Вы можете сделать, чтобы
OPTIMIZE TABLE
работал
для других механизмов хранения, запуская
mysqld с
опцией --skip-new
. В этом случае
OPTIMIZE TABLE
отображен на
ALTER TABLE
.
Для InnoDB
OPTIMIZE
TABLE
отображен на
ALTER TABLE ... FORCE
,
который пересоздает таблицу, чтобы обновить индексную статистику и свободное
неиспользуемое место в кластеризируемом индексе. Это выведено на экран в
выводе OPTIMIZE TABLE
,
когда Вы выполняете это на InnoDB
:
mysql> OPTIMIZE TABLE foo; +----------+----------+----------+-------------------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +----------+----------+----------+-------------------------------------------------------------------+ | test.foo | optimize | note | Table does not support optimize, doing recreate + analyze instead | | test.foo | optimize | status | OK | +----------+----------+----------+-------------------------------------------------------------------+
OPTIMIZE TABLE
использует online DDL
(ALGORITHM=INPLACE
) для таблиц InnoDB
. Это
блокирует таблицу только на краткое время, что уменьшает время простоя для
параллельных операций DML.
OPTIMIZE TABLE
продолжает использовать ALGORITHM=COPY
при следующих условиях:
Когда
old_alter_table
в состоянии ON.
--skip-new
.OPTIMIZE TABLE
,
используя online DDL
(ALGORITHM=INPLACE
), не поддержан для таблиц
InnoDB
с индексами FULLTEXT
.
Тут нужен ALGORITHM=COPY
.
InnoDB
хранит данные, используя метод распределения
страницы и не страдают от фрагментации, как MyISAM
.
Оптимизатор рассматривает рабочую нагрузку транзакций, которые
обработает Ваш сервер:
Некоторый уровень фрагментации ожидается. InnoDB
заполняет страницы только на 93%, чтобы
оставить место для обновлений, не имея необходимости разделять страницы.
InnoDB
сохраняет многократные версии тех же самых данных через его механизм
MVCC, см.
раздел 16.3.
Для таблиц MyISAM
OPTIMIZE TABLE
работает так:
Если таблица удалила или разделила строки, восстановит таблицу.
OPTIMIZE TABLE
возвращает набор результатов со следующими столбцами.
Столбец | Значение |
---|---|
Таблица | Имя таблицы |
Op | Всегда optimize |
Msg_type | status ,
error , info , note или
warning |
Msg_text | Соответствующее информационное сообщение |
Для таблиц InnoDB
до 5.7.4 и других табличных типов MySQL
блокирует таблицу
в течение времени работы OPTIMIZE
TABLE
. OPTIMIZE TABLE
выполнен онлайн для обычных и
разделенных таблиц InnoDB
.
По умолчанию сервер пишет OPTIMIZE
TABLE
в двоичный журнал так, чтобы они копировались к ведомым
устройствам. Чтобы подавить журналирование, определите дополнительный
параметр NO_WRITE_TO_BINLOG
или LOCAL
.
OPTIMIZE TABLE
не сортирует R-дерево индекса, такое как пространственный индекс на
столбцах POINT
(Bug #23578).
OPTIMIZE TABLE
ловит и бросает любые ошибки, которые происходят, копируя табличную
статистику от старого файла в недавно созданный. Например. если
пользовательский ID владельца файла .MYD
или .MYI
отличается от пользовательского ID процесса
mysqld,
OPTIMIZE TABLE
производит ошибку "cannot change ownership of the file", если
mysqld
не запущен от имени root
.
REPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLEtbl_name
[,tbl_name
] ... [QUICK] [EXTENDED] [USE_FRM]
REPAIR TABLE
восстанавливает возможно поврежденную таблицу, для определенных механизмов
хранения. По умолчанию это имеет тот же самый эффект, как
myisamchk --recover
tbl_name
.
REPAIR TABLE
работает для
таблиц MyISAM
, ARCHIVE
и CSV
, см.
разделы 17.2
17.5 и
17.4.
Этот запрос не работает с представлениями.
Нужны привилегии SELECT
и INSERT
на уровне таблицы.
Вы можете использовать ALTER TABLE ... REPAIR PARTITION
,
чтобы восстановить один или более разделов, см. разделы
14.1.7 и
20.3.4.
Хотя обычно Вам никогда не придется выполнять
REPAIR TABLE
,
этот запрос, очень вероятно, возвратит все Ваши данные из таблицы
MyISAM
. Если Ваши таблицы становятся поврежденными часто,
попытайтесь найти причину этого, чтобы избавиться от необходимости
использовать REPAIR TABLE
.
См. разделы B.5.3.3 и
17.2.4.
Сделайте резервное копирование таблицы прежде, чем выполнить работу по ремонту таблицы: при некоторых обстоятельствах эта работа может вызвать потерю данных. Возможные причины включают, но не ограничены ошибками файловой системы. См. главу 8.
Если сервер отказывает во время
REPAIR TABLE
, важно после перезапуска немедленно выполнить
REPAIR TABLE
для таблицы прежде, чем выполнить любые другие операции на ней. В худшем
случае у Вас мог бы быть новый чистый индексный файл без информации о файле с
данными, и затем следующая работа, которую Вы выполняете, могла перезаписать
файл с данными. Это маловероятный, но возможный сценарий, который
подчеркивает значение создания резервной копии сначала.
REPAIR TABLE
возвращает набор результатов со следующими столбцами.
Столбец | Значение |
---|---|
Table | Имя таблицы |
Op | Всегда repair |
Msg_type | status ,
error , info , note или
warning |
Msg_text | Соответствующее информационное сообщение |
REPAIR TABLE
может произвести много строк информации для каждой восстановленной таблицы.
У последней строки есть Msg_type
= status
и
Msg_test
обычно должен быть OK
. Если это не
OK
для таблицы MyISAM
, Вы должны попытаться
восстановить ее с myisamchk
--safe-recover.
REPAIR TABLE
не осуществляет все опции
myisamchk.
С myisamchk
--safe-recover Вы можете также использовать опции,
которые не поддерживает REPAIR TABLE
, например,
--max-record-length
.
Если Вы используете опцию QUICK
,
REPAIR TABLE
попытается восстановить только индексный файл, а не файл с данными. Этот тип
ремонта походит на myisamchk
--recover --quick.
Если Вы используете опцию EXTENDED
, MySQL
создает индекс строку за строкой вместо того, чтобы создать индекс за один
раз с сортировкой. Этот тип ремонта походит на
myisamchk --safe-recover
.
Опция USE_FRM
доступна для использования, если
индексный файл .MYI
отсутствует или если его заголовок
поврежден. Эта опция говорит MySQL не доверять информации из заголовка файла
.MYI
и обновлять это, используя информацию из словаря данных.
Этот вид ремонта не может быть сделан с
myisamchk.
Используйте USE_FRM
только, если
Вы не можете использовать обычные режимы REPAIR
.
Сообщение серверу проигнорировать файл .MYI
делает важные табличные метаданные, сохраненные в .MYI
,
недоступными процессу ремонта, у этого могут быть вредные последствия:
Текущее значение AUTO_INCREMENT
потеряно.
.MYI
указывает, сжата ли таблица. Если сервер
игнорирует эту информацию, он не может сказать, что таблица сжата, и ремонт
может вызвать изменение или потерю табличного содержания. Это означает, что
USE_FRM
не должна использоваться со сжатыми таблицами. Это не
должно быть необходимо: сжатые таблицы предназначены только для чтения, таким
образом, они не должны стать поврежденными.Если USE_FRM
не используется,
REPAIR TABLE
проверяет таблицу, чтобы видеть, требуется ли обновление. Если так, это
выполняет обновление по тем же самым правилам, как
CHECK TABLE ... FOR UPGRADE
.
См. раздел 14.7.2.2.
По умолчанию, сервер пишет REPAIR
TABLE
в двоичный журнал так, чтобы они копировались к ведомым
устройствам. Чтобы подавить журналирование, определите дополнительный
параметр NO_WRITE_TO_BINLOG
или LOCAL
.
Когда таблица на ведущем устройстве становится поврежденной, и Вы
выполняете REPAIR TABLE
,
любые получающиеся изменения оригинальной таблицы не
размножены ведомым устройствам.
Вы можете быть в состоянии увеличить скорость
REPAIR TABLE
, устанавливая
определенные системные переменные. См.
раздел 9.6.3.
CREATE [AGGREGATE] FUNCTIONUser-defined function (UDF) является способом расширить MySQL с новой функцией, которая работает как родная (встроенная) функция MySQL, например,function_name
RETURNS {STRING|INTEGER|REAL|DECIMAL} SONAMEshared_library_name
ABS()
или
CONCAT()
.
function_name
имя, которое должно использоваться в
запросах SQL, чтобы вызвать функцию. RETURNS
указывает на тип возвращаемого значения функции.
DECIMAL
допустимое значение после RETURNS
, но в настоящее время
DECIMAL
возвращают
строковые значения и должны быть написаны как STRING
.
shared_library_name
это базовое имя совместно
используемого файла библиотеки, который содержит код, который осуществляет
функцию. Файл должен быть расположен в каталоге плагинов. Этот каталог дан
значением plugin_dir
.
См. раздел 26.4.2.5.
Чтобы создать функцию, Вы должны иметь привилегию
INSERT
для базы данных
mysql
. Это необходимо потому что
CREATE FUNCTION
добавляет строку к системной таблице mysql.func
, которая делает
запись имени функции и имени библиотеки. Если у Вас нет этой таблицы, Вы
должны выполнить
mysql_upgrade, чтобы создать ее. См.
раздел 5.4.5.
Активная функция это та, которая была загружена
CREATE FUNCTION
и не удалена с DROP FUNCTION
.
Все активные функции перезагружены каждый раз, когда сервер запускается, если
Вы не запускаете mysqld
с опцией
--skip-grant-tables
. В этом случае инициализация UDF
пропущена и UDF недоступны.
См. раздел 26.4.2. Для механизма UDF, чтобы работать, функции должны быть написаны на C или C++ (или другом языке, который может использовать соглашение вызова C), Ваша операционная система должна поддерживать динамическую загрузку, и Вы должны собрать mysqld динамически (не статически).
AGGREGATE
работает точно как совокупная функция MySQL вроде
SUM
или COUNT()
. Чтобы AGGREGATE
работала, Ваша таблица
mysql.func
должна содержать столбец type
. Если это
не так, выполните
mysql_upgrade (см.
раздел 5.4.5.
Чтобы обновить совместно используемую библиотеку UDF, используйте
DROP FUNCTION
,
обновите совместно используемую библиотеку, и затем скомандуйте
CREATE FUNCTION
. Если Вы
обновляете совместно используемую библиотеку сначала и затем используете
DROP FUNCTION
,
сервер может рухнуть.
DROP FUNCTION function_name
Этот запрос удаляет определяемую пользователем функцию (UDF)
function_name
.
Чтобы удалить функцию, Вы должны иметь привилегию
DELETE
для базы данных
mysql
. Это потому, что
DROP FUNCTION
удаляет строку из системной таблицы mysql.func
, которая делает
запись имени функции.
DROP FUNCTION
также используется, чтобы удалить сохраненные функции (см.
раздел 14.1.23).
INSTALL COMPONENTЭтот запрос устанавливает один или более серверных компонентов, которые становятся активными немедленно. Компонент оказывает услуги, которые доступны серверу и другим компонентам.component_name
[,component_name
] ...
INSTALL COMPONENT
требует привилегию INSERT
для таблицы mysql.component
.
Служба загрузчика обрабатывает установку компонентов, а
также перечисляет установленные компоненты в mysql.component
,
которая служит регистрацией. Для последующих перезапусков сервера любые
компоненты, перечисленные в mysql.component
,
установлены службой загрузчика во время запуска. Это происходит, даже если
сервер запущен с
--skip-grant-tables
(это отличается от эффекта той опции в
подавлении загрузки mysql.event
,
mysql.func
и mysql.proc
).
Если компонент зависит от служб, не существующих в регистрации, и Вы пытаетесь установить компонент, также не устанавливая компонент или компоненты, которые оказывают услуги, от которых это зависит, ошибка происходит:
ERROR 3527 (HY000): Cannot satisfy dependency for service 'component1' required by component 'component2'.Чтобы избежать этого, устанавливайте все компоненты в том же самом запросе или устанавливайте зависимый компонент после установки любых компонентов, от которых это зависит.
Если ошибка происходит, запрос не имеет никакого эффекта. Например, это происходит, если название компонента ошибочно, названный компонент не существует или уже установлен или инициализация терпит неудачу.
В настоящее время названия компонента это URN, которые начинаются
file://
и для которого следующее значение имени файла не
содержит имен каталогов и задано относительно каталога, названного
в переменной plugin_dir
. Названия компонента не включают зависимого от платформы суффикса
имени файла, например, .so
или .dll
.
Эти детали подвержены изменениям, потому что интерпретация названия
компонента самостоятельно выполнена службой, и составляющая инфраструктура
позволяет заменить выполнение службы по умолчанию альтернативным выполнением.
Например:
INSTALL COMPONENT 'file://component1', 'file://component2';См. раздел 6.5.
INSTALL PLUGINЭтот запрос устанавливает плагин сервера. Это требует привилегииplugin_name
SONAME 'shared_library_name
'
INSERT
для
таблицы mysql.plugin
.
plugin_name
это название плагина как определено в
дескрипторной структуре, содержавшейся в файле библиотеки (см.
раздел 26.2.4.2).
Имена не являются чувствительными к регистру. Для максимальной совместимости
имена должны быть ограничены символами ASCII, цифрами
и подчеркиванием, потому что они используются в исходных файлах C и SQL.
shared_library_name
название совместно используемой
библиотеки, которая содержит код плагина. Имя включает расширение имени файла
(например, libmyplugin.so
,
libmyplugin.dll
или libmyplugin.dylib
).
Совместно используемая библиотека должна быть расположена в каталоге
плагинов (указан в plugin_dir
). Библиотека должна быть непосредственно в каталоге, не в
подкаталоге. По умолчанию
plugin_dir
это
подкаталог plugin
в соответствии с каталогом, названным
переменной pkglibdir
, но это может быть изменено, устанавливая
значение plugin_dir
при запуске сервера. Например, установите ее значение в файле
my.cnf
:
[mysqld]
plugin_dir=/path/to/plugin/directory
Если значение plugin_dir
относительный путь, это взято относительно основного каталога MySQL
(значение basedir
).
INSTALL PLUGIN
загрузки и инициализируют сменный код, чтобы сделать плагин доступным для
использования. Плагин инициализирован, выполняя его функцию инициализации,
которая обрабатывает любую установку, которую должен выполнить плагин прежде,
чем это сможет использоваться. Когда сервер закрывается, он выполняет функцию
парковки для каждого плагина, который загружен так, чтобы у плагина был шанс
выполнить любую заключительную уборку.
INSTALL PLUGIN
также регистрирует плагин, добавляя строку, которая указывает на имя плагина
и имя файла библиотеки в таблицу mysql.plugin
.
При запуске сервера он загружает и инициализирует любой плагин, который
перечислен в mysql.plugin
. Это означает, что плагин
установлен с INSTALL PLUGIN
, только однажды, а не каждый раз, когда сервер запускается. Загрузки
плагина при запуске не происходит, если сервер запущен с опцией
--skip-grant-tables
.
Библиотека может содержать много плагинов.
Для каждого из них используйте отдельный запрос
INSTALL PLUGIN
.
Каждый запрос называет различный плагин, но все они определяют то же
самое имя библиотеки.
INSTALL PLUGIN
заставляет сервер читать файл опций (my.cnf
), как во время
запуска сервера. Это позволяет плагину поднять любые соответствующие опции от
тех файлов. Возможно добавить опции к файлу опции даже прежде, чем загрузить
плагин (если использовать префикс loose
).
Также возможно удалить плагин, отредактировать my.cnf
и
установить плагин снова. Перезапуск плагина этим путем приводит к новым
значениям опции без перезапуска сервера.
Для опций, которые управляют отдельным плагином, загружающимся при запуске
сервера, см.
раздел 6.6.2. Если Вы должны загрузить плагины для запуска
сервера, когда задана опция
--skip-grant-tables
(которая говорит серверу не читать системные
таблицы), используйте опцию
--plugin-load
, см.
раздел 6.1.4.
Чтобы удалить плагин, используйте запрос
UNINSTALL PLUGIN
.
См. раздел 6.6.2.
Чтобы видеть, какие плагины установлены, используйте
SHOW PLUGINS
или смотрите таблицу
INFORMATION_SCHEMA.PLUGINS
.
Если Вы повторно собираете библиотеку и надо повторно установить ее, Вы можете использовать любой из следующих методов:
Используйте UNINSTALL
PLUGIN
, чтобы удалить все плагины в библиотеке, установите новый
файл библиотеки в каталоге, и затем используйте
INSTALL PLUGIN
, чтобы
устанавливать все плагины в библиотеке. У этой процедуры есть преимущество,
что это может использоваться, не останавливая сервер. Однако, если
библиотека содержит много плагинов, Вы должны выпустить много запросов
INSTALL PLUGIN
и
UNINSTALL PLUGIN
.
UNINSTALL COMPONENTЭтот запрос дезактивирует и удаляет один или более серверных компонентов. Это требует привилегииcomponent_name
[,component_name
] ...
DELETE
для таблицы mysql.component
.
UNINSTALL COMPONENT
дополнение INSTALL COMPONENT
.
Служба загрузчика также разрегистрирует удаленные компоненты в
A loader service also unregisters uninstalled components from
mysql.component
. В результате они больше не установлены во время
запуска для последующих перезапусков сервера.
Если ошибка происходит, запрос не имеет никакого эффекта. Например, это происходит, если название компонента ошибочно, названный компонент не установлен или не может быть удален, потому что другие установленные компоненты зависят от этого.
См. раздел 14.7.3.3.
Пример:
UNINSTALL COMPONENT 'file://component2';См. раздел 6.5.
UNINSTALL PLUGIN plugin_name
Этот запрос удаляет установленный плагин сервера. Это требует привилегию
DELETE
на системной
таблице mysql.plugin
.
UNINSTALL PLUGIN
дополняет
INSTALL PLUGIN
.
plugin_name
должно быть названием некоторого плагина,
который перечислен в таблице mysql.plugin
.
Сервер выполняет функцию парковки плагина и удаляет строку для плагина из
таблицы mysql.plugin
, чтобы последующие перезапуски сервера не
загрузили и инициализировали плагин.
UNINSTALL PLUGIN
не удаляет совместно используемый
файл библиотеки плагина.
Вы не можете удалить плагин, если любая таблица, которая использует это, открыта.
У удаления есть значения для использования связанных таблиц. Например,
если полнотекстовый плагин анализатора связан с индексом
FULLTEXT
таблицы, удаление плагина делает таблицу непригодной.
Любая попытка получить доступ к таблице приводит к ошибке. Таблица не может
даже быть открыта, таким образом, Вы не можете удалить индекс, для которого
используется плагин. Это означает, что удаление плагина является чем-то, что
надо делать аккуратно. Если Вы удаляете плагин без намерения повторно
установить это позже, и Вы заботитесь о табличном содержании, Вы должны
вывести таблицу в дамп с помощью
mysqldump и удалить WITH PARSER
из
CREATE TABLE
в дампе, чтобы
Вы могли перезагрузить таблицу позже. Если Вы не заботитесь о таблице,
DROP TABLE
может
использоваться, даже если какие-либо плагины,
связанные с таблицей, отсутствуют.
См. раздел 6.6.2.
SET
имеет несколько форм:
SET
позволяет Вам назначить значения на переменные, которые затрагивают работу
сервера или клиентов. См. раздел 14.7.4.1.
var_name
= value
SET CHARACTER SET
и
SET NAMES
назначают значения набора символов и сопоставления, связанные с текущим
соединением с сервером. См. разделы
14.7.4.2 и
14.7.4.3.SET DEFAULT ROLE
и
SET ROLE
устанавливают роль по
умолчанию и текущую роль для учетных записей пользователя. См. разделы
14.7.1.10 и
14.7.1.12.SET PASSWORD
назначает пароли учетной записи. См.
раздел 14.7.1.11.SET TRANSACTION ISOLATION LEVEL
устанавливает уровень изоляции для обработки транзакций. См.
раздел 14.3.6.SETvariable_assignment
[,variable_assignment
] ...variable_assignment
:user_var_name
=expr
|param_name
=expr
|local_var_name
=expr
| [GLOBAL | SESSION | PERSIST]system_var_name
=expr
| [@@global. | @@session. | @@persist. | @@]system_var_name
=expr
SET
для назначения переменных
позволяет Вам назначить значения на различные типы переменных, которые
затрагивают работу сервера или клиентов:
Системные переенные. См.
раздел 6.1.5.
Системные переенные также могут быть установлены при запуске сервера, как
описано в разделе 6.1.6.
Чтобы вывести на экран имя и значение системные
переменной, используйте SHOW
VARIABLES
, см.
раздел 14.7.5.39.
SET
, который назначает
переменные значения, не записан в двоичный журнал, таким образом, в скриптах
репликации это затрагивает только хост, на котором Вы выполняете это. Чтобы
затронуть все хосты, выполните запрос на каждом.
Следующие примеры иллюстрируют
SET
для того, чтобы установить переменные. Они используют оператор назначения
=
, но оператор
назначения :=
также разрешен с этой целью.
Пользовательская переменная записана как
@
и назначено значение выражения следующим образом:
var_name
SET @Примеры:var_name
=expr
;
SET @name = 43; SET @total_tax = (SELECT SUM(tax) FROM taxable_transactions);Как демонстрирующийся этими запросами,
expr
может быть простым (буквальное значение) или более сложным
(значение, возвращенное скалярным подзапросом).
SET
относится к параметрам и местным переменным в контексте объекта, в пределах
которого они определены. Следующая процедура использует
местную переменную counter
как счетчик:
CREATE PROCEDURE p() BEGIN DECLARE counter INT DEFAULT 0; WHILE counter < 10 DO -- ... do work ... SET counter = counter + 1; END WHILE; END;Много системных переменных являются динамичными и могут быть изменены во время выполнения при использовании
SET
. Список см. в
разделе 6.1.6.2.
Чтобы изменить системную переменную с
SET
,
обратитесь к этому по имени, произвольно предваренному модификатором:
Чтобы указать, что переменная глобальная, предшествуйте ее имени
GLOBAL
или @@global.
:
SET GLOBAL max_connections = 1000; SET @@global.max_connections = 1000;Привилегия
SUPER
нужна,
чтобы устанавливать глобальные переменные.PERSIST
или
@@persist.
:
SET PERSIST max_connections = 1000; SET @@persist.max_connections = 1000;
SET
позволяет Вам произвести изменения конфигурации во время
выполнения, которые также сохраняются через перезапуски сервера. Как
SET GLOBAL
,
SET PERSIST
изменяет значение переменной во время выполнения, но также пишет установку
переменной в файл опции mysqld-auto.cnf
в каталоге данных (заменяющий любую существующую установку переменной,
если есть). При запуске сервер обрабатывает этот файл после всех других
файлов опции. Нужна привилегия
SUPER
, чтобы сохранять глобальные переменные.
Управление mysqld-auto.cnf
нужно оставить серверу и не выполнять вручную:
Удаление файла приведет к потере всех сохраненных настроек при следующем запуске сервера. Это допустимо, если Ваше намерение состоит в том, чтобы реконфигурировать сервер без этих настроек.
persisted_globals_load
или с опцией --no-defaults
.
Альтернативно, удалите файл mysqld-auto.cnf
,
но, как отмечено ранее, удаляя этот файл потеряете все сохраненные настройки.
Переменная плагина может быть сохранена, если плагин установлен, когда
выполнен SET PERSIST
.
Назначение сохраненной переменной плагина вступает в силу для последующих
перезапусков сервера, если плагин все еще установлен. Если плагин больше не
будет установлен, то переменная не будет существовать, когда сервер будет
читать файл mysqld-auto.cnf
. В этом случае сервер пишет
предупреждение в журнал ошибок и продолжает работу:
currently unknown variable 'var_name
'
was read from the persisted config file
SESSION
, @@session.
или @@
:
SET SESSION sql_mode = 'TRADITIONAL'; SET @@session.sql_mode = 'TRADITIONAL'; SET @@sql_mode = 'TRADITIONAL';Установка переменной сеанса обычно не требует никакой специальной привилегии, хотя есть исключения, которые требуют привилегию
SUPER
(например,
sql_log_bin
).
Клиент может изменить его собственные переменные сеанса, но не таковые для
любого другого клиента.
Системные переменные только для сеанса не могут быть сохранены. Они не
могут быть установлены при запуске сервера, таким образом нет никакой причины
перечислить их в mysqld-auto.cnf
.
LOCAL
и @@local.
синонимы для
SESSION
и @@session.
.SET
меняет переменную сеанса. Если у переменной нет никакого значения
сеанса, ошибка происходит.
mysql> SET max_connections = 1000; ERROR 1229 (HY000): Variable 'max_connections' is a GLOBAL variable and should be set with SET GLOBAL
Используйте SET
GLOBAL
(@@global.
) или
SET PERSIST
(или
@@persist.
), устанавливая переменную, у которой есть
только значение сеанса.
GLOBAL
(или
@@global.
) или PERSIST
(или
@@persist.
), устанавливая переменную, у которой есть
только глобальное значение.SET SESSION
(или @@SESSION.
), устанавливая переменную, у которой есть
только глобальное значение.Предыдущие модификаторы применяются только к системным переменным. Ошибка происходит для попыток применить их к определяемым пользователем переменным, хранимой процедуре или функциональным параметрам или местным переменным сохраненной программы.
SET
может содержать многократные переменные назначения, отделенные запятыми. Этот
запрос назначает значения на определяемую пользователем
переменную и системную переменную:
SET @x = 1, SESSION sql_mode = '';Если Вы устанавливаете многократные системные переменные, новый модификатор
GLOBAL
или SESSION
в запросе используется для следующих назначений, у которых нет
никакого определенного модификатора.
Примеры многократно-переменного назначения:
SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000; SET @@global.sort_buffer_size = 1000000, @@local.sort_buffer_size = 1000000; SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;Если любое переменное назначение в
SET
терпит неудачу, весь запрос терпит неудачу, никакие переменные не изменены,
mysqld-auto.cnf
не изменен тоже.
Если Вы меняете системную переменную сеанса, значение остается в силе в пределах Вашего сеанса, пока Вы не меняете переменную к иному значению или завершаете сеанс. Изменение не имеет никакого эффекта на другие сеансы.
Если Вы меняете глобальную системную переменную, значение используется
для новых сеансов, пока Вы не меняете переменную к иному значению или
не завершите сервер. Изменение видимо любому клиенту, который получает доступ
к глобальной переменной. Однако, изменение затрагивает соответствующую
переменную сеанса только для клиентов, которые соединяются после изменения.
Изменение глобальной переменной не затрагивает переменную сеанса для любых
текущих сеансов клиента (даже сеанс, в пределах которого выполнена команда
SET GLOBAL
).
Чтобы сделать установку глобальной системной переменной постоянной,
чтобы это применилось через перезапуски сервера, измените это с помощью
SET PERSIST
, чтобы
сделать запись в файл mysqld-auto.cnf
.
Также возможно использовать SET
GLOBAL
и вручную изменить my.cnf
, но тут есть
вероятность накосячить. SET
PERSIST
более удобно.
Чтобы установить значение GLOBAL
в значение по умолчанию MySQL или соответствующее GLOBAL
,
установите переменную к значению DEFAULT
. Например, следующие
два запроса идентичны в установке значения
max_join_size
к текущему глобальному значению:
SET @@session.max_join_size=DEFAULT; SET @@session.max_join_size=@@global.max_join_size;Не все системные переменные могут быть установлены в
DEFAULT
.
В таких случаях назначение DEFAULT
приводит к ошибке.
С SET
PERSIST
(или @@persist.
),
эффект установки глобальной переменной к ее значению по умолчанию
является определенным версией:
С MySQL 8.0.1 установка глобальной переменной в
DEFAULT
назначает значение по умолчанию и удаляет это из
файла mysqld-auto.cnf
. Установка переменной к ее буквальному
значению по умолчанию назначает значение по умолчанию и добавляет установку
для переменной в файл mysqld-auto.cnf
.
DEFAULT
или к буквальной переменной назначает ее значение по умолчанию. Это также
добавляет установку для переменной к файлу mysqld-auto.cnf
,
если ее там нет, и удаляет из
mysqld-auto.cnf
, если есть.Ошибка происходит для попыток назначить DEFAULT
определяемым
пользователем переменным, хранимой процедуре или функциональным параметрам
или местным переменным сохраненной программы.
Чтобы обратиться к значению системной переменной в выражениях, используйте
один из модификаторов @@
.
Например, Вы можете получить значения в
SELECT
:
SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;Для ссылки на системную переменную в выражении как
@@var_name
(вместо
@@global.
или @@session.
) MySQL
возвращает значение сеанса, если это существует и глобальное значение иначе.
Это отличается от SET @@var_name
= expr
, который всегда обращается к значению сеанса.
@@persist.
не разрешен в выражениях.
SET {CHARACTER SET | CHARSET}
{charset_name
| DEFAULT}
Этот запрос отображает все строки, посланные между сервером и текущим
клиентом с данным отображением. SET CHARACTER SET
устанавливает три системных переменные сеанса:
character_set_client
и
character_set_results
установлены в данный набор символов, и
character_set_connection
к значению
character_set_database
. См.
раздел 11.1.4.
Отображение наборов символов по умолчанию может быть восстановлено при
использовании значения DEFAULT
.
Значение по умолчанию зависит от конфигурации сервера.
ucs2
, utf16
и utf32
не может использоваться в качестве набора символов клиента, что означает, что
они не работают в SET CHARACTER SET
.
SET NAMES {'Этот запрос устанавливает три системных переменные сеансаcharset_name
' [COLLATE 'collation_name
'] | DEFAULT}
character_set_client
,
character_set_connection
и
character_set_results
к данному набору символов. Установка
character_set_connection
в charset_name
также установит
collation_connection
к сопоставлению по умолчанию для
charset_name
. См.
раздел 11.1.4.
Дополнительный параметр COLLATE
может использоваться, чтобы
определить сопоставление явно. Если дано, сопоставление должно быть одним из
разрешенных сопоставлений для charset_name
.
Отображение значения по умолчанию может быть восстановлено при
использовании значения DEFAULT
.
Значение по умолчанию зависит от конфигурации сервера.
ucs2
, utf16
и utf32
не может использоваться в качестве набора символов клиента, что означает, что
они не работают в SET NAMES
.
SHOW
имеет много форм, которые предоставляют информацию о базах данных, таблицах,
столбцах или сервере. Этот раздел описывает следующее:
SHOW {BINARY | MASTER} LOGS SHOW BINLOG EVENTS [IN 'Если синтаксис для данногоlog_name
'] [FROMpos
] [LIMIT [offset
,]row_count
] SHOW CHARACTER SET [like_or_where
] SHOW COLLATION [like_or_where
] SHOW [FULL] COLUMNS FROMtbl_name
[FROMdb_name
] [like_or_where
] SHOW CREATE DATABASEdb_name
SHOW CREATE EVENTevent_name
SHOW CREATE FUNCTIONfunc_name
SHOW CREATE PROCEDUREproc_name
SHOW CREATE TABLEtbl_name
SHOW CREATE TRIGGERtrigger_name
SHOW CREATE VIEWview_name
SHOW DATABASES [like_or_where
] SHOW ENGINEengine_name
{STATUS | MUTEX} SHOW [STORAGE] ENGINES SHOW ERRORS [LIMIT [offset
,]row_count
] SHOW EVENTS SHOW FUNCTION CODEfunc_name
SHOW FUNCTION STATUS [like_or_where
] SHOW GRANTS FORuser
SHOW INDEX FROMtbl_name
[FROMdb_name
] SHOW MASTER STATUS SHOW OPEN TABLES [FROMdb_name
] [like_or_where
] SHOW PLUGINS SHOW PROCEDURE CODEproc_name
SHOW PROCEDURE STATUS [like_or_where
] SHOW PRIVILEGES SHOW [FULL] PROCESSLIST SHOW PROFILE [types
] [FOR QUERYn
] [OFFSETn
] [LIMITn
] SHOW PROFILES SHOW RELAYLOG EVENTS [IN 'log_name
'] [FROMpos
] [LIMIT [offset
,]row_count
] SHOW SLAVE HOSTS SHOW SLAVE STATUS [NONBLOCKING] SHOW [GLOBAL | SESSION] STATUS [like_or_where
] SHOW TABLE STATUS [FROMdb_name
] [like_or_where
] SHOW [FULL] TABLES [FROMdb_name
] [like_or_where
] SHOW TRIGGERS [FROMdb_name
] [like_or_where
] SHOW [GLOBAL | SESSION] VARIABLES [like_or_where
] SHOW WARNINGS [LIMIT [offset
,]row_count
]like_or_where
: LIKE 'pattern
' | WHEREexpr
SHOW
включает часть LIKE
'pattern
'
,
'pattern
'
это
строка, которая может содержать SQL-символы %
и
_
. Образец полезен для ограничения вывода
запроса соответствием значений.
Несколько SHOW
также принимают
WHERE
, который обеспечивает больше гибкости в определении,
которые строки вывести на экран. См.
раздел 22.31.
Много MySQL APIs (например, PHP) позволяют обработать результат
SHOW
как набор результатов из
SELECT
, см.
главу 25.
Кроме того, Вы можете работать в SQL с результатами запросов на таблицах
в базе данных INFORMATION_SCHEMA
, которые Вы не можете легко
полцить из SHOW
. См.
главу 22.
SHOW BINARY LOGS SHOW MASTER LOGSПеречисляет двоичные файлы системного журнала на сервере. Это запрос используется как часть процедуры, описанной в разделе 14.4.1.1, которая показывает, как определить, какие журналы могут быть очищены.
mysql> SHOW BINARY LOGS; +---------------+-----------+ | Log_name | File_size | +---------------+-----------+ | binlog.000015 | 724935 | | binlog.000016 | 733481 | +---------------+-----------+
SHOW MASTER LOGS
эквивалент SHOW BINARY LOGS
.
Нужны привилегии SUPER
или REPLICATION CLIENT
.
SHOW BINLOG EVENTS [IN 'Показывает события в двоичном журнале. Если Вы не определяетеlog_name
'] [FROMpos
] [LIMIT [offset
,]row_count
]
'log_name
'
,
первый двоичный журнал выведен на экран.
LIMIT
имеет тот же самый синтаксис, что в
SELECT
. См.
раздел 14.2.9.
SHOW BINLOG EVENTS
без LIMIT
может занять очень много времени и потреблять ресурс
процесса, потому что сервер возвращает клиенту полное содержание двоичного
журнала (который включает все запросы, выполненные сервером, которые изменяют
данные). Как альтернатива SHOW
BINLOG EVENTS
, используйте
mysqlbinlog, чтобы сохранить двоичной
журнал к текстовому файлу для более поздней экспертизы и анализа. См.
раздел 5.6.8.
Некоторые события, касающиеся установки пользователя и системных
переменных, не включены в вывод
SHOW BINLOG EVENTS
. Чтобы получить полный обзор событий в пределах
двоичного журнала, используйте
mysqlbinlog.
SHOW BINLOG EVENTS
не работает с файлами системного журнала реле. Вы
можете использовать SHOW
RELAYLOG EVENTS
для этого.
SHOW CHARACTER SET [LIKE 'pattern
' | WHEREexpr
]
SHOW CHARACTER SET
показывает все доступные наборы символов.
LIKE
, если дан,
указывает, который набор символов соответствует. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в разделе 22.31:
mysql> SHOW CHARACTER SET LIKE 'latin%'; +---------+-----------------------------+-------------------+--------+ | Charset | Description | Default collation | Maxlen | +---------+-----------------------------+-------------------+--------+ | latin1 | cp1252 West European | latin1_swedish_ci | 1 | | latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 | | latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 | | latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 | +---------+-----------------------------+-------------------+--------+
Maxlen
показывает максимальное количество байтов, требуемых,
чтобы сохранить один символ.
filename
набора символов только для внутреннего пользования,
SHOW CHARACTER SET
не выводит его на экран.
Вы можете также получить информацию о наборах символов из
INFORMATION_SCHEMA
, которая содержит таблицу
CHARACTER_SETS
.
См. раздел 22.1.
SHOW COLLATION [LIKE 'Этот запрос перечисляет сопоставления, поддержанные сервером. По умолчанию выводpattern
' | WHEREexpr
]
SHOW COLLATION
включает все доступные сопоставления.
LIKE
, если есть,
указывает, которое сопоставление соответствует. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в разделе 22.31:
mysql> SHOW COLLATION WHERE Charset = 'latin1'; +-------------------+---------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +-------------------+---------+----+---------+----------+---------+ | latin1_german1_ci | latin1 | 5 | | Yes | 1 | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 | | latin1_danish_ci | latin1 | 15 | | Yes | 1 | | latin1_german2_ci | latin1 | 31 | | Yes | 2 | | latin1_bin | latin1 | 47 | | Yes | 1 | | latin1_general_ci | latin1 | 48 | | Yes | 1 | | latin1_general_cs | latin1 | 49 | | Yes | 1 | | latin1_spanish_ci | latin1 | 94 | | Yes | 1 | +-------------------+---------+----+---------+----------+---------+Столбцы
Collation
и Charset
указывают на названия сопоставления и набора символов, с которым оно связано.
Id
ID сопоставления. Default
указывает, является ли сопоставление значением по умолчанию для своего набора
символов. Compiled
указывает, собран ли набор символов в сервер.
Sortlen
связан с суммой памяти, требуемой, чтобы сортировать
строки, выраженные в наборе символов.
Чтобы видеть сопоставление по умолчанию для каждого набора символов,
используйте следующий запрос. Default
это зарезервированное
слово, чтобы использовать это в качестве идентификатора, это должно
быть заключено в кавычки:
mysql> SHOW COLLATION WHERE `Default` = 'Yes'; +-------------------+---------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +-------------------+---------+----+---------+----------+---------+ | big5_chinese_ci | big5 | 1 | Yes | Yes | 1 | | dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 | | cp850_general_ci | cp850 | 4 | Yes | Yes | 1 | | hp8_english_ci | hp8 | 6 | Yes | Yes | 1 | | koi8r_general_ci | koi8r | 7 | Yes | Yes | 1 | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 | ...Вы можете также получить информацию о сопоставлениях из
INFORMATION_SCHEMA
, которая содержит таблицу
COLLATIONS
, см.
раздел 22.2.
SHOW [FULL] COLUMNS {FROM | IN}tbl_name
[{FROM | IN}db_name
] [LIKE 'pattern
' | WHEREexpr
]
SHOW COLUMNS
показывает сведения о столбцах в данной таблице. Это также работает на
представлениях. LIKE
,
если есть, указывает, которые имена столбцов соответствуют.
WHERE
может быть дан, чтобы выбрать строки, используя более
общие условия, как обсуждено в разделе
22.31.
SHOW COLUMNS
покажет сведения только для тех столбцов, для которых у Вас
есть некоторая привилегия.
mysql> SHOW COLUMNS FROM City; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | Id | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | Country | char(3) | NO | UNI | | | | District | char(20) | YES | MUL | | | | Population | int(11) | NO | | 0 | | +------------+----------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)Если типы данных отличаются от того, что Вы ожидаете, что они будут основаны на
CREATE TABLE
,
отметьте, что MySQL иногда изменяет типы данных, когда Вы создаете или
изменяете таблицу. Условия, при которых это происходит, описаны в
раздел 14.1.15.4.
FULL
заставляет вывод включать сопоставление столбца и
комментарии, так же как привилегии, которые Вы имеете для каждого столбца.
Вы можете использовать db_name.tbl_name
как альтернативу
.
Другими словами, эти два запроса эквивалентны:
tbl_name
FROM db_name
mysql> SHOW COLUMNS FROM mytable FROM mydb; mysql> SHOW COLUMNS FROM mydb.mytable;
SHOW COLUMNS
покажет
следующие значения для каждого столбца таблицы:
Field
имя столбца.
Type
тип данных столбца.
Collation
указывает на сопоставление для недвоичных строковых
столбцов или NULL
для других столбцов. Это значение выведено на
экран, только если Вы используете FULL
.
Поле Null
содержит YES
, если значения
NULL
могут быть сохранены в столбце, NO
если нет.
Поле Key
указывает, индексирован ли столбец:
Если Key
пусто, столбец не индексирован или
индексирован только как вторичный столбец в многостолбцовом групповом индексе.
Key
PRI
, столбец PRIMARY KEY
или один из столбцов в многостолбцовом PRIMARY KEY
.Key
UNI
, это первый столбец индекса
UNIQUE
. Он допускает многократные NULL
, но Вы
можете сказать, разрешает ли столбец NULL
проверяя поле Null
.Key
MUL
, это первый столбец группового
индекса, в котором многократные возникновения данного значения
разрешены в пределах столбца.Если больше, чем одно из значений Key
относится к данному
столбцу таблицы, Key
выводит на экран значение с самым высоким
приоритетом, в порядке PRI
, UNI
, MUL
.
Индекс UNIQUE
может быть выведен на экран как
PRI
, если это не может содержать NULL
и нет PRIMARY KEY
в таблице. UNIQUE
может вывести на экран как MUL
, если несколько столбцов
формируют композитный индекс UNIQUE
, хотя комбинация столбцов
уникальна, каждый столбец все еще может содержать многократные
возникновения данного значения.
Поле Default
указывает на значение по умолчанию, которое
назначено столбцу. Это NULL
, если у столбца есть явное значение
по умолчанию NULL
, или если определение столбца
не имеет DEFAULT
.
Поле Extra
содержит любую дополнительную информацию, которая
доступна о данном столбце. Значение не пусто в этих случаях:
auto_increment
для столбцов, которые имеют
признак AUTO_INCREMENT
.
on update CURRENT_TIMESTAMP
для столбцов
TIMESTAMP
или
DATETIME
, которые имеют признак
ON UPDATE CURRENT_TIMESTAMP
.VIRTUAL GENERATED
или VIRTUAL STORED
для произведенных столбцов.Privileges
указывает на привилегии, которые Вы имеете для
столбца. Это значение выведено на экран, только если
Вы используете FULL
.
Comment
указывает на любой комментарий, который имеет
столбец. Это значение выведено на экран, только если
Вы используете FULL
.
SHOW FIELDS
синоним для
SHOW COLUMNS
.
Вы можете также перечислить столбцы таблицы с помощью
mysqlshow
db_name
tbl_name
.
DESCRIBE
предоставляет информацию, подобную SHOW
COLUMNS
. См. раздел 14.8.1.
SHOW CREATE TABLE
,
SHOW TABLE STATUS
и
SHOW INDEX
также предоставляют информацию о таблицах. См. раздел
14.7.5.
SHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
Показывает запрос CREATE DATABASE
, который создает названную базу данных. Если
SHOW
включает IF NOT EXISTS
,
вывод также включает такой пункт.
SHOW CREATE SCHEMA
синоним для SHOW CREATE DATABASE
.
mysql> SHOW CREATE DATABASE test\G *************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ mysql> SHOW CREATE SCHEMA test\G *************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */
SHOW CREATE DATABASE
берет в кавычки имена таблиц и имена столбцов согласно значению опции
sql_quote_show_create
. См. раздел 6.1.5
.
SHOW CREATE EVENT event_name
Отображает CREATE EVENT
,
который должен был обновить данное событие. Это требует привилегии
requires the EVENT
для базы данных, из которой нужно показать событие. Например (используя то же
самое событие e_daily
, которое использовано в
then altered in разделе 14.7.5.18):
mysql> SHOW CREATE EVENT test.e_daily\G *************************** 1. row *************************** Event: e_daily sql_mode: time_zone: SYSTEM Create Event: CREATE EVENT `e_daily` ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR ON COMPLETION NOT PRESERVE ENABLE COMMENT 'Saves total number of sessions then clears the table each day' DO BEGIN INSERT INTO site_activity.totals (time, total) SELECT CURRENT_TIMESTAMP, COUNT(*) FROM site_activity.sessions; DELETE FROM site_activity.sessions; END character_set_client: latin1 collation_connection: latin1_swedish_ci Database Collation: latin1_swedish_ci
character_set_client
это сессионное значение переменной
character_set_client
, когда событие создавалось
collation_connection
сессионное значение переменной
collation_connection
, когда событие создавалось. Database Collation
сопоставление базы данных, с которой связано событие.
Вывод отражает текущий статус события
(ENABLE
) вместо состояния, с которым это создавалось.
SHOW CREATE FUNCTION func_name
Этоь запрос подобен SHOW CREATE
PROCEDURE
, но для сохраненных функций. См.
раздел 14.7.5.9.
SHOW CREATE PROCEDURE proc_name
Этот запрос расширение MySQL. Это возвращает точную строку, которая может
использоваться, чтобы обновить названную хранимую процедуру. Подобный запрос,
SHOW CREATE FUNCTION
,
дает информацию о сохраненных функциях (см.
раздел 14.7.5.8).
Чтобы использовать любой запрос, Вы должны быть пользователем, названным в
подпрограмме DEFINER
или иметь доступ
SELECT
к таблице
mysql.proc
. Если у Вас нет привилегий для подпрограммы
непосредственно, значение для полей Create Procedure
или <
code>Create Function будет NULL
.
mysql> SHOW CREATE PROCEDURE test.simpleproc\G *************************** 1. row *************************** Procedure: simpleproc sql_mode: Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT) BEGIN SELECT COUNT(*) INTO param1 FROM t; END character_set_client: latin1 collation_connection: latin1_swedish_ci Database Collation: latin1_swedish_ci mysql> SHOW CREATE FUNCTION test.hello\G *************************** 1. row *************************** Function: hello sql_mode: Create Function: CREATE FUNCTION `hello`(s CHAR(20)) RETURNS CHAR(50) RETURN CONCAT('Hello, ',s,'!') character_set_client: latin1 collation_connection: latin1_swedish_ci Database Collation: latin1_swedish_ci
character_set_client
значение сеанса
the
character_set_client
, когда подпрограмма создавалась.
collation_connection
значение сеанса
collation_connection
, когда подпрограмма создавалась.
Database Collation
сопоставление базы данных, с
которой связана подпрограмма.
SHOW CREATE TABLE tbl_name
Показывает CREATE TABLE
,
который составляет названную таблицу. Чтобы использовать этот запрос, у Вас
должна быть некоторая привилегия для таблицы.
Этот запрос также работает с представлениями.
mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `s` char(60) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1
SHOW CREATE TABLE
цитирует имена таблиц и столбцов согласно значению опции
sql_quote_show_create
. См. раздел 6.1.5
.
SHOW CREATE TRIGGER trigger_name
Это запрос показывает запрос CREATE
TRIGGER
, который создает названный триггер. Это запрос требует
привилегию TRIGGER
для таблицы, связанной с триггером.
mysql> SHOW CREATE TRIGGER ins_sum\G *************************** 1. row *************************** Trigger: ins_sum sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION SQL Original Statement: CREATE DEFINER=`me`@`localhost` TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET @sum = @sum + NEW.amount character_set_client: utf8 collation_connection: utf8_general_ci Database Collation: latin1_swedish_ci Created: 2013-07-09 10:39:34.96Вывод
SHOW CREATE TRIGGER
имеет следующие столбцы:
Trigger
: Имя триггера.
sql_mode
: Режим SQL, когда триггер выполняется.SQL Original Statement
:
CREATE TRIGGER
, который определяет триггер.character_set_client
: Сессионное значение переменной
character_set_client
, когда триггер создавался.collation_connection
: Сессионное значение переменной
collation_connection
, когда триггер создавался.Database Collation
: Сопоставление базы данных, с
которой связан триггер.Created
: Дата и время, когда триггер создавался. Это
TIMESTAMP(2)
(с дробной частью в сотые части
секунд) для триггеров.Вы можете также получить информацию из
INFORMATION_SCHEMA
, которая имеет таблицу
TRIGGERS
, см.
раздел 22.27.
SHOW CREATE USER user
Этот запрос показывает CREATE
USER
, которое создает названного пользователя. Ошибка происходит,
если пользователь не существует. Запрос требует привилегию
SELECT
для базы данных
mysql
, кроме просмотра привилегий для текущего пользователя.
Чтобы назвать учетную запись, используйте формат, описанный в
разделе 7.2.3.
Если Вы определяете только часть имени пользователя имени учетной записи,
часть имени хоста '%'
. Также возможно определить
CURRENT_USER
или
CURRENT_USER()
,
чтобы ссылаться на учетную запись, связанную с текущим сеансом.
mysql> SHOW CREATE USER 'root'@'localhost'\G *************************** 1. row *************************** CREATE USER for root@localhost: CREATE USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCKВыходной формат затронут установкой
log_builtin_as_identified_by_password
.
Чтобы вывести на экран привилегии, предоставленные учетной записи,
используйте SHOW GRANTS
, см.
раздел 14.7.5.21.
SHOW CREATE VIEW view_name
Этот запрос показывает CREATE VIEW
, который создает названное представление.
mysql> SHOW CREATE VIEW v\G *************************** 1. row *************************** View: v Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`bob`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select 1 AS `a`,2 AS `b` character_set_client: latin1 collation_connection: latin1_swedish_ci
character_set_client
значение сеанса
character_set_client
, когда представление создавалось.
collation_connection
значение сеанса
collation_connection
, когда представление создавалось.
Использование SHOW CREATE VIEW
требует привилегии
SHOW VIEW
и SELECT
для рассматриваемого представления.
Вы можете также получить информацию об объектах представления из базы
данных INFORMATION_SCHEMA
, таблица
VIEWS
, см.
раздел 22.29.
MySQL позволяет Вам использовать отличающийся
sql_mode
, чтобы
сказать серверу тип синтаксиса SQL. Например, Вы могли бы использовать режим
SQL ANSI
, чтобы
гарантировать, что MySQL правильно интерпретирует стандартный оператор связи
SQL, двойную черту (||
), в Ваших запросах. Если Вы тогда
создаете представление, которое связывает элементы, Вы могли бы поменять
sql_mode
на
значение, отличающееся от ANSI
, а это может заставить представление становиться недопустимым. Но дело
обстоит не так. Независимо от того, как Вы описываете определение
представления, MySQL всегда хранит это одинаково, в канонической форме.
Вот пример, который показывает, как сервер изменяет оператор связи на
функцию CONCAT()
:
mysql> SET sql_mode = 'ANSI'; Query OK, 0 rows affected (0.00 sec) mysql> CREATE VIEW test.v AS SELECT 'a' || 'b' as col1; Query OK, 0 rows affected (0.01 sec) mysql> SHOW CREATE VIEW test.v\G *************************** 1. row *************************** View: v Create View: CREATE VIEW "v" AS select concat('a','b') AS "col1" ... 1 row in set (0.00 sec)Преимущество хранения определения представления в канонической форме состоит в том что изменения, произведенные позже в значении
sql_mode
не будут затрагивать работу представления. Однако дополнительное последствие
то, что комментарии до SELECT
исключены из определения сервером.
SHOW {DATABASES | SCHEMAS} [LIKE 'pattern
' | WHEREexpr
]
SHOW DATABASES
перечисляет базы данных по узлу сервера MySQL.
SHOW SCHEMAS
синоним для
SHOW DATABASES
.
LIKE
, если есть,
указывает, которые имена базы данных должны соответствовать.
WHERE
может быть дан, чтобы выбрать строки, используя более
общие условия, как обсуждено в разделе
22.31.
Вы видите только те базы данных, для которых у Вас есть некоторая
привилегия, если у Вас нет глобальной привилегии
SHOW DATABASES
.
Вы можете также получить этот список, используя
mysqlshow.
Если сервер был запущен с опцией
--skip-show-database
,
Вы не можете использовать это запрос вообще, если Вы не имеете привилегии
SHOW DATABASES
.
MySQL осуществляет базы данных как подкаталоги в каталоге данных, таким образом, этот запрос просто перечисляет каталоги. Однако, вывод может включать названия каталогов, которые не соответствуют фактическим базам данных.
SHOW ENGINE engine_name
{STATUS | MUTEX}
SHOW ENGINE
выводит на экран операционную информацию о механизме хранения. Это требует
привилегии PROCESS
.
У запроса есть эти разновидности:
SHOW ENGINE INNODB STATUS SHOW ENGINE INNODB MUTEX SHOW ENGINE PERFORMANCE_SCHEMA STATUS
SHOW ENGINE INNODB STATUS
выводит на экран обширную информацию от стандартного InnoDB
Monitor о статусе механизма хранения InnoDB
. См.
раздел 16.16.
SHOW ENGINE INNODB MUTEX
отображает статистику InnoDB
mutex и
rw-lock.
InnoDB
mutexes и rwlocks можно также отследить по таблицам в
Performance Schema, см.
раздел 16.15.2.
Набор статистики Mutex сконфигурирован динамически, используя следующие опции:
Чтобы включить сбор mutex статистики:
SET GLOBAL innodb_monitor_enable='latch';
SET GLOBAL innodb_monitor_reset='latch';
SET GLOBAL innodb_monitor_disable='latch';
Сбор mutex статистики для
SHOW ENGINE INNODB MUTEX
может также быть включен, устанавливая
innodb_monitor_enable='all'
или выключен, устанавливая
innodb_monitor_disable='all'
.
Вывод SHOW ENGINE INNODB MUTEX
включает следующие столбцы:
Type
Всегда InnoDB
.
Name
Для mutexes поле Name
сообщает только об имени mutex.
Для rwlocks Name
сообщает об исходном файле, где rwlock
осуществлен, и номер строки в файле, где rwlock создается. Номер строки
является определенным для Вашей версии MySQL.
Status
Статус mutex. Поле сообщает о числе spin, ожиданий и вызовов.
Статистика для низкоуровневых mutex операционной системы, которые
осуществлены за пределами InnoDB
, отсутствует.
spins
число spin.
waits
число ожиданий.calls
сколько раз mutex был запрошен.SHOW ENGINE INNODB MUTEX
пропускает
mutexes и
rw-locks блоков
буферного пула, поскольку
количество вывода может быть подавляющим на системах с большим буферным
пулом. Есть один mutex и одна rw-блокировка в каждом 16K буферном блоке
пула и 65536 блоков на каждый гигабайт. SHOW ENGINE INNODB MUTEX
также не перечисляет mutex или rw-блокировки, которые никогда не ждали
(os_waits=0
). Таким образом, SHOW ENGINE INNODB MUTEX
покажет только информацию о mutex и rw-locks
за пределами буферного пула, которые вызвали по крайней мере
одно ожидание на уровне OS.
Использовать SHOW ENGINE
PERFORMANCE_SCHEMA STATUS
, чтобы смотреть внутренние операции
кода Performance Schema:
mysql> SHOW ENGINE PERFORMANCE_SCHEMA STATUS\G ... *************************** 3. row *************************** Type: performance_schema Name: events_waits_history.size Status: 76 *************************** 4. row *************************** Type: performance_schema Name: events_waits_history.count Status: 10000 *************************** 5. row *************************** Type: performance_schema Name: events_waits_history.memory Status: 760000 ... *************************** 57. row *************************** Type: performance_schema Name: performance_schema.memory Status: 26459600 ...Этот запрос предназначен, чтобы помочь DBA понять эффекты, которые различные опции Performance Schema имеют на требования к памяти.
Name
состоят из двух частей, которые называют внутренний
буфер и буферный признак, соответственно. Интерпретируйте буферные
имена следующим образом:
Внутренний буфер, который не выставлен как таблица, называют в
пределах круглых скобок. Примеры: (pfs_cond_class).size
,
(pfs_mutex_class).memory
.
performance_schema
, называют после таблицы без
круглых скобок. Примеры: events_waits_history.size
,
mutex_instances.count
.performance_schema
:
performance_schema.memory
.У буферных признаков есть эти значения:
size
размер внутренней записи, используемой
выполнением, таким как размер строки в таблице. size
не могут быть изменены.
count
число внутренних записей, например,
число строк в таблице. count
могут быть изменены, используя
параметры конфигурации Performance Schema.tbl_name
.memory
произведение size
и count
. Для Performance Schema
в целом performance_schema.memory
сумма всей используемой памяти
(сумма всех значений memory
).В некоторых случаях есть непосредственная связь между
параметром конфигурации Performance Schema и SHOW ENGINE
.
Например, events_waits_history_long.count
соответствует
performance_schema_events_waits_history_long_size
.
В других случаях отношения более сложны. Например,
events_waits_history.count
соответствует
performance_schema_events_waits_history_size
(число строк на поток) умноженный на
performance_schema_max_thread_instances
(число потоков).
SHOW [STORAGE] ENGINES
SHOW ENGINES
показывает информацию о статусе механизмов хранения сервера. Это особенно
полезно для проверки, поддержан ли механизм хранения, или чтобы увидеть,
каков механизм по умолчанию. Эта информация может также быть получена из
INFORMATION_SCHEMA
(таблица
ENGINES
), см.
раздел 22.6.
mysql> SHOW ENGINES\G *************************** 1. row *************************** Engine: InnoDB Support: DEFAULT Comment: Supports transactions, row-level locking и foreign keys Transactions: YES XA: YES Savepoints: YES *************************** 2. row *************************** Engine: MRG_MYISAM Support: YES Comment: Collection of identical MyISAM tables Transactions: NO XA: NO Savepoints: NO *************************** 3. row *************************** Engine: MEMORY Support: YES Comment: Hash based, stored in memory, useful for temporary tables Transactions: NO XA: NO Savepoints: NO *************************** 4. row *************************** Engine: BLACKHOLE Support: YES Comment: /dev/null storage engine (anything you write to it disappears) Transactions: NO XA: NO Savepoints: NO *************************** 5. row *************************** Engine: MyISAM Support: YES Comment: MyISAM storage engine Transactions: NO XA: NO Savepoints: NO *************************** 6. row *************************** Engine: CSV Support: YES Comment: CSV storage engine Transactions: NO XA: NO Savepoints: NO *************************** 7. row *************************** Engine: ARCHIVE Support: YES Comment: Archive storage engine Transactions: NO XA: NO Savepoints: NO *************************** 8. row *************************** Engine: PERFORMANCE_SCHEMA Support: YES Comment: Performance Schema Transactions: NO XA: NO Savepoints: NO *************************** 9. row *************************** Engine: FEDERATED Support: YES Comment: Federated MySQL storage engine Transactions: NO XA: NO Savepoints: NOВывод
SHOW ENGINES
может измениться, согласно версии MySQL и другим факторам. Значения,
показанные в столбце Support
, указывают на уровень поддержки
сервером механизма хранения, как показано в следующей таблице.
Значение | Смысл |
---|---|
YES |
Механизм поддержан и активный. |
DEFAULT |
Like YES , но это механизм по умолчанию. |
NO | Механизм не поддержан. |
DISABLED |
Механизм поддержан, но был отключен. |
NO
значит, что сервер был собран без поддержки механизма,
таким образом, это не может быть включено во время выполнения.
DISABLED
происходит потому, что сервер был запущен с опциями,
которые отключает механизм, или потому что не все опции, необходимые, чтобы
включить это, были даны. В последнем случае файл журнала ошибок должен
содержать причину, указывающую, почему опция отключена. См.
раздел 6.4.2.
Вы могли бы также видеть DISABLED
для механизма хранения,
если сервер был собран, чтобы поддержать это, но был запущен с
опцией --skip-
.engine_name
Все MySQL поддерживают MyISAM
.
Невозможно отключить MyISAM
.
Столбцы Transactions
, XA
и
Savepoints
указывают, поддерживает ли механизм хранения
транзакции, транзакции XA и точки сохранения, соответственно.
SHOW ERRORS [LIMIT [offset
,]row_count
] SHOW COUNT(*) ERRORS
SHOW ERRORS
это диагностический запрос, который подобен
SHOW WARNINGS
,
за исключением того, что это выводит на экран информацию только для ошибок,
а не для ошибок, предупреждений и примечаний.
LIMIT
аналогичен соответствующему параметру в
SELECT
. См.
раздел 14.2.9.
SHOW COUNT(*) ERRORS
выводит на экран число ошибок. Вы можете также получить это число из
переменной error_count
:
SHOW COUNT(*) ERRORS; SELECT @@error_count;
SHOW ERRORS
и
error_count
относятся только к ошибкам, не предупреждениям или примечаниям. В других
отношениях они подобны SHOW WARNINGS
и warning_count
. В частности, SHOW ERRORS
не может вывести на экран информацию больше, чем
max_error_count
сообщений, и error_count
может превысить значение
max_error_count
, если число ошибок превышает
max_error_count
.
См. раздел 14.7.5.40.
SHOW EVENTS [{FROM | IN}Этот запрос выводит на экран информацию о событиях Event Manager. Нужна привилегияschema_name
] [LIKE 'pattern
' | WHEREexpr
]
EVENT
для базы данных, из которой нужно показать события.
В его самой простой форме SHOW EVENTS
перечисляет все события в текущей схеме:
mysql> SELECT CURRENT_USER(), SCHEMA(); +----------------+----------+ | CURRENT_USER() | SCHEMA() | +----------------+----------+ | jon@ghidora | myschema | +----------------+----------+ 1 row in set (0.00 sec) mysql> SHOW EVENTS\G *************************** 1. row *************************** Db: myschema Name: e_daily Definer: jon@ghidora Time zone: SYSTEM Type: RECURRING Execute at: NULL Interval value: 10 Interval field: SECOND Starts: 2006-02-09 10:41:23 Ends: NULL Status: ENABLED Originator: 0 character_set_client: latin1 collation_connection: latin1_swedish_ci Database Collation: latin1_swedish_ciЧтобы видеть события для определенной схемы, используйте
FROM
. Например, чтобы видеть события для схемы
test
, используйте следующий запрос:
SHOW EVENTS FROM test;
LIKE
, если есть,
указывает, которые события соответствуют. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия,
как обсуждено в разделе 22.31.
Вывод SHOW EVENTS
имеет следующие столбцы:
Db
: Схема (база данных), на
которой определено событие.
Name
: Название события.Time zone
: Часовой пояс событий, который является часовым
поясом, используемым для того, чтобы наметить событие и используется в
пределах события, когда это выполняется.
Значение по умолчанию SYSTEM
.Definer
: Учетная запись пользователя, который создал
событие, в виде 'user_name
'@'host_name
'
.Type
: Тип повторения событий:
ONE TIME
(разово) или RECURRING
(повторение).Execute At
: Дата и время, когда событие надо выполнить.
Показано как значение DATETIME
.
Для повторяемого события это всегда NULL
.
Interval Value
: Для повторяемого события
число интервалов, чтобы ждать между выполнением событий.
Для одноразового события значение этого столбца всегда NULL
.
Interval Field
: Единицы измерения времени
для интервала, который событие ждет перед повторением.
Для одноразового события значение этого столбца всегда NULL
.
Starts
: Дата и время начала для повторяемого события.
Это выведено на экран как значение
DATETIME
и NULL
,
если никакая дата и время начала не определены для случая.
Для одноразового события значение этого столбца всегда NULL
.
Ends
: Дата и время окончания для повторяемого события.
Это выведено на экран как значение
DATETIME
и NULL
,
если никакая дата и время окончания не определены для случая.
Для одноразового события значение этого столбца всегда NULL
.
Status
: Одно из ENABLED
, DISABLED
или SLAVESIDE_DISABLED
.
SLAVESIDE_DISABLED
указывает, что создание
произошло на другом сервере MySQL, действующем как ведущее устройство, и
событие копировалось к текущему серверу MySQL, который действует как ведомое
устройство, но событие теперь не запускается на ведомом устройстве.
Originator
: ID сервера MySQL, на котором создавалось
событие. Значение по умолчанию 0.character_set_client
сессионное значение
character_set_client
, когда подпрограмма создавалась.
collation_connection
сессионное значение
of the
collation_connection
, когда подпрограмма создавалась.
Database Collation
сопоставление базы данных,
с которой связана подпрограмма.См. раздел 19.4.1.12 .
Запрос действия событий не показывают в выводе
SHOW EVENTS
. Используйте
SHOW CREATE EVENT
или
таблицу INFORMATION_SCHEMA.EVENTS
.
Времена, выведенные на экран SHOW
EVENTS
, даны в часовом поясе, как обсуждено в
разделе 21.4.4.
Столбцы в выводе SHOW EVENTS
подобны, но не идентичны столбцам в таблице
INFORMATION_SCHEMA.EVENTS
.
См. раздел 22.7.
SHOW FUNCTION CODE func_name
Этот запрос подобен
SHOW PROCEDURE CODE
, но для сохраненных функций. См.
раздел 14.7.5.27.
SHOW FUNCTION STATUS [LIKE 'Этот запрос подобенpattern
' | WHEREexpr
]
SHOW
PROCEDURE STATUS
, но для сохраненных функций. См.
раздел 14.7.5.28.
SHOW GRANTS [FORЭтот запрос выводит на экран запрос или запросыuser
[USINGuser
[,user
] ...]]
GRANT
, которые должны быть сделаны, чтобы дублировать
привилегии, которые предоставляют учетной записи пользователя MySQL.
SHOW GRANTS
требует привилегии
SELECT
для базы данных
mysql
, кроме просмотра привилегии для текущего пользователя.
Чтобы назвать учетную запись, используйте тот же самый формат, что в
GRANT
, например,
'jeffrey'@'localhost'
. Если Вы определяете только часть имени
пользователя имени учетной записи, часть имени хоста
'%'
. См. раздел 14.7.1.6.
mysql> SHOW GRANTS FOR 'root'@'localhost'; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+Чтобы вывести на экран привилегии, предоставленные учетной записи, которую Вы используете, чтобы соединиться с сервером, Вы можете использовать любой из следующих запросов:
SHOW GRANTS; SHOW GRANTS FOR CURRENT_USER; SHOW GRANTS FOR CURRENT_USER();Если
SHOW GRANTS FOR CURRENT_USER
(или любой из эквивалентных
синтаксисов), используется в DEFINER
, например,
в пределах хранимой процедуры, которая определена с
SQL SECURITY DEFINER
), выведенные на экран привилегии
являются таковыми из definer, а не invoker.
С USING
SHOW GRANTS
позволяет Вам исследовать привилегии, связанные с ролями для
пользователя. Каждую роль, названную в пункте,
нужно предоставить пользователю.
Если Вы не выводите на экран информацию для своей собственной учетной
записи, USING
требует привилегию
SUPER
.
Предположите, что пользователю u1
назначены роли
r1
и r2
:
CREATE ROLE 'r1', 'r2'; GRANT SELECT ON db1.* TO 'r1'; GRANT INSERT, UPDATE, DELETE ON db1.* TO 'r2'; CREATE USER 'u1'@'localhost' IDENTIFIED BY 'u1pass'; GRANT 'r1', 'r2' TO 'u1'@'localhost';
SHOW GRANTS
без
USING
показывает предоставленные роли:
mysql> SHOW GRANTS FOR 'u1'@'localhost'; +---------------------------------------------+ | Grants for u1@localhost | +---------------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`localhost` | | GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost` | +---------------------------------------------+Добавление
USING
заставляет запрос также выводить на экран
привилегии, связанные с каждой названной ролью:
mysql> SHOW GRANTS FOR 'u1'@'localhost' USING 'r1'; +---------------------------------------------+ | Grants for u1@localhost | +---------------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`localhost` | | GRANT SELECT ON `db1`.* TO `u1`@`localhost` | | GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost` | +---------------------------------------------+ mysql> SHOW GRANTS FOR 'u1'@'localhost' USING 'r2'; +-------------------------------------------------------------+ | Grants for u1@localhost | +-------------------------------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`localhost` | | GRANT INSERT, UPDATE, DELETE ON `db1`.* TO `u1`@`localhost` | | GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost` | +-------------------------------------------------------------+ mysql> SHOW GRANTS FOR 'u1'@'localhost' USING 'r1', 'r2'; +---------------------------------------------------------------------+ | Grants for u1@localhost | +---------------------------------------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`localhost` | | GRANT SELECT, INSERT, UPDATE, DELETE ON `db1`.* TO `u1`@`localhost` | | GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost` | +---------------------------------------------------------------------+
SHOW GRANTS
покажет
только привилегии, предоставленные явно названной учетной записи. Другие
привилегии, которые могли бы быть доступными учетной записи, не выведены на
экран. Например, если анонимная учетная запись существует, названная учетная
запись могла бы быть в состоянии использовать свои привилегии, но
SHOW GRANTS
не
будет их показывать.
Чтобы вывести на экран информацию не о привилегиях для учетных записей
MySQL, используйте SHOW CREATE USER
, см. раздел 14.7.5.12.
SHOW {INDEX | INDEXES | KEYS} {FROM | IN}tbl_name
[{FROM | IN}db_name
] [WHEREexpr
]
SHOW INDEX
возвращает индексную
информацию. Формат напоминает формат SQLStatistics
в ODBC.
Это запрос требует некоторой привилегии для любого столбца в таблице.
SHOW INDEX
возвращает следующие поля:
Table
Имя таблицы.
Non_unique
0, если индексирование не может содержать дубликаты, 1, если может.
Key_name
Название индекса. Если индексирование является первичным ключом,
имя всегда PRIMARY
.
Seq_in_index
Порядковый номер столбца в индексировании, начиная с 1.
Column_name
Имя столбца.
Collation
Как столбец сортирован в индексировании. В MySQL у этого могут быть
значения A
(Ascending) или NULL
(не сортирован).
Cardinality
Оценка числа уникальных значений в индексировании. Это обновлено
ANALYZE TABLE
или
myisamchk -a
. Cardinality
посчитан, основываясь на статистике,
сохраненной как целые числа, таким образом, значение не обязательно точно
даже для маленьких таблиц. Чем выше количество элементов, тем больше шанс,
что MySQL использует индексирование, делая соединения.
Sub_part
Префикс индекса. Число индексированных символов, если
столбец только частично индексирован, NULL
,
если весь столбец индексирован.
Пределы префикса измерены в байтах, тогда как длина префикса в
CREATE TABLE
,
ALTER TABLE
и
CREATE INDEX
интерпретируется как число символов для недвоичных строковых типов
(CHAR
,
VARCHAR
,
TEXT
)
и число байт для двоичных строковых типов
(BINARY
,
VARBINARY
,
BLOB
).
Примите это во внимание, определяя длину префикса для недвоичного строкового
столбца, который использует многобайтовый набор символов.
См. раздел 14.1.12.
Packed
Указывает, как ключ упакован. NULL
, если никак.
Null
YES
, если столбец может содержать значения
NULL
, ''
, если нет.
Index_type
Используемый метод индекса (BTREE
,
FULLTEXT
, HASH
, RTREE
).
Comment
Информация об индексировании, не описанная в его собственном столбце,
такая как disabled
, если индекс выключен.
Index_comment
Любой комментарий с атрибутом COMMENT
,
когда индексирование создавалось.
Visible
Видимо ли индексирование оптимизатору. См. раздел 9.3.10.
Вы можете использовать
db_name
.tbl_name
как альтернативу
. Эти два запросы эквивалентны:
tbl_name
FROM
db_name
SHOW INDEX FROM mytable FROM mydb; SHOW INDEX FROM mydb.mytable;
WHERE
может быть дан, чтобы выбрать строки, используя более
общие условия, как обсуждено в
раздел 22.31.
Вы можете также перечислить индексы таблицы с
mysqlshow -k
db_name
tbl_name
.
SHOW MASTER STATUSЭтот запрос обеспечивает информацию о статусе двоичных файлов системного журнала ведущего устройства. Это требует любой привилегии
SUPER
или
REPLICATION CLIENT
.
Пример:
mysql> SHOW MASTER STATUS\G *************************** 1. row *************************** File: master-bin.000002 Position: 1307 Binlog_Do_DB: test Binlog_Ignore_DB: manual, mysql Executed_Gtid_Set: 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5 1 row in set (0.00 sec)Когда глобальные операционные ID используются,
Executed_Gtid_Set
показывает набор GTID
для транзакций, которые были выполнены на ведущем устройстве. Это то же
самое, как значение
gtid_executed
на этом сервере, так же как значение
Executed_Gtid_Set
в выводе
SHOW SLAVE STATUS
на этом сервере.
SHOW OPEN TABLES [{FROM | IN}db_name
] [LIKE 'pattern
' | WHEREexpr
]
SHOW OPEN TABLES
перечисляет не-TEMPORARY
таблицы, которые в настоящее время
открыты в табличном кэше. См. раздел
9.4.3.1. FROM
, если есть, ограничивает таблицы
существующими в db_name
.
LIKE
, если есть,
указывает, которые имена таблиц соответствуют. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в разделе 22.31.
SHOW OPEN TABLES
имеет следующие столбцы:
Database
База данных, содержащая таблицу.
Table
Имя таблицы.
In_use
Число табличных блокировок или запросов блокировки для таблицы. Например,
если один клиент приобретает блокировку таблицы через
LOCK TABLE t1 WRITE
, In_use
1.
Если другой клиент командует LOCK TABLE t1 WRITE
в то время как таблица остается заблокированной, клиент заблокирует ожидание
блокировки, но запрос блокировки посчитан, и In_use
2.
Если количество ноль, таблица открыта, но в настоящее время не используется.
In_use
также увеличен
HANDLER ... OPEN
и уменьшен
HANDLER ... CLOSE
.
Name_locked
Заблокировано ли имя таблицы. Блокировка имени используется для таких операций, как удаление или переименование таблиц.
Если у Вас нет никаких привилегий для таблицы, она не показана в выводе
SHOW OPEN TABLES
.
SHOW PLUGINS
SHOW PLUGINS
показывает
информацию о плагинах сервера. Эта информация также доступна в таблице
INFORMATION_SCHEMA.PLUGINS
, см.
раздел 22.15.
Пример вывода SHOW PLUGINS
:
mysql> SHOW PLUGINS\G *************************** 1. row *************************** Name: binlog Status: ACTIVE Type: STORAGE ENGINE Library: NULL License: GPL *************************** 2. row *************************** Name: CSV Status: ACTIVE Type: STORAGE ENGINE Library: NULL License: GPL *************************** 3. row *************************** Name: MEMORY Status: ACTIVE Type: STORAGE ENGINE Library: NULL License: GPL *************************** 4. row *************************** Name: MyISAM Status: ACTIVE Type: STORAGE ENGINE Library: NULL License: GPL ...Столбцы вывода
SHOW PLUGINS
:
Name
: Имя плагина.
Status
: Статус плагина, одно из
ACTIVE
, INACTIVE
,
DISABLED
или DELETED
.Type
: Тип плагина, одно из STORAGE ENGINE
,
INFORMATION_SCHEMA
или AUTHENTICATION
.Library
: Название совместно используемого файла библиотеки
плагина. Это имя, используемое, чтобы обратиться к файлу в запросах вроде
INSTALL PLUGIN
и
UNINSTALL PLUGIN
.
Этот файл расположен в каталоге, названном переменной
plugin_dir
.
Если имя библиотеки NULL
, плагин собран в сервер и не может быть
удален UNINSTALL PLUGIN
.
License
: Как плагин лицензируется, например,
GPL
.Для плагинов, установленных с
INSTALL PLUGIN
, Name
и Library
также зарегистрированы в таблице mysql.plugin
.
Для информации о структурах данных, которые формируют информацию,
выведенную на экран SHOW PLUGINS
, см. раздел 26.2.
SHOW PRIVILEGES
SHOW PRIVILEGES
показывает
список системных привилегий, которые сервер MySQL поддерживает. Точный список
привилегий зависит от версии Вашего сервера.
mysql> SHOW PRIVILEGES\G *************************** 1. row *************************** Privilege: Alter Context: Tables Comment: To alter the table *************************** 2. row *************************** Privilege: Alter routine Context: Functions,Procedures Comment: To alter or drop stored functions/procedures *************************** 3. row *************************** Privilege: Create Context: Databases,Tables,Indexes Comment: To create new databases and tables *************************** 4. row *************************** Privilege: Create routine Context: Databases Comment: To use CREATE FUNCTION/PROCEDURE *************************** 5. row *************************** Privilege: Create temporary tables Context: Databases Comment: To use CREATE TEMPORARY TABLE ...Привилегии, принадлежащие определенному пользователю, выведены на экран
SHOW GRANTS
, см.
раздел 14.7.5.21.
SHOW PROCEDURE CODE proc_name
Этот запрос расширение MySQL, которое доступно только для серверов, которые
были созданы с поддержкой отладки. Это выводит на экран представление
внутреннего выполнения названной хранимой процедуры. Подобный запрос
SHOW FUNCTION CODE
,
показывает информацию о сохраненных функциях (см.
раздел 14.7.5.19).
Чтобы использовать запрос, Вы должны быть владельцем подпрограммы или
иметь привилегию SELECT
на таблице mysql.proc
.
Если названная подпрограмма доступна, запрос производит набор результатов.
Каждая строка в наборе результатов соответствует одной
инструкции в подпрограмме. Первый столбец
Pos
, который является порядковым числом, начинающимся с 0.
Второй столбец Instruction
содержит запрос SQL (обычно
измененный от первоисточника) или директиву, у которой есть значение только
в обработчике сохраненной подпрограммы.
mysql> DELIMITER // mysql> CREATE PROCEDURE p1 () -> BEGIN -> DECLARE fanta INT DEFAULT 55; -> DROP TABLE t2; -> LOOP -> INSERT INTO t3 VALUES (fanta); -> END LOOP; -> END// Query OK, 0 rows affected (0.00 sec) mysql> SHOW PROCEDURE CODE p1// +-----+----------------------------------------+ | Pos | Instruction | +-----+----------------------------------------+ | 0 | set fanta@0 55 | | 1 | stmt 9 "DROP TABLE t2" | | 2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" | | 3 | jump 2 | +-----+----------------------------------------+ 4 rows in set (0.00 sec)В этом примере невыполняемые запросы
BEGIN
и END
исчезли, и для DECLARE variable_name
появляется только выполнимая часть (часть, где значение по умолчанию
назначено). Для каждого запроса, который взят из источника, есть кодовое
слово stmt
сопровождаемое типом (9 DROP
, 5
INSERT
). Заключительная строка
содержит инструкцию jump 2
со
значением GOTO instruction #2
.
SHOW PROCEDURE STATUS [LIKE 'Этот запрос расширение MySQL. Это возвращает характеристики хранимой процедуры, такие как база данных, имя, тип, создатель, даты создания и модификации и информация о наборе символов. Подобный запрос,pattern
' | WHEREexpr
]
SHOW FUNCTION STATUS
,
покажет информацию о сохраненных функциях (см.
раздел 14.7.5.20).
LIKE
, если есть,
указывает, которые имена процедур или функций соответствуют.
WHERE
может быть дан, чтобы выбрать строки, используя более
общие условия, как обсуждено в
разделе 22.31.
mysql> SHOW PROCEDURE STATUS LIKE 'sp1'\G *************************** 1. row *************************** Db: test Name: sp1 Type: PROCEDURE Definer: testuser@localhost Modified: 2004-08-03 15:29:37 Created: 2004-08-03 15:29:37 Security_type: DEFINER Comment: character_set_client: latin1 collation_connection: latin1_swedish_ci Database Collation: latin1_swedish_ci
character_set_client
сессионное значение переменной
character_set_client
, когда подпрограмма создавалась.
collation_connection
сессионное значение переменной
collation_connection
, когда подпрограмма создавалась.
Database Collation
сопоставление базы данных, с
которой связана подпрограмма.
Вы можете также получить информацию о сохраненных подпрограммах из
таблицы ROUTINES
в
INFORMATION_SCHEMA
. См.
раздел 22.19.
SHOW [FULL] PROCESSLIST
SHOW PROCESSLIST
показывает, которые потоки выполняются. Вы можете также получить эту
информацию из таблицы
PROCESSLIST
базы данных INFORMATION_SCHEMA
или
из команды mysqladmin
processlist. Если Вы имеете привилегию
PROCESS
,
Вы можете видеть все потоки. Иначе Вы можете видеть только свои собственные
потоки (то есть, потоки, связанные с учетной записью MySQL, которую Вы
используете). Если Вы не используете FULL
, только первые 100
символов каждого запроса показываются в поле Info
.
Информация о процессе также доступна из таблицы
performance_schema.threads
. Однако, доступ к threads
не требует mutex и оказывает минимальное влияние на работу
сервера.
INFORMATION_SCHEMA.PROCESSLIST
и
SHOW PROCESSLIST
имеют отрицательные исполнительные последствия, потому что они требуют mutex.
threads
также показывает информацию о фоновых потоках, которую
INFORMATION_SCHEMA.PROCESSLIST
и SHOW PROCESSLIST
не выводят. Это означает, что
threads
может использоваться, чтобы контролировать
деятельность, которую другие источники информации потока не могут.
SHOW PROCESSLIST
очень полезен, если Вы получаете сообщение
too many connections
и хотите узнать, что происходит. MySQL резервирует одно дополнительное
соединение, которое будет использоваться учетными записями, которые имеют
привилегию SUPER
,
чтобы гарантировать, что администраторы должны всегда быть в состоянии
соединиться и проверить систему (предполагая, что Вы не даете эту привилегию
всем своим пользователям).
Потоки могут быть уничтожены с помощью
KILL
, см.
раздел 14.7.6.4.
Пример вывода SHOW PROCESSLIST
:
mysql> SHOW FULL PROCESSLIST\G *************************** 1. row *************************** Id: 1 User: system user Host: db: NULL Command: Connect Time: 1030455 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 2 User: system user Host: db: NULL Command: Connect Time: 1004 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 3. row *************************** Id: 3112 User: replikator Host: artemis:2204 db: NULL Command: Binlog Dump Time: 2144 State: Has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 4. row *************************** Id: 3113 User: replikator Host: iconnect2:45781 db: NULL Command: Binlog Dump Time: 2086 State: Has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 5. row *************************** Id: 3123 User: stefan Host: localhost db: apollon Command: Query Time: 0 State: NULL Info: SHOW FULL PROCESSLIST 5 rows in set (0.00 sec)Столбцы, произведенные
SHOW
PROCESSLIST
имеют следующие значения:
Идентификатор соединения. Это ID
столбца из таблицы
INFORMATION_SCHEMA.PROCESSLIST
, столбец PROCESSLIST_ID
из таблицы
threads
в Performance
Schema, он же возвращается функцией
CONNECTION_ID()
.
User
Пользователь MySQL, который сделал запрос. Если это system
user
, он обращается к потоку, порожденному сервером, чтобы обработать
задачи внутренне. Это могло быть вводом/выводом или потоком SQL, используемым
на ведомых устройствах или обработчике отсроченной строки.
unauthenticated user
обращается к потоку, который стал связанным
с соединением клиента, но для которого еще не была сделана аутентификация
пользователя клиента. event_scheduler
обращается к потоку,
который следит за развитием запланированных событий. Для system
user
нет никакого узла, определенного в столбце Host
.
Host
Имя хоста клиента, делающего запрос (за исключением
system user
, где хоста нет).
SHOW PROCESSLIST
сообщает имя хоста для соединений TCP/IP в формате
, чтобы облегчить определять, какой клиент что делает.host_name
:client_port
db
База данных значения по умолчанию, если выбрана, иначе NULL
.
Command
Тип команды, которую поток выполняет. Для описаний команд потока см.
раздел 9.14.
Значение этого столбца соответствует командам
COM_
протокола клиент-сервер и
переменным состояния xxx
Com_
. См.
раздел 6.1.7.xxx
Time
Время в секундах, которое поток был в его текущем состоянии. Для ведомого потока SQL значение указывает число секунд между timestamp последнего копируемого события и реальным временем ведомой машины. См. раздел 19.2.2.
State
Действие или статус, которое указывает на то, что делает поток. См раздел 9.14.
Большинство статусов соответствует очень быстрым операциям. Если поток остается в данном статусе в течение многих секунд, может быть проблема, которая должна быть исследована.
Для SHOW PROCESSLIST
значение State
NULL
.
Info
Запрос, который поток выполняет, или NULL
, если это не
выполняет запрос. Запрос может быть посланным в сервер или внутренним
запросом, если запрос выполняет другие запросы. Например, если
CALL
выполняет хранимую процедуру, которая выполняет
SELECT
, Info
покажет именно SELECT
.
SHOW PROFILE [type
[,type
] ... ] [FOR QUERYn
] [LIMITrow_count
[OFFSEToffset
]]type
: ALL | BLOCK IO | CONTEXT SWITCHES | CPU | IPC | MEMORY | PAGE FAULTS | SOURCE | SWAPS
SHOW PROFILE
и
SHOW PROFILES
выводят на экран информацию о профилировании, которая указывает на
использование ресурсов для запросов, выполненных в течение текущего сеанса.
Эти запросы устарели и будут удалены в будущем выпуске MySQL. Используйте Performance Schema, см. раздел 23.16.1.
Профилированием управляет сессионная переменная
profiling
,
у которой есть значение по умолчанию 0 (OFF
).
Профилирование включено, устанавливая
profiling
в 1 или ON
:
mysql> SET profiling = 1;
SHOW PROFILES
выводит на экран список новых запросов, посланных в сервер. Размером списка
управляет
profiling_history_size
, у которой есть значение по умолчанию 15.
Максимальное значение 100. Установка значения к 0 имеет
эффект отключения профилирования.
Все запросы профилируются, кроме
SHOW PROFILE
и
SHOW PROFILES
,
таким образом, Вы не найдете ни один из этих запросов в списке профиля.
Например, SHOW PROFILING
незаконный запрос, и синтаксическая
ошибка происходит, если Вы пытаетесь выполнить ее, но она
обнаружится в списке профилирования.
SHOW PROFILE
покажет подробную информацию о единственном запросе. Без
FOR QUERY
вывод принадлежит последний раз выполненному запросу. Если
n
FOR QUERY
включен,
n
SHOW PROFILE
покажет
информацию для запроса n
. Значение
n
соответствует значению Query_ID
,
выведенному SHOW PROFILES
.
LIMIT
может быть дан, чтобы ограничить вывод
row_count
row_count
строками. Если
LIMIT
задан, OFFSET
может быть добавлен, чтобы начать вывод со строки
offset
offset
в полном наборе строк.
По умолчанию SHOW PROFILE
отобразит столбцы Status
и Duration
Значения Status
походят на значения State
из
SHOW PROCESSLIST
,
хотя могли бы быть некоторые незначительные различия в интерпретации
этих двух запросов для некоторых значений состояния (см.
раздел 9.14).
type
могут быть определены, чтобы вывести на экран
определенные дополнительные типы информации:
ALL
покажет всю информацию.
BLOCK IO
покажет операции ввода и вывода блока.CONTEXT SWITCHES
покажет добровольные и
ненамеренные переключения контекста.CPU
покажет пользовательские и системные времена
использования центрального процессора.IPC
покажет число сообщений, посланных и полученных.MEMORY
в настоящее время не осуществляется.PAGE FAULTS
покажет главные и
незначительные ошибки страницы.SOURCE
покажет названия функций от исходного кода, вместе с
именем и номером строки файла, в котором происходит функция.SWAPS
покажет число свопов.Профилирование включено для сеанса. Когда сеанс заканчивается, его информация о профилировании потеряна.
mysql> SELECT @@profiling; +-------------+ | @@profiling | +-------------+ | 0 | +-------------+ 1 row in set (0.00 sec) mysql> SET profiling = 1; Query OK, 0 rows affected (0.00 sec) mysql> DROP TABLE IF EXISTS t1; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> CREATE TABLE T1 (id INT); Query OK, 0 rows affected (0.01 sec) mysql> SHOW PROFILES; +----------+----------+--------------------------+ | Query_ID | Duration | Query | +----------+----------+--------------------------+ | 0 | 0.000088 | SET PROFILING = 1 | | 1 | 0.000136 | DROP TABLE IF EXISTS t1 | | 2 | 0.011947 | CREATE TABLE t1 (id INT) | +----------+----------+--------------------------+ 3 rows in set (0.00 sec) mysql> SHOW PROFILE; +----------------------+----------+ | Status | Duration | +----------------------+----------+ | checking permissions | 0.000040 | | creating table | 0.000056 | | After create | 0.011363 | | query end | 0.000375 | | freeing items | 0.000089 | | logging slow query | 0.000019 | | cleaning up | 0.000005 | +----------------------+----------+ 7 rows in set (0.00 sec) mysql> SHOW PROFILE FOR QUERY 1; +--------------------+----------+ | Status | Duration | +--------------------+----------+ | query end | 0.000107 | | freeing items | 0.000008 | | logging slow query | 0.000015 | | cleaning up | 0.000006 | +--------------------+----------+ 4 rows in set (0.00 sec) mysql> SHOW PROFILE CPU FOR QUERY 2; +----------------------+----------+----------+------------+ | Status | Duration | CPU_user | CPU_system | +----------------------+----------+----------+------------+ | checking permissions | 0.000040 | 0.000038 | 0.000002 | | creating table | 0.000056 | 0.000028 | 0.000028 | | After create | 0.011363 | 0.000217 | 0.001571 | | query end | 0.000375 | 0.000013 | 0.000028 | | freeing items | 0.000089 | 0.000010 | 0.000014 | | logging slow query | 0.000019 | 0.000009 | 0.000010 | | cleaning up | 0.000005 | 0.000003 | 0.000002 | +----------------------+----------+----------+------------+ 7 rows in set (0.00 sec)
Профилирование только частично функционально на небольшом количестве
архитектуры. Для значений, которые зависят от системного вызова
getrusage()
, NULL
возвращен на таких системах, как
Windows, которые не поддерживают требование. Кроме того, профилирование для
процесса, а не потока. Это означает, что деятельность по потокам в пределах
сервера, кроме Вашего собственного, может затронуть информацию о
синхронизации, которую Вы видите.
Вы можете также получить информацию профилирования из таблицы
PROFILING
базы данных
INFORMATION_SCHEMA
. См.
раздел 22.17.
Например, следующие запросы приводят к тому же самому результату:
SHOW PROFILE FOR QUERY 2; SELECT STATE, FORMAT(DURATION, 6) AS DURATION FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID = 2 ORDER BY SEQ;
SHOW PROFILES
SHOW PROFILES
вместе с
SHOW PROFILE
показывают
профилирующие информацию, которая указывает на использование ресурсов для
запросов, выполненных в течение текущего сеанса. См.
раздел 14.7.5.30.
SHOW RELAYLOG EVENTS [IN 'Показывает события в журнале реле ведомого устройства. Если Вы не определяетеlog_name
'] [FROMpos
] [LIMIT [offset
,]row_count
]
'log_name
'
, первый журнал реле выведен
на экран. Этот запрос не имеет никакого эффекта на ведущее устройство.
LIMIT
имеет тот же самый синтаксис, что касается
SELECT
, см.
раздел 14.2.9.
SHOW RELAYLOG EVENTS
без LIMIT
может занять много времени и ресурсов, потому что
сервер возвращает клиенту полное содержание журнала реле (включая все
запросы, изменяющие данные, которые были получены ведомым устройством).
Некоторые события, касающиеся установки пользовательских и системных
переменных, не включены в вывод
SHOW RELAYLOG EVENTS
. Чтобы получить полный обзор событий в
пределах журнала реле, используйте
mysqlbinlog.
SHOW SLAVE HOSTSВыводит на экран список ведомых устройств, в настоящее время зарегистрированных в ведущем устройстве.
SHOW SLAVE HOSTS
должен быть выполнен на сервере, который
действует как ведущее устройство. Запрос выводит на экран информацию о
серверах, которые являются или были соединены как ведомые устройства, с
каждой строкой результата, соответствующей одному ведомому серверу,
как показано здесь:
mysql> SHOW SLAVE HOSTS; +------------+-----------+------+-----------+--------------------------------------+ | Server_id | Host | Port | Master_id | Slave_UUID | +------------+-----------+------+-----------+--------------------------------------+ | 192168010 | iconnect2 | 3306 | 192168011 | 14cb6624-7f93-11e0-b2c0-c80aa9429562 | | 1921680101 | athena | 3306 | 192168011 | 07af4990-f41f-11df-a566-7ac56fdaf645 | +------------+-----------+------+-----------+--------------------------------------+
Server_id
: ID ведомого сервера, как указано в файле
опций ведомого сервера или в командной строке с
--server-id=
.value
Host
: Имя хоста ведомого сервера как определено на ведомом
устройстве с помощью
--report-host
. Это может отличаться от машинного
имени в операционной системе.User
: Ведомое имя пользователя сервера как определено на
ведомом устройстве с помощью
--report-user
. Вывод запросов включает этот столбец, только если главный сервер
запущен с опцией
--show-slave-auth-info
.Password
: Ведомый пароль сервера как определен на ведомом
устройстве с помощью
--report-password
. Вывод включает этот столбец, только если
главный сервер запущен с опцией
--show-slave-auth-info
.Port
: Порт на ведущем устройстве, который ведомый сервер
слушает, как определено на ведомом устройстве с опцией
--report-port
.
Ноль в этом столбце означает, что ведомый порт
(--report-port
) не определен вообще.
Master_id
: ID главного сервера, с которого копирует ведомый
сервер. Это ID сервера, на котором выполнен SHOW SLAVE HOSTS
,
таким образом, это же значение перечислено для каждой строки в результате.
Slave_UUID
: ID этого ведомого устройства, как произведено
на ведомом устройстве и записано в файл auto.cnf
.
SHOW SLAVE STATUS [FOR CHANNEL channel
]
Этот запрос обеспечивает информацию о статусе и существенных параметрах
ведомых потоков. Это требует любой привилегии
SUPER
или
REPLICATION CLIENT
.
SHOW SLAVE STATUS
не блокирует. Когда выполнен одновременно с
STOP SLAVE
,
SHOW SLAVE STATUS
возвращается, не ожидая, пока
STOP SLAVE
закончить закрывать ведомый поток SQL или ведомый
поток ввода/вывода (или обоих). Это разрешает использование в контроле и
других приложениях где, получение непосредственного ответа от
SHOW SLAVE STATUS
более важно, чем обеспечение, чтобы это
возвратило последние данные.
Если Вы делаете этот запрос, используя
mysql, Вы можете использовать
\G
, а не точку с запятой, чтобы получить более
читаемое вертикальное расположение:
mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: root Master_Port: 13000 Connect_Retry: 60 Master_Log_File: master-bin.000002 Read_Master_Log_Pos: 1307 Relay_Log_File: slave-relay-bin.000003 Relay_Log_Pos: 1508 Relay_Master_Log_File: master-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1307 Relay_Log_Space: 1858 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: 3e11fa47-71ca-11e1-9e33-c80aa9429562 Master_Info_File: /var/mysqld.2/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 10 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5 Executed_Gtid_Set: 3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5 Auto_Position: 1 Replicate_Rewrite_DB: Channel_name: 1 row in set (0.00 sec)Performance Schema обеспечивает таблицы, которые выставляют информацию о репликации. Это подобно информации, доступной из
SHOW SLAVE STATUS
,
но представленной в табличной форме. Для деталей см.
раздел 23.9.11
.
Следующий список описывает области, возвращенные
SHOW SLAVE STATUS
.
См. раздел 19.1.7.1
.
Slave_IO_State
Копия State
из SHOW
PROCESSLIST
для ведомого потока ввода/вывода. Это говорит Вам, что
делает поток: попытку соединиться с ведущим устройством, ожидание событий от
ведущего устройства, пересоединение с ведущим устройством и так далее. Для
перечисления возможных статусов см.
раздел 9.14.5.
Master_Host
Основной узел, с которым соединено ведомое устройство.
Master_User
Имя пользователя учетной записи для соединения с ведущим устройством.
Master_Port
Порт для соединения с ведущим устройством.
Connect_Retry
Число секунд между повторами соединенияя (значение по умолчанию 60).
Это может быть установлено с помощью
CHANGE MASTER TO
.
Master_Log_File
Название основного двоичного файла системного журнала, из которого в настоящее время читает поток ввода/вывода.
Read_Master_Log_Pos
Позиция в текущем основном двоичном файле системного журнала, до которого читал поток ввода/вывода.
Relay_Log_File
Название файла системного журнала реле, из которого поток SQL в настоящее время читает и выполняет.
Relay_Log_Pos
Позиция в текущем файле системного журнала реле, до которой поток SQL считал и выполнил.
Relay_Master_Log_File
Название основного двоичного файла системного журнала, содержащего новое событие, выполненное потоком SQL.
Slave_IO_Running
Начат ли поток ввода/вывода и соединился ли успешно с ведущим устройством. Внутренне статус этого потока представлен одним из следующих трех значений:
MYSQL_SLAVE_NOT_RUN.
Ведомый поток ввода/вывода не работает. Для этого статуса
Slave_IO_Running
No
.
Slave_IO_Running
зависит от версии сервера как показано в следующей таблице.
Версия MySQL | Slave_IO_Running |
---|---|
4.1 (4.1.13 и ранее), 5.0 (5.0.11 и ранее) | Yes |
4.1 (4.1.14 и позже), 5.0 (5.0.12 и позже) | No |
5.1 (5.1.45 и ранее) | No |
5.1 (5.1.46 и позже), 5.5, 5.6 | Connecting |
Slave_IO_Running
Yes
.Значение Slave_running
соответствует этому значению.
Slave_SQL_Running
Начат ли поток SQL.
Replicate_Do_DB
, Replicate_Ignore_DB
Списки баз данных, которые были определены с опциями
--replicate-do-db
и
--replicate-ignore-db
, если есть.
Replicate_Do_Table
, Replicate_Ignore_Table
,
Replicate_Wild_Do_Table
, Replicate_Wild_Ignore_Table
Списки таблиц, которые были определены с опциями
--replicate-do-table
,
--replicate-ignore-table
,
--replicate-wild-do-table
и
--replicate-wild-ignore-table
, если есть.
Last_Errno
, Last_Error
Эти столбцы псевдонимы для Last_SQL_Errno
и
Last_SQL_Error
.
RESET MASTER
или
RESET SLAVE
сбрасывают значения, показанные в этих столбцах.
Когда ведомый поток SQL получает ошибку, он сообщает об ошибке сначала,
затем останавливает поток SQL. Это означает, что есть маленькое окно времени,
во время которого SHOW SLAVE STATUS
показывает ненулевое значение для Last_SQL_Errno
даже при том, что Slave_SQL_Running
все еще Yes
.
Skip_Counter
Текущее значение
sql_slave_skip_counter
, см.
раздел 14.4.2.5.
Exec_Master_Log_Pos
Позиция в текущем основном двоичном файле системного журнала, которую
поток SQL считал и выполнил, отмечая запуск следующей транзакции или события,
которое будет обработано. Вы можете использовать это значение с
опцией MASTER_LOG_POS
в
CHANGE MASTER TO
, запуская новое ведомое устройство с
существующего ведомого устройства, чтобы новое ведомое устройство читало с
этого пункта. Координаты, данные (Relay_Master_Log_File
,
Exec_Master_Log_Pos
) в двоичном журнале ведущего устройства
соответствуют координатам, данным (Relay_Log_File
,
Relay_Log_Pos
) в журнале реле.
Несогласованности в последовательности транзакций от журнала реле, которые
были выполнены, могут заставить это значение быть
нижней меткой. Другими словами, транзакции,
появляющиеся перед позицией, как гарантируют, переданы, но транзакции после
позиции, возможно, переданы или нет. Если эти промежутки должны быть
исправлены, надо использовать
START SLAVE UNTIL SQL_AFTER_MTS_GAPS
. См.
раздел 19.4.1.34.
Relay_Log_Space
Полный объединенный размер всех существующих файлов системного журнала реле.
Until_Condition
, Until_Log_File
,
Until_Log_Pos
Значения, определенные в UNTIL
в
START SLAVE
.
Until_Condition
имеет эти значения:
None
, если нет UNTIL
.
Master
, если ведомое устройство читает до данной позиции в
двоичном журнале ведущего устройства.Relay
, если ведомое устройство читает до данной
позиции в журнале реле.SQL_BEFORE_GTIDS
, если ведомый поток SQL обрабатывает
транзакции, пока он не достиг первой транзакции, GTID которой
перечислен в gtid_set
.SQL_AFTER_GTIDS
, если ведомые потоки обрабатывают все
транзакции до последней транзакции в gtid_set
, которая
была обработана обоими потоками.SQL_AFTER_MTS_GAPS
,
если потоки SQL мультипоточного ведомого устройства работают, пока больше
промежутков не найдено в журнале реле.Until_Log_File
и Until_Log_Pos
указывают на имя файла системного журнала и позицию, которые определяют
координаты, в которых поток SQL прекращает выполнять.
См. раздел 14.4.2.6.
Master_SSL_Allowed
, Master_SSL_CA_File
,
Master_SSL_CA_Path
, Master_SSL_Cert
,
Master_SSL_Cipher
, Master_SSL_CRL_File
,
Master_SSL_CRL_Path
, Master_SSL_Key
,
Master_SSL_Verify_Server_Cert
Эти области показывают параметры SSL, используемые ведомым устройством, чтобы соединиться с ведущим устройством, если есть.
Master_SSL_Allowed
имеет эти значения:
Yes
, если соединение SSL с
ведущим устройством разрешено.
No
, если соединение SSL с ведущим устройством не разрешено.
Ignored
, если соединение SSL разрешено, но у ведомого
сервера нет включенной поддержки SSL.Значения других SSL-областей соответствуют значениям
MASTER_SSL_CA
, MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
, MASTER_SSL_CIPHER
,
MASTER_SSL_CRL
, MASTER_SSL_CRLPATH
,
MASTER_SSL_KEY
и MASTER_SSL_VERIFY_SERVER_CERT
в
CHANGE MASTER TO
, см.
раздел 14.4.2.1.
Seconds_Behind_Master
Эта область признак того, как работает ведомое устройство:
Когда ведомое устройство активно обрабатывает обновления, эта область показывает различие между потоком timestamp на ведомом устройстве и оригинальным timestamp в системе ведущего устройства для события, в настоящее время обрабатываемого на ведомом устройстве.
В основном, эта область измеряет разницу во времени в секундах между
ведомым потоком SQL и ведомым потоком ввода/вывода. Если сетевое соединение
между ведущим устройством и ведомым устройством быстрое, ведомый поток
ввода/вывода очень близко к ведущему устройству, таким образом, эта область
хорошее приближение того, как отстает ведомый поток SQL по сравнению с
ведущим устройством. Если сеть является медленной, это не
не хорошее приближение, ведомый поток SQL может
довольно часто столкнуться с медленным чтением ведомого потока ввода/вывода,
таким образом, Seconds_Behind_Master
часто показывает значение
0, даже если поток ввода/вывода отстает по сравнению с ведущим устройством.
Другими словами, этот столбец полезен только для быстрых сетей
.
Это вычисление разницы во времени работает, даже если у ведущего устройства и ведомого устройства нет идентичных часов, при условии, что различие, вычисленное, когда ведомый поток ввода/вывода запускается, остается постоянным с тех пор.
В MySQL 8.0 эта область NULL
(не определена или неизвестна),
если ведомый поток SQL не работает, или если поток SQL потребил весь журнал
реле, и ведомый поток ввода/вывода не работает. В более старых версиях MySQL
эта область была NULL
, если ведомый поток SQL или ведомый поток
ввода/вывода не работали или не были соединены с ведущим устройством. Если
поток ввода/вывода работает, но журнал реле исчерпан,
Seconds_Behind_Master
установлен в 0.
Seconds_Behind_Master
основано на timestamp, сохраненном в
событиях, которые сохранены через репликацию.
Это означает, что, если ведущее устройство
M1 самостоятельно ведомое устройство M0, у любого события из двоичного
журнала M0, которое происходит из двоичного журнала M0, есть timestamp M0 для
того события. Это позволяет MySQL копировать
TIMESTAMP
нормально.
Однако, проблема для Seconds_Behind_Master
, если M1 также
получает прямые обновления от клиентов,
Seconds_Behind_Master
беспорядочно колеблется, потому что иногда
последнее событие в M1 происходит из M0, а иногда является результатом
прямого обновления на M1.
Используя мультипоточное ведомое устройство, Вы должны иметь в виду, что
это значение основано на Exec_Master_Log_Pos
и, возможно, не
отражает позицию последней переданной транзакции.
Last_IO_Errno
, Last_IO_Error
Код ошибки и сообщение об ошибке, которая заставила поток ввода/вывода
останавливаться. Код ошибки 0 и сообщение пустой строки не означают
нет ошибки. Если Last_IO_Error
не пусто, ошибочные значения также появляются в журнале
ошибок ведомого устройства.
Информация об ошибке ввода/вывода включает timestamp, показывающий,
когда ошибка потока ввода/вывода произошла. Этот timestamp использует формат
YYMMDD HH:MM:SS
и появляется в Last_SQL_Error_Timestamp
.
RESET MASTER
или
RESET SLAVE
сбрасывают значения, показанные в этих столбцах.
Last_SQL_Errno
, Last_SQL_Error
Код ошибки и сообщение об ошибке, которая заставила поток SQL
останавливаться. Код ошибки 0 и сообщение пустой строки не означают
нет ошибки. Если Last_SQL_Error
не пусто, ошибочные значения также появляются в журнале
ошибок ведомого устройства.
Если ведомое устройство является мультипоточным, поток SQL это
координатор для рабочих потоков. В этом случае
Last_SQL_Error
показывает точное значение столбца
Last_Error_Message
в таблице Performance Schema
replication_applier_status_by_coordinator
.
Значение поля изменено, чтобы предположить, что может быть больше
отказов в других рабочих потоках, которые могут быть замечены в таблице
replication_applier_status_by_worker
,
которая показывает каждое состояние потока. Если та таблица недоступна,
ведомый журнал ошибок может использоваться. Журнал или таблица
replication_applier_status_by_worker
должны также использоваться, чтобы узнать больше об отказе, показанном
SHOW SLAVE STATUS
или таблицей координатора.
Информация об ошибке SQL включает timestamp, показывающий, когда новая
ошибка потока SQL произошла. Этот timestamp использует формат
YYMMDD HH:MM:SS
и появляется в столбце
Last_SQL_Error_Timestamp
.
RESET MASTER
или
RESET SLAVE
сбрасывают значения, показанные в этих столбцах.
В MySQL 8.0 все коды ошибки и сообщения, выведенные на экран в
Last_SQL_Errno
и Last_SQL_Error
соответствуют ошибочным значениям, перечисленным в
разделе B.3. Это было не всегда
истиной в предыдущих версиях (Bug #11760365, Bug #52768).
Replicate_Ignore_Server_Ids
В MySQL 8.0 Вы устанавливаете ведомое устройство, чтобы проигнорировать
события от 0 или больше ведущих устройств, использующих опцию
IGNORE_SERVER_IDS
в
CHANGE MASTER TO
.
По умолчанию это пусто и обычно изменяется только, используя круговую или
другую мультиосновную установку репликации. Сообщение, показанное для
Replicate_Ignore_Server_Ids
, если не пустое,
состоит из разграниченного запятыми списка из одного или более чисел,
указывающих на ID серверов, которые будут проигнорированы. Например:
Replicate_Ignore_Server_Ids: 2, 6, 9
Ignored_server_ids
также показывает ID
сервера, которые будут проигнорированы, но разделенный пробелами список,
которому предшествует общее количество ID
серверов, которые будут проигнорированы. Например, если
CHANGE MASTER TO
содержит опцию IGNORE_SERVER_IDS = (2,6,9)
,
это означает игнорировать ведущие устройства, имеющие ID 2, 6 или 9,
как показано здесь:
Ignored_server_ids: 3, 2, 6, 9Первое число (в этом случае
3
) показывает
число проигнорированных ID.
Replicate_Ignore_Server_Ids
фильтрация выполнена потоком ввода/вывода, а не потоком SQL, что означает,
что события, которые отфильтрованы, не записаны в журнал реле. Это отличается
от мер фильтрации, предпринятых параметрами сервера вроде
--replicate-do-table
, которые относятся к потоку SQL.
Master_Server_Id
server_id
от ведущего устройства.
Master_UUID
server_uuid
от ведущего устройства.
Master_Info_File
Местоположение файла master.info
.
SQL_Delay
Число секунд, которые ведомое устройство должно изолировать ведущее устройство.
SQL_Remaining_Delay
Когда Slave_SQL_Running_State
=
Waiting until MASTER_DELAY seconds after master executed event
,
эта область содержит число оставшихся секунд задержки.
В других случаях эта область NULL
.
Slave_SQL_Running_State
Статус потока SQL (аналогичн Slave_IO_State
). Идентично
State
потока SQL в SHOW
PROCESSLIST
. раздел
9.14.6 перечисляет возможные статусы.
Master_Retry_Count
Сколько раз ведомое устройство может попытаться повторно соединиться с
ведущим устройством в случае потерянного соединения. Это значение может быть
установлено, используя опцию MASTER_RETRY_COUNT
в
CHANGE MASTER TO
(предпочтительно) или более старую опцию
--master-retry-count
(все еще поддержана
для обратной совместимости).
Master_Bind
Сетевой интерфейс, с которым связано ведомое устройство связано, если
есть. Это установлено, используя опцию MASTER_BIND
в
CHANGE MASTER TO
.
Last_IO_Error_Timestamp
Метка времени в формате YYMMDD HH:MM:SS
, которая показывает,
когда новая ошибка ввода/вывода имела место.
Last_SQL_Error_Timestamp
Метка времени в формате YYMMDD HH:MM:SS
, которая показывает,
когда последняя ошибка SQL произошла.
Retrieved_Gtid_Set
Набор глобальных операционных ID, соответствующих всем транзакциям, полученных этим ведомым устройством. Пусто, если GTID не используются.
Это набор всех GTID, которые существуют или существовали в журналах реле.
Каждый GTID добавлен как только получен Gtid_log_event
.
Это может заставить частично переданные транзакции включать
свой GTID в набор.
Когда все журналы реле потеряны из-за выполнения
RESET SLAVE
,
CHANGE MASTER TO
или из-за эффектов опции
--relay-log-recovery
, набор очищен. Когда
relay_log_purge = 1
, новейший журнал реле всегда сохраняется, и набор не очищен.
Executed_Gtid_Set
Набор глобальных операционных ID, записанных в двоичном журнале. Это то же
самое, как значение для глобальной системной переменной
gtid_executed
на этом сервере, так же как значение
Executed_Gtid_Set
в выводе
SHOW MASTER STATUS
на этом сервере. Пусто, если GTID если GTIDs не используются.
Auto_Position
1, если автопорзиционирование используется, иначе 0.
Replicate_Rewrite_DB
Replicate_Rewrite_DB
выводит любые правила фильтрации
репликации, которые были определены. Например, если следующее правило
фильтра было установлено:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=((db1,db2), (db3,db4));
Replicate_Rewrite_DB
покажет:
Replicate_Rewrite_DB: (db1,db2),(db3,db4)См. раздел 14.4.2.2.
Channel_name
Канал, который выводится на экран, всегда канал по умолчанию, и больше каналов может быть добавлено. См. раздел 19.2.3.
SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern
' | WHEREexpr
]
Значение
show_compatibility_56
затрагивает информацию и привилегии,
требуемые для запроса, описанного здесь. Для деталей см.
раздел 6.1.5.
SHOW STATUS
обеспечивает информацию о статусе сервера (см.
раздел 6.1.7).
Этот запрос не требует никакой привилегии. Это требует только
способности соединиться с сервером.
Информация о переменной состояния также доступна из этих источников:
Таблицы Performance Schema. См. раздел 23.9.14 .
GLOBAL_STATUS
и SESSION_STATUS
,
см. раздел 22.9.Для SHOW STATUS
LIKE
, если есть,
указывает, которые имена переменных соответствуют. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в разделе 22.31.
SHOW STATUS
принимает
дополнительный параметр GLOBAL
или SESSION
:
С GLOBAL
запрос выводит на экран глобальные значения
состояния. Глобальная переменная состояния может представить состояние для
некоторого аспекта сервера непосредственно (например,
Aborted_connects
) или соединенное состояние по всем соединениям
с MySQL (например, Bytes_received
и Bytes_sent
).
Если у переменной нет никакого глобального значения, значение сеанса
выведено на экран.
SESSION
запрос выводит на экран значения переменной
состояния для текущего соединения. Если у переменной нет никакого значения
сеанса, глобальное значение выведено на экран.
LOCAL
синоним для SESSION
.SESSION
.Контекст для каждой переменной состояния перечислен в разделе 6.1.7.
Каждый вызов SHOW STATUS
использует внутреннюю временную таблицу и постепенно увеличивает глобальное
значение
Created_tmp_tables
.
Частичный вывод показан здесь. Список имен и значений может отличаться для Вашего сервера. Значение каждой переменной дано в разделе 6.1.7.
mysql> SHOW STATUS; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | Aborted_clients | 0 | | Aborted_connects | 0 | | Bytes_received | 155372598 | | Bytes_sent | 1176560426 | | Connections | 30023 | | Created_tmp_disk_tables | 0 | | Created_tmp_tables | 8340 | | Created_tmp_files | 60 | ... | Open_tables | 1 | | Open_files | 2 | | Open_streams | 0 | | Opened_tables | 44600 | | Questions | 2026873 | ... | Table_locks_immediate | 1920382 | | Table_locks_waited | 0 | | Threads_cached | 0 | | Threads_created | 30022 | | Threads_connected | 1 | | Threads_running | 1 | | Uptime | 80380 | +-------------------------+------------+С
LIKE
запрос выводит на
экран только строки для переменных с именами, которые соответствуют образцу:
mysql> SHOW STATUS LIKE 'Key%'; +--------------------+----------+ | Variable_name | Value | +--------------------+----------+ | Key_blocks_used | 14955 | | Key_read_requests | 96854827 | | Key_reads | 162040 | | Key_write_requests | 7589728 | | Key_writes | 3813196 | +--------------------+----------+
SHOW TABLE STATUS [{FROM | IN}db_name
] [LIKE 'pattern
' | WHEREexpr
]
SHOW TABLE STATUS
работает аналогично SHOW TABLES
, но предоставляет большую информацию о каждой не-TEMPORARY
таблице. Вы можете также получить этот список, используя команду
mysqlshow --status
db_name
.
LIKE
, если есть,
указывает, которые имена таблиц соответствуют. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в раздел 22.31.
Этот запрос также выводит на экран информацию о представлениях.
Вывод SHOW TABLE STATUS
имеет такие столбцы:
Name
Название таблицы.
Engine
Механизм хранения для таблицы. См. главу 17.
Version
Эта область не использована.
Row_format
Формат хранения строки (Fixed
,
Dynamic
, Compressed
,
Redundant
, Compact
). Для таблиц MyISAM
Dynamic
соответствует тому, о чем
myisamchk -dvv
сообщает о как Packed
.
Rows
Число строк. Некоторые механизмы хранения, такие как
MyISAM
, сохраните точное количество. Для других механизмов
хранения, таких как InnoDB
, это значение приближенное и может
отличаться от фактического значения на целых 40-50%.
В таких случаях надо использовать SELECT COUNT(*)
, чтобы
получить точное количество.
Значение Rows
NULL
для таблиц в
базе данных INFORMATION_SCHEMA
.
Avg_row_length
Средняя длина строки.
Data_length
Для MyISAM
Data_length
длина файла с данными в байтах.
Для InnoDB
Data_length
приблизительный объем памяти, выделенный для кластеризируемого индекса
в байтах. Определенно, это размер кластеризируемого индекса в страницах,
умноженный на размер страницы InnoDB
.
Обратитесь к примечаниям в конце этого раздела для информации относительно других механизмов хранения.
Max_data_length
Для MyISAM
Max_data_length
максимальная длина файла с данными. Это общее количество байтов данных,
которые могут храниться в таблице, учитывая используемый
размер указателя данных. Не использовано для InnoDB
.
Index_length
Для MyISAM
Index_length
длина
индексного файла в байтах.
Для InnoDB
Index_length
приблизительный объем памяти, выделенный для некластеризируемого индекса в
байтах. Определенно, это сумма страниц некластеризируемого индекса,
умноженная на размер страницы InnoDB
.
Data_free
Число выделенных но не использованных байтов.
Эту информацию также показывают таблицы для InnoDB
(ранее в значении Comment
). Таблицы InnoDB
сообщают о свободном пространстве в табличном пространстве, к которому
принадлежит таблица. Для таблицы, расположенной в совместно используемом
табличном пространстве, это свободное пространство совместно используемого
табличного пространства. Если Вы используете многократные табличные
пространства, и у таблицы есть свое собственное табличное пространство, то
это свободное пространство только для этой таблицы. Свободное пространство
означает число байтов в абсолютно свободных экстентах минус запас прочности.
Даже если свободное пространство выводится на экран как 0, может быть
возможно вставить строки, пока новые экстенты не должны быть выделены.
Для разделенных таблиц это значение только оценка и, возможно, не
абсолютно правильно. Более точный метод получения этой информации в таких
случаях должен запросить таблицу INFORMATION_SCHEMA.PARTITIONS
:
SELECT SUM(DATA_FREE) FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 'mytable';См. раздел 22.14.
Auto_increment
Следующее значение AUTO_INCREMENT
.
Create_time
Когда таблица была составлена.
Update_time
Когда файл с данными обновлялся. Для некоторых механизмов хранения это
значение NULL
. Например, InnoDB
хранит много
таблиц в его системном
табличном пространстве и метка времени файла с данными
не применяются. Даже с режимом
file-per-table с каждой
таблицей InnoDB
в отдельном файле .ibd
,
буфер изменений
может задержать запись файла данных, таким образом, время изменения файла
отличается от времени последней вставки, обновления или удаления. Для
MyISAM
метка времени файла с данными используется, однако, в
Windows timestamp не изменен операциями обновления, таким
образом, значение неточно.
Check_time
Когда таблица была последний раз проверена. Не все механизмы хранения
обновляют значение, в этом случе оно всегда NULL
.
Collation
Набор символов таблицы и сопоставление.
Checksum
Живое значение контрольной суммы (если есть).
Create_options
Дополнительные опции, используемые с
CREATE TABLE
. Оригинальные опции, поставляемые, когда вызван
CREATE TABLE
, сохранены, и
опции здесь могут отличаться от активных табличных настроек и опций.
Comment
Комментарий, используемый, составляя таблицу (или информация относительно того, почему MySQL не смог получить доступ к информации о таблице).
Примечания:
Для таблиц MEMORY
Data_length
,
Max_data_length
и Index_length
это приближенное к фактическому количество выделенной памяти. Алгоритм
распределения резервирует память в большом количестве, чтобы сократить
количество операций распределения.
SHOW TABLE STATUS
NULL
, кроме Name
, которая указывает имя
представления, и Comment
, в которой написано view
.
SHOW [FULL] TABLES [{FROM | IN}db_name
] [LIKE 'pattern
' | WHEREexpr
]
SHOW TABLES
перечисляет
не-TEMPORARY
таблицы в данной базе данных. Вы можете также
получить этот список, используя
mysqlshow db_name
.
LIKE
, если есть,
указывает, которые имена таблиц соответствуют. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в раздел 22.31.
Соответствие LIKE
зависит от установки переменной
lower_case_table_names
.
Этот запрос также перечисляет любые представления в базе данных.
FULL
поддержан таким образом, что
SHOW FULL TABLES
выводит на экран второй столбец. Значения для второго столбца BASE
TABLE
для таблицы и VIEW
для представления.
Если у Вас нет никаких привилегий для базовой таблицы или
представления, объект не показан в выводе
SHOW TABLES
или
mysqlshow db_name.
SHOW TRIGGERS [{FROM | IN}db_name
] [LIKE 'pattern
' | WHEREexpr
]
SHOW TRIGGERS
перечисляет триггеры, в настоящее время определенные для таблиц в базе данных
(базе данных по умолчанию, если нет FROM
).
Этот запрос возвращает результаты только для баз данных и таблиц, для которых
Вы имеете привилегию TRIGGER
. LIKE
, если
есть, указывает, какие имена таблиц (не триггеров!) соответствуют,
и заставляет запрос выводить на экран триггеры для тех таблиц.
WHERE
может быть дан, чтобы выбрать строки, используя более
общие условия, как обсуждено в
разделе 22.31.
Для триггера ins_sum
, определенного в
разделе 21.3,
вывод этого запроса показан здесь:
mysql> SHOW TRIGGERS LIKE 'acc%'\G *************************** 1. row *************************** Trigger: ins_sum Event: INSERT Table: account Statement: SET @sum = @sum + NEW.amount Timing: BEFORE Created: 2013-07-09 10:39:34.96 sql_mode: NO_ENGINE_SUBSTITUTION Definer: me@localhost character_set_client: utf8 collation_connection: utf8_general_ci Database Collation: latin1_swedish_ciСтолбцы вывода
SHOW TRIGGERS
:
Trigger
: Имя триггера.
Event
: Тип работы, которая вызывает активацию триггера.
Значения 'INSERT'
, 'UPDATE'
или
'DELETE'
.Table
: Таблица, для которой определен триггер.Statement
: Запрос, выполненный, когда триггер активируется.
Timing
: Активируется ли триггер прежде или после
инициирующего события. Значения 'BEFORE'
или 'AFTER'
.Created
: Дата и время, когда триггер создавался. Это
TIMESTAMP(2)
(точность до сотых долей секунды).sql_mode
: Режим SQL, когда триггер выполняется.Definer
: Учетная запись пользователя, который создал
триггер, в формате 'user_name
'@'
host_name
'
.character_set_client
: Сессионное значение
character_set_client
, когда триггер создавался.collation_connection
: Сессионное значение
collation_connection
, когда триггер создавался.Database Collation
: Сопоставление базы данных,
с которой связан триггер.Вы можете также получить информацию о триггерах из таблицы
TRIGGERS
в базе данных
INFORMATION_SCHEMA
. См.
раздел 22.27.
SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern
' | WHEREexpr
]
Значение
show_compatibility_56
затрагивает доступную информацию и
привилегии, требуемые для запроса, описанного здесь. Для деталей см. описание
этой переменной в разделе 6.1.5
.
SHOW VARIABLES
показывает значения системных переменных MySQL (см.
раздел 6.1.5).
Этот запрос не требует никакой привилегии. Это требует только
способности соединиться с сервером.
Системная информация о переменной также доступна из этих источников:
Таблицы Performance Schema. См. раздел 23.9.13.
GLOBAL_VARIABLES
и SESSION_VARIABLES
, см. раздел 22.10.Для SHOW VARIABLES
LIKE
, если есть,
указывает, которые имена переменной соответствуют. WHERE
может быть дан, чтобы выбрать строки, используя более общие условия, как
обсуждено в разделе 22.31.
SHOW VARIABLES
принимает дополнительный модификатор контекста
GLOBAL
или SESSION
:
С GLOBAL
запрос выводит на экран глобальные системные
значения переменной. Это значения, используемые, чтобы инициализировать
соответствующие переменные сеанса для новых соединений с MySQL. Если у
переменной нет никакого глобального значения, никакое значение
не выведено на экран.
SESSION
запрос выводит на экран значения переменных,
которые в действительности используются для текущего соединения. Если у
переменной нет никакого значения сеанса, глобальное значение выведено на
экран. LOCAL
синоним для SESSION
.SESSION
.Контекст для каждой системной переменной перечислен в разделе 6.1.5.
SHOW VARIABLES
подвергается зависимому от версии пределу ширины отображения.
Для переменных с очень длинными значениями, которые не полностью выведены
на экран, надо использовать SELECT
как обходное решение. Например:
SELECT @@GLOBAL.innodb_data_file_path;Большинство системных переменных может быть установлено при запуске сервера (переменные только для чтения, например,
version_comment
это исключения). Многие могут быть изменены во время выполнения с помощью
SET
. См. разделы
6.1.6 и
14.7.4.1.
Частичный вывод показывают здесь. Список имен и значений может отличаться для Вашего сервера. Раздел 6.1.5 описывает значение каждой переменной, а раздел 6.1.1 предоставляет информацию об их настройке.
mysql> SHOW VARIABLES; +-----------------------------------------+---------------------------+ | Variable_name | Value | +-----------------------------------------+---------------------------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | | autocommit | ON | | automatic_sp_privileges | ON | | back_log | 50 | | basedir | /home/jon/bin/mysql-5.5 | | big_tables | OFF | | binlog_cache_size | 32768 | | binlog_direct_non_transactional_updates | OFF | | binlog_format | STATEMENT | | binlog_stmt_cache_size | 32768 | | bulk_insert_buffer_size | 8388608 | ... | max_allowed_packet | 4194304 | | max_binlog_cache_size | 18446744073709547520 | | max_binlog_size | 1073741824 | | max_binlog_stmt_cache_size | 18446744073709547520 | | max_connect_errors | 100 | | max_connections | 151 | | max_delayed_threads | 20 | | max_error_count | 64 | | max_heap_table_size | 16777216 | | max_insert_delayed_threads | 20 | | max_join_size | 18446744073709551615 | ... | thread_handling | one-thread-per-connection | | thread_stack | 262144 | | time_format | %H:%i:%s | | time_zone | SYSTEM | | timestamp | 1316689732 | | tmp_table_size | 16777216 | | tmpdir | /tmp | | transaction_alloc_block_size | 8192 | | transaction_prealloc_size | 4096 | | tx_isolation | REPEATABLE-READ | | unique_checks | ON | | updatable_views_with_limit | YES | | version | 5.5.17-log | | version_comment | Source distribution | | version_compile_machine | x86_64 | | version_compile_os | Linux | | wait_timeout | 28800 | | warning_count | 0 | +-----------------------------------------+---------------------------+С
LIKE
запрос выводит на экран строки только для тех переменных, имена которых
соответствуют образцу. Чтобы получить строку для определенной переменной,
используйте LIKE
:
SHOW VARIABLES LIKE 'max_join_size'; SHOW SESSION VARIABLES LIKE 'max_join_size';Чтобы получить список переменных чьи имена соответствуют образцу, используйте подстановочный символ
%
в
LIKE
:
SHOW VARIABLES LIKE '%size%'; SHOW GLOBAL VARIABLES LIKE '%size%';Подстановочные символы могут использоваться в любой позиции в пределах образца, который будет соответствующим. Строго говоря, потому что
_
это подстановочный знак, который соответствует любому
единственному символу, Вы должны экранировать его как \_
,
чтобы соответствовать этому буквально. Практически это редко необходимо.
SHOW WARNINGS [LIMIT [offset
,]row_count
] SHOW COUNT(*) WARNINGS
SHOW WARNINGS
это
диагностический запрос, отображающий информацию об условиях (ошибки,
предупреждения и примечания), следующих из выполнения запросов в текущем
сеансе. Предупреждения произведены для таких запросов DML, как
INSERT
,
UPDATE
и
LOAD DATA INFILE
, а также для
запросов DDL CREATE TABLE
и
ALTER TABLE
.
LIMIT
имеет тот же самый синтаксис, что касается
SELECT
, см.
раздел 14.2.9.
SHOW WARNINGS
также используется после EXPLAIN
EXTENDED
, чтобы вывести на экран дополнительную информацию,
произведенную EXPLAIN
,
когда используется EXTENDED
, см.
раздел 9.8.3.
SHOW WARNINGS
показывает информацию об условиях, следующих из выполнения нового
недиагностического запроса в текущем сеансе. Если новый запрос привел к
ошибке во время парсинга,
SHOW WARNINGS
показывает получающиеся условия, независимо от типа запроса
(диагностический или недиагностический).
SHOW COUNT(*) WARNINGS
выводит на экран общее количество ошибок, предупреждений и примечаний. Вы
можете также получить это число из переменной
warning_count
:
SHOW COUNT(*) WARNINGS; SELECT @@warning_count;Различие в этих запросах: первый является диагностическим запросом, который не очищает список сообщений. Второй считают недиагностическим и очищает список сообщений, потому что это использует
SELECT
.
Связанный диагностический запрос SHOW
ERRORS
показывает только состояния ошибки (это исключает
предупреждения и примечания), а SHOW
COUNT(*) ERRORS
показывает общее количество ошибок. См.
раздел 14.7.5.17.
GET DIAGNOSTICS
может использоваться, чтобы исследовать информацию на отдельные условия. См.
раздел 14.6.7.3.
Вот простой пример, который показывает предупреждения преобразования
данных для INSERT
:
mysql> CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4)); Query OK, 0 rows affected (0.05 sec) mysql> INSERT INTO t1 VALUES(10,'mysql'), (NULL,'test'), (300,'xyz'); Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 1 *************************** 2. row *************************** Level: Warning Code: 1048 Message: Column 'a' cannot be null *************************** 3. row *************************** Level: Warning Code: 1264 Message: Out of range value for column 'a' at row 3 3 rows in set (0.00 sec)
max_error_count
управляет максимальным количеством ошибок, предупреждений и сообщений
примечания, для которых сервер хранит информацию, и таким образом число
сообщений, которые покажет SHOW
WARNINGS
. Чтобы изменить число сообщений, которое сервер может
сохранить, измените значение
max_error_count
. По умолчанию 64.
max_error_count
контролирует сколько сообщений хранится, а не сколько посчитано.
Значение warning_count
не ограничено
max_error_count
, даже если число произведенных сообщений превышает
max_error_count
.
Следующий пример демонстрирует это. ALTER
TABLE
производит три предупреждающих сообщения (строгий режим SQL
отключен для примера, чтобы препятствовать ошибке после проблемы однократного
преобразования). Только одно сообщение хранится и выведено на экран потому,
что max_error_count
была установлена в 1, но все три посчитаны (как показано значением
warning_count
):
mysql> SHOW VARIABLES LIKE 'max_error_count'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_error_count | 64 | +-----------------+-------+ 1 row in set (0.00 sec) mysql> SET max_error_count=1, sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE t1 MODIFY b CHAR; Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql> SHOW WARNINGS; +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT @@warning_count; +-----------------+ | @@warning_count | +-----------------+ | 3 | +-----------------+ 1 row in set (0.01 sec)Чтобы отключить хранение сообщений, установите
max_error_count
в 0. В этом случае
warning_count
все еще указывает, сколько предупреждений произошло,
но сообщения не хранятся и не могут быть выведены на экран.
sql_notes
управляет, увеличивается ли счетчик сообщений
warning_count
и
хранит ли их сервер. По умолчанию
sql_notes
= 1,
но если установлено в 0, примечания не увеличивают
warning_count
и сервер не хранит их:
mysql> SET sql_notes = 1; mysql> DROP TABLE IF EXISTS test.no_such_table; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS; +-------+------+------------------------------------+ | Level | Code | Message | +-------+------+------------------------------------+ | Note | 1051 | Unknown table 'test.no_such_table' | +-------+------+------------------------------------+ 1 row in set (0.00 sec) mysql> SET sql_notes = 0; mysql> DROP TABLE IF EXISTS test.no_such_table; Query OK, 0 rows affected (0.00 sec) mysql> SHOW WARNINGS; Empty set (0.00 sec)Сервер MySQL посылает каждому клиенту количество, указывающее на общее количество ошибок, предупреждений и примечаний, следующих из нового запроса, выполненного клиентом. Из C API это значение может быть получено вызовом
mysql_warning_count()
. См. раздел 25.8.7.77.
В mysql
Вы можете включить и отключить автоматическое отображение
предупреждений, используя соответственно команды
warnings
и nowarning
или их сокращения
\W
и \w
(см.
раздел 5.5.1.2):
mysql> \W Show warnings enabled. mysql> SELECT 1/0; +------+ | 1/0 | +------+ | NULL | +------+ 1 row in set, 1 warning (0.03 sec) Warning (Code 1365): Division by 0 mysql> \w Show warnings disabled.
BINLOG 'str
'
BINLOG
запрос внутреннего пользования. Это произведено
mysqlbinlog
как пригодное для печатания представление определенных событий в
двоичных файлах системного журнала. См.
раздел 5.6.8. Значение 'str
'
это строка в base64, которую сервер расшифровывает, чтобы определить
изменение данных, обозначенное соответствующим событием. Этот запрос требует
привилегию SUPER
.
Это запрос может выполнить только события описания формата и события строки.
CACHE INDEXtbl_index_list
[,tbl_index_list
] ... [PARTITION (partition_list
| ALL)] INkey_cache_name
tbl_index_list
:tbl_name
[[INDEX|KEY] (index_name
[,index_name
] ...)]partition_list
:partition_name
[,partition_name
][, ...]
CACHE INDEX
назначает табличные индексы к определенному ключевому кэшу. Это используется
только для MyISAM
. После назначения индексов, они могут быть
предварительно загружены в кэш при желании с
LOAD INDEX INTO CACHE
.
Следующий запрос назначает индекс таблиц
t1
, t2
и t3
к ключевому кэшу hot_cache
:
mysql> CACHE INDEX t1, t2, t3 IN hot_cache; +---------+--------------------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+--------------------+----------+----------+ | test.t1 | assign_to_keycache | status | OK | | test.t2 | assign_to_keycache | status | OK | | test.t3 | assign_to_keycache | status | OK | +---------+--------------------+----------+----------+
CACHE INDEX
позволяет Вам
определить, что только особый индекс таблицы должен быть назначен на кэш.
Текущее выполнение назначает все индексы таблицы к кэшу, таким образом нет
никакой причины определить что-либо, кроме имени таблицы.
Ключевой кэш, упомянутый в CACHE
INDEX
, может быть создан, устанавливая его размер с запросом
установки параметра или в установках параметров сервера. Например:
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;К ключевым параметрам кэша можно получить доступ как к членам структурированной системной переменной. См. раздел 6.1.6.1.
Ключевой кэш должен существовать прежде, чем Вы сможете назначить индекс к нему:
mysql> CACHE INDEX t1 IN non_existent_cache; ERROR 1284 (HY000): Unknown key cache 'non_existent_cache'По умолчанию индексы таблицы назначены на основной (значение по умолчанию) ключевой кэш, создаваемый при запуске сервера. Когда ключевой кэш разрушен, все индексы, назначенные на него, становятся назначенными на ключевой кэш значения по умолчанию снова.
Назначения действуют на сервер глобально: если один клиент назначает индексирование на данный кэш, этот кэш используется для всех запросов, вовлекающих индексирование, независимо от того, какой клиент их запускает.
В MySQL 8.0 этот запрос также поддержан для разделенных таблиц
MyISAM
. Вы можете назначить один или больше индексов для одного,
нескольких или всех разделов к данному ключевому кэшу.
Например, Вы можете сделать следующее:
CREATE TABLE pt (c1 INT, c2 VARCHAR(50), INDEX i(c1)) ENGINE=MyISAM PARTITION BY HASH(c1) PARTITIONS 4; SET GLOBAL kc_fast.key_buffer_size = 128 * 1024; SET GLOBAL kc_slow.key_buffer_size = 128 * 1024; CACHE INDEX pt PARTITION (p0) IN kc_fast; CACHE INDEX pt PARTITION (p1, p3) IN kc_slow;Предыдущий набор запросов выполняет следующие действия:
Составляет разделенную таблицу с 4 разделами, они
автоматически названы p0
, ..., p3
, в этой таблице
есть индекс i
на столбце c1
.
kc_fast
и kc_slow
.p0
на ключевой кэш
kc_fast
и индекс для разделов p1
и p3
на ключевой кэш kc_slow
, индекс для остающегося раздела
(p2
) использует ключевой кэш сервера по умолчанию.Если Вы хотите вместо этого назначить индекс для всех разделов
в таблице pt
к единственному ключевому кэшу
kc_all
, Вы можете использовать любой из следующих 2 запросов:
CACHE INDEX pt PARTITION (ALL) IN kc_all; CACHE INDEX pt IN kc_all;Эти два запроса эквивалентны. Другими словами, если Вы хотите назначить индекс для всех разделов таблицы к тому же самому ключевому кэшу, тогда
PARTITION (ALL)
опционально.
Когда назначен индекс для многих разделов к ключевому кэшу, разделение не должно быть непрерывным, и Вы не обязаны перечислять имена разделов в любом особом порядке. Индекс для любого раздела, который явно не назначен на ключевой кэш, автоматически используют ключевой кэш по умолчанию сервера.
В MySQL 8.0 индекс предварительно загружен для разделенных таблиц
MyISAM
. См. раздел 14.7.6.5.
FLUSH [NO_WRITE_TO_BINLOG | LOCAL]flush_option
[,flush_option
] ...
FLUSH
имеет несколько различных
форм, которые перезагружают различные внутренние кэши, таблицы потока или
блокировки. Чтобы выполнить FLUSH
,
Вы должны иметь привилегию RELOAD
. Определенные опции потока могли бы потребовать дополнительных
привилегий, как описано позже.
По умолчанию сервер пишет запросы
FLUSH
в двоичный журнал, чтобы они
копировались к ведомым устройствам. Чтобы подавить журналирование, определите
дополнительный параметр NO_WRITE_TO_BINLOG
или
его псевдоним LOCAL
.
FLUSH LOGS
,
FLUSH TABLES WITH READ LOCK
и
FLUSH TABLES
не записаны в двоичный журнал в любом случае,
потому что они вызвали бы проблемы, если копируются к ведомому устройству.
tbl_name
... FOR EXPORT
Сигнал SIGHUP
серверу вызывает
несколько операций, которые подобны различным формам
FLUSH
, см.
раздел 6.1.11.
FLUSH
неявно закрывает
транзакции. См. раздел 14.3.3.
RESET
аналогичен
FLUSH
, см.
раздел 14.7.6.6.
flush_option
может быть любым
из следующих элементов.
DES_KEY_FILE
Перезагружает ключи DES из файла, который был определен с
--des-key-file
при запуске сервера.
HOSTS
Освобождает кэш узла. Вы должны сбросить
кэш узла, если некоторые из Ваших узлов изменяют IP-адрес или если
полуаете сообщение об ошибке
Host '
(см.
раздел B.5.2.5). Когда больше, чем
host_name
' is blockedmax_connect_errors
ошибок происходят последовательно для данного узла, соединяясь с
сервером MySQL, он предполагает, что что-то неправильно и блокирует узел от
дальнейших запросов соединения. Сброс кэша узла включает дальнейшие попытки
соединения с узлом. Значение по умолчанию
max_connect_errors
100. Чтобы избежать этого сообщения об ошибке, запустите сервер с
max_connect_errors
, установленной к большому значению.
[log_type
] LOGS | RELAY
LOGS [ channel_option
]
Без опции log_type
FLUSH LOGS
закрывает
и вновь открывает все файлы системного журнала. Если двоичное журналирование
включено, порядковый номер двоичного файла системного журнала увеличен на 1
относительно предыдущего файла.
FLUSH LOGS
не имеет никакого эффекта на таблицы, используемые
для общего журнала запроса или для медленного журнала запроса (см.
раздел 6.4.1).
С опцией log_type
только указанный тип журнала
сброшен. Опция log_type
:
BINARY
закрывает и вновь открывает двоичные файлы
системного журнала. Если двоичное журналирование включено, порядковый номер
двоичного файла системного журнала увеличен на 1
относительно предыдущего файла.
ENGINE
закрывает и вновь открывает любые журналы
для установленных механизмов хранения. Это вызывает сброс журналов
InnoDB
на диск.ERROR
закрывает и вновь открывает
файл журнала ошибок.GENERAL
закрывает и вновь открывает
общий файл системного журнала запроса.RELAY
закрывает и вновь открывает
системного журнала реле. Если двоичное журналирование включено, порядковый
номер двоичного файла системного журнала
увеличен на 1 относительно предыдущего файла.
FOR CHANNEL
позволяет Вам выбрать, который канал репликации применить к
channel
FLUSH RELAY LOGS
. Если никакой пункт не установлен, и никакие
дополнительные каналы не существуют, запрос относится к каналу по умолчанию и
ведет себя как версии MySQL до 5.7.6. Если много каналов существует, и
никакой пункт не установлен, все каналы сбрасываются.
Выполните FLUSH RELAY LOGS FOR CHANNEL
, чтобы сбросить определенный журнал реле канала ответа. См.
раздел 19.2.3.channel
FOR CHANNEL
может использоваться только с
channel
RELAY LOGS
log_type
.
SLOW
закрывает и вновь открывают медленный файл
системного журнала запроса.OPTIMIZER_COSTS
Перечитывает таблицы модели стоимости так, чтобы оптимизатор начал использовать текущие значения, сохраненные в них. Сервер пишет предупреждение в журнал ошибок для любых непризнанных записей. Для информации об этих таблицах см. раздел 9.9.5. Эта работа затрагивает только сеансы, которые начинаются после сброса. Существующие сеансы продолжают использовать значения, которые были актуальны, когда они начались.
PRIVILEGES
Перезагружает привилегии из таблиц доступа в
базе данных mysql
.
Сервер кэширует в памяти результаты
GRANT
,
CREATE USER
,
CREATE SERVER
и
INSTALL PLUGIN
.
Эта память не освобождена передачей
REVOKE
,
DROP USER
,
DROP SERVER
и
UNINSTALL PLUGIN
,
таким образом, для сервера, который выполняет много запросов, которые
кэшируются, будет увеличение использования памяти.
Эта кэшируемая память может быть освобождена с помощью
FLUSH PRIVILEGES
.
QUERY CACHE
Дефрагментирует кэш запроса, чтобы лучше использовать его память.
FLUSH QUERY CACHE
не удаляет запросов из кэша, в отличие от
FLUSH TABLES
или
RESET QUERY CACHE
.
STATUS
Значение
show_compatibility_56
затрагивает работу этой опции. Для деталей
см. описание этой переменной в
разделе 6.1.5.
Эта опция добавляет, что переменная состояния сеанса текущего потока
оценивает глобальным значением и сбрасывает значения сеансовых переменных к
нолю. Некоторые глобальные переменные могут быть сброшены к нолю также. Это
также сбрасывает счетчики для ключевых кэшей к нолю и устанавливает
Max_used_connections
к текущему числу открытых соединений. Вы должны использовать это
только отлаживая запрос. См. раздел 1.7.
TABLES
FLUSH TABLES
сбрасывает таблицы и, в зависимости от используемой разновидности,
блокировки. Разрешенный синтаксис обсужден позже в этом разделе.
USER_RESOURCES
Сбрасывает все часовые пользовательские ресурсы к нолю. Это включает
клиентов, которые достигли их почасового предела соединения, запроса или
обновляения, чтобы немедленно возобновить деятельность.
FLUSH USER_RESOURCES
не относится к пределу на максимум одновременных соединений.
См. раздел 7.3.5.
mysqladmin
обеспечивает интерфейс командной строки к некоторым операциям потока,
используя такие команды, как flush-hosts
, flush-logs
, flush-privileges
, flush-status
и
flush-tables
. См.
раздел 5.5.2.
Невозможно запустить FLUSH
в пределах сохраненных функций или триггеров. Однако, Вы можете использовать
statements within stored FLUSH
в хранимых процедурах, пока их не вызывают из сохраненных функций или
триггеров. См. раздел C.1
.
FLUSH TABLES
имеет несколько форм, описанных после. Если любая разновидность опции
TABLES
используется в FLUSH
, это должна быть единственная используемая опция.
FLUSH TABLE
синоним для
FLUSH TABLES
.
FLUSH TABLES
Закрывает все открытые таблицы и сбрасывает кэш запроса.
FLUSH TABLES
также удаляет все запросы из кэша запроса, подобно
RESET QUERY CACHE
.
В MySQL 8.0 FLUSH TABLES
не разрешен, когда есть активный запрос
LOCK TABLES ... READ
.
Чтобы сбросить и заблокировать таблицы, надо использовать
FLUSH TABLES
.tbl_name
... WITH READ LOCK
FLUSH TABLES tbl_name
[,
tbl_name
] ...
Со списком из одного или более отделенных запятыми имен таблиц этот запрос
похож на FLUSH TABLES
без имен за исключением того, что сервер сбрасывает
только названные таблицы. Никакая ошибка не происходит, если названная
таблица не существует.
FLUSH TABLES WITH READ LOCK
Закрывает все открытые таблицы и блокирует все таблицы для всех баз данных
с глобальной блокировкой чтения. Это очень удобный способ получить резервные
копии, если у Вас есть файловая система, такая как Veritas или ZFS, которая
может взять снимки в момент времени.
Используйте UNLOCK TABLES
,
чтобы снять блокировку.
FLUSH TABLES WITH READ LOCK
приобретает глобальную блокировку чтения, а не табличные блокировки, таким
образом, это не подвергается тому же самому поведению, как
LOCK TABLES
и
UNLOCK TABLES
относительно табличной блокировки и неявной передачи
UNLOCK TABLES
неявно передает любую активную транзакцию, только если любые таблицы в
настоящее время блокировались с LOCK
TABLES
. Этого не происходит для
UNLOCK TABLES
с
FLUSH TABLES WITH READ LOCK
,
потому что последний запрос не приобретает табличные блокировки.
LOCK TABLES
, как если бы Вы
выполнили UNLOCK TABLES
.
Начало транзакции не выпускает глобальную блокировку чтения, приобретенную с
FLUSH TABLES WITH READ LOCK
.
FLUSH TABLES WITH READ LOCK
не препятствует тому, чтобы сервер вставил строки в таблицы журнала (см.
раздел 6.4.1).
FLUSH TABLES tbl_name
[,
tbl_name
] ... WITH READ LOCK
Это запрос сбрасывает и приобретает блокировки чтения на названных
таблицах. Запрос сначала приобретает исключительные блокировки метаданных
для таблиц, таким образом, он ждет завершения транзакций, у которых эти
таблицы открыты. Тогда запрос сбрасывает таблицы из табличного кэша, вновь
открывает таблицы, приобретает табличные блокировки (как
LOCK TABLES ... READ
)
и понижает блокировки метаданных с исключительных до совместно используемых.
После того, как запрос приобретает блокировки и удаляет блокировки
метаданных, другие сеансы могут читать, но не изменять таблицы.
Поскольку этот запрос приобретает табличные блокировки, Вы должны иметь
привилегию LOCK TABLES
для каждой таблицы, в дополнение к привилегии
RELOAD
, которая нужна,
чтобы использовать любой FLUSH
.
Этот запрос применяется только к существующим базовым таблицам. Если имя
ссылается на базовую таблицу, та таблица используется. Если это обращается к
таблице TEMPORARY
, это проигнорировано. Если имя относится к
представлению, будет ошибка
ER_WRONG_OBJECT
. Иначе происходит ошибка
ER_NO_SUCH_TABLE
.
Используйте UNLOCK TABLES
,
чтобы выпустить блокировки, LOCK TABLES
, чтобы выпустить блокировки и приобрести другие блокировки или
START TRANSACTION
, чтобы
выпустить блокировки и начать новую транзакцию.
Эта разновидность FLUSH
позволяет сбросить и заблокировать
таблицы в единственном запросе. Это обеспечивает обходное решение для
ограничения в MySQL 8.0, что FLUSH TABLES
не разрешен, когда есть активный запрос
LOCK TABLES ... READ
.
Этот запрос не выполняет неявный
UNLOCK TABLES
,
таким образом, будет ошибка, если Вы используете запрос в то время, как есть
любой активный запрос LOCK TABLES
или используйте это во второй раз без снятия приобретенных блокировок.
Если сбрасываемая таблица была открыта с
HANDLER
,
обработчик неявно сбрасывается и теряет свою позицию.
FLUSH TABLES tbl_name
[,
tbl_name
] ... FOR EXPORT
Этот вариант FLUSH TABLES
применим к InnoDB
.
Это гарантирует, что изменения названных таблиц сброшены на диск, чтобы
двоичные табличные копии могли быть сделаны в то время, как сервер работает.
Запрос работает так:
Это приобретает совместно использованные блокировки метаданных для названных таблиц. Запрос блокирован, пока другие сеансы имеют активные транзакции, которые изменили те таблицы или держат табличные блокировки для них. Когда блокировки были приобретены, запрос блокирует транзакции, которые пытаются обновить таблицы, разрешая операции только для чтения.
FOR EXPORT
. Если кто-либо этого не делает, будет ошибка
ER_ILLEGAL_HA
.FOR EXPORT
.FLUSH TABLES ... FOR EXPORT
требует, чтобы Вы имели
привилегию SELECT
для каждой таблицы. Поскольку этот запрос приобретает табличные блокировки,
Вы должны также иметь привилегию
LOCK TABLES
в
дополнение к RELOAD
,
которая нужна для выполнения FLUSH
.
Этот запрос применяется только к существующим базовым таблицам. Если имя
ссылается на базовую таблицу, та таблица используется.
Если это обращается к таблице TEMPORARY
,
это проигнорировано. Если имя относится к представлению, будет ошибка
ER_WRONG_OBJECT
,
иначе будет ошибка
ER_NO_SUCH_TABLE
.
InnoDB
поддерживает FOR EXPORT
для таблиц, у которых есть их собственный файл
.ibd
(то есть, таблицы, которые были составлены с включенной опцией
innodb_file_per_table
). InnoDB
гарантирует, когда регистрирует FOR EXPORT
, что
любые изменения сброшены на диск. Это разрешает сделать
двоичную копию таблицы в то время, как работает FOR EXPORT
,
потому что файл .ibd
транзакционно последователен и может быть
скопирован в то время, как сервер работает. FOR EXPORT
не относится к системным файлам табличного пространства или к таблицам
InnoDB
, у которых есть любые индексы FULLTEXT
.
FLUSH TABLES ...FOR EXPORT
поддержан для
разделенных таблиц InnoDB
.
Когда регистрируется FOR EXPORT
, InnoDB
пишет на диск определенным видам данных, которые обычно хранятся в памяти или
в отдельных дисковых буферах вне файлов табличного пространства. Для каждой
таблицы InnoDB
также производит файл
в том же самом каталоге базы данных, где таблица. Файл table_name
.cfg.cfg
содержит метаданные, чтобы можно было повторно импортировать файлы табличного
пространства позже в тот же самый или другой сервер.
Когда FOR EXPORT
завершается, InnoDB
сбросит
все грязные страницы в
табличные файлы с данными. Любые
буферы изменений слиты до
сброса.В этом пункте таблицы заблокированы и неподвижны: таблицы находятся в
транзакционно последовательном статусе на диске, и Вы можете скопировать
файлы табличного пространства .ibd
вместе с файлами
соответствующими файлами .cfg
, чтобы получить последовательный
снимок тех таблиц.
Для процедуры повторного импорта скопированных табличных данных в MySQL см. раздел 16.7.6.
После того, как Вы закончили с таблицами, надо использовать
UNLOCK TABLES
, чтобы
снять блокировки, LOCK TABLES
,
чтобы снять блокировки и приобрести другие блокировки или
START TRANSACTION
, чтобы
снять блокировки и начать новую транзакцию.
В то время как любой из этих запросов работает в пределах сеанса, попытки
использовать FLUSH TABLES ... FOR
EXPORT
приведут к ошибке:
FLUSH TABLES ... WITH READ LOCK FLUSH TABLES ... FOR EXPORT FLUSH TABLES ... WITH READ LOCK FLUSH TABLES ... FOR EXPORT LOCK TABLES ... READ LOCK TABLES ... WRITE
KILL [CONNECTION | QUERY] processlist_id
Каждое соединение с mysqld
работает в отдельном потоке. Вы можете уничтожить поток
с помощью KILL processlist_id
.
Идентификаторы потока могут быть определены из столбца ID
таблицы
INFORMATION_SCHEMA.PROCESSLIST
, столбца Id
вывода
SHOW PROCESSLIST
и
столбца PROCESSLIST_ID
таблицы Performance Schema
threads
. Значение для
текущего потока возвращено функцией
CONNECTION_ID()
.
KILL
разрешает дополнительный
модификатор CONNECTION
или QUERY
:
KILL CONNECTION
то же самое, как KILL
без
модификаторов: это заканчивает соединение, связанное с данным
processlist_id
, после завершения любого
выполняемого соединением запроса.
KILL QUERY
заканчивает запрос, который соединение в настоящее время выполняет, но
оставляет непосредственно соединение неповрежденным.Если Вы имеете привилегию
PROCESS
, Вы можете видеть все потоки. Если Вы имеете привилегию
SUPER
,
Вы можете уничтожить все потоки и запросы. Иначе Вы можете видеть и
уничтожить только свои собственные потоки и запросы.
Вы можете также использовать команды mysqladmin processlist и mysqladmin kill, чтобы исследовать и уничтожить потоки.
Вы не можете использовать KILL
с
библиотекой Embedded MySQL Server потому, что встроенный сервер просто
работает в потоках приложения. Это не создает собственных потоков соединения.
Когда Вы используете KILL
,
определенный для потока флаг уничтожения установлен. В большинстве случаев
это может занять время для потока, потому что флаг уничтожения проверен
только в определенных интервалах:
Во время SELECT
для
ORDER BY
и GROUP BY
флаг проверен после чтения блока строк.
Если флаг уничтожения установлен, запрос прерван.
ALTER TABLE
, которые
осуществляют табличную копию, проверяют флаг уничтожения периодически
по мере копирования строк, считанных из оригинальной таблицы. Если флаг
уничтожения был установлен, запрос прерван и временная таблица удалена.
KILL
не ожидает подтверждения, но
проверки флага уничтожения прерывают работу в пределах разумно небольшого
количества времени. Прерывание работы, чтобы выполнить любую необходимую
уборку, также занимает время.
UPDATE
или
DELETE
флаг уничтожения проверен после того, как каждый блок считан и после каждой
обновленной или удаленной строки. Если флаг уничтожения установлен, запрос
прерван. Если Вы не используете транзакции, изменения не откатываются.GET_LOCK()
прекращает работу и возвращает NULL
.Locked
), табличная блокировка быстро прервана.Уничтожение REPAIR TABLE
или OPTIMIZE TABLE
на MyISAM
приводит к таблице, которая повреждена и непригодна.
Любые чтения или записи такой таблицы терпят неудачу, пока Вы не
оптимизируете или не восстанавливаете ее снова (без прерывания).
LOAD INDEX INTO CACHEtbl_index_list
[,tbl_index_list
] ...tbl_index_list
:tbl_name
[PARTITION (partition_list
| ALL)] [[INDEX|KEY] (index_name
[,index_name
] ...)] [IGNORE LEAVES]partition_list
:partition_name
[,partition_name
][, ...]
LOAD INDEX INTO CACHE
предварительные загружает табличный индекс в ключевой кэш, на который она
была назначена явным
CACHE INDEX
или в ключевой кэш по умолчанию иначе.
LOAD INDEX INTO CACHE
используется только для MyISAM
. В MySQL 8.0 это также поддержано
для разделенных таблиц MyISAM
, кроме того, индекс на разделенных
таблицах, может быть предварительно загружен для одного, нескольких
или всех разделов.
IGNORE LEAVES
заставляет только блоки для узлов нелиста
индекса быть предварительно загруженными.
IGNORE LEAVES
также поддержан для
разделенных таблиц MyISAM
.
Следующий запрос предварительно загружает узлы (индексные блоки) индекса
для таблиц t1
и t2
:
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES; +---------+--------------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+--------------+----------+----------+ | test.t1 | preload_keys | status | OK | | test.t2 | preload_keys | status | OK | +---------+--------------+----------+----------+Этот запрос предварительно загружает все индексные блоки из
t1
.
Это предварительно загружает только блоки для узлов нелиста t2
.
LOAD INDEX INTO CACHE
позволяет Вам определить, что только особый индекс таблицы должен быть
предварительно загружен. Текущие выполнение грузит все индексы таблицы в кэш,
таким образом, нет никакой причины определить что-либо, кроме имени таблицы.
Возможно предварительно загрузить индекс на определенном разделе
таблицы MyISAM
. Например, следующие 2 запроса предварительно
загружают индекс: первый запрос для раздела p0
таблицы
pt
, второй запрос для разделов p1
и
p3
:
LOAD INDEX INTO CACHE pt PARTITION (p0); LOAD INDEX INTO CACHE pt PARTITION (p1, p3);Предварительно загрузить индексирование для всего разделения в таблице
pt
можно любым из следующих 2 запросов:
LOAD INDEX INTO CACHE pt PARTITION (ALL); LOAD INDEX INTO CACHE pt;Эти два запроса эквивалентны. Другими словами, если Вы хотите предварительно загрузить индексы для всего разделения разделенной таблицы, то
PARTITION (ALL)
опционально.
Когда предварительно загружены индексы для многих разделов, разделение не должно быть непрерывным, и Вы не обязаны перечислять имена разделов в любом особом порядке.
LOAD INDEX INTO CACHE ... IGNORE LEAVES
терпит неудачу, если не все индексы в таблице имеют тот же самый
размер блока. Вы можете определить размеры блока для таблицы при
использовании myisamchk -dv
и проверке столбца Blocksize
.
RESETreset_option
[,reset_option
] ...
RESET
используется, чтобы очистить состояние различных операций сервера.
Вы должны иметь привилегию RELOAD
.
RESET
действует как более сильная
версия FLUSH
, см.
раздел 14.7.6.3.
RESET
неявно закрывает
транзакции. См. раздел 14.3.3.
reset_option
может быть таким:
MASTER
Удаляет все двоичные журналы, перечисленные в индексном файле, сбрасывает двоичной индексный файл журнала к пустому и создает новый двоичной файл системного журнала.
QUERY CACHE
Удаляет все результаты запросов из кэша запроса.
SLAVE
Заставляет ведомое устройство забыть свою позицию в основных двоичных журналах. Также сбрасывает журнал реле, удаляя любые существующие файлы системного журнала реле и начиная новый.
SHUTDOWNЭтот запрос останавливает сервер MySQL. Это требует привилегии
SHUTDOWN
.
SHUTDOWN
обеспечивает
SQL-интерфейс с той же самой функциональностью, как использование команды
mysqladmin shutdown
.
DESCRIBE
и
EXPLAIN
синонимы,
используемые чтобы получить информацию о структуре таблицы или планах
выполнения запроса. Для получения дополнительной информации см. разделы
14.7.5.5 и
14.8.2.
{EXPLAIN | DESCRIBE | DESC}Практическиtbl_name
[col_name
|wild
] {EXPLAIN | DESCRIBE | DESC} [explain_type
] {explainable_stmt
| FOR CONNECTIONconnection_id
}explain_type
: {EXTENDED | PARTITIONS | FORMAT =format_name
}format_name
: {TRADITIONAL | JSON}explainable_stmt
: { SELECT statement | DELETE statement | INSERT statement | REPLACE statement | UPDATE statement}
DESCRIBE
чаще используется, чтобы получить информацию о структуре таблицы, тогда как
EXPLAIN
используется, чтобы получить план выполнения запроса (то есть, объяснение
того, как MySQL выполнил бы запрос). Следующее обсуждение использует
DESCRIBE
и
EXPLAIN
в соответствии с этим использованием, но анализатор MySQL обрабатывает их
как абсолютные синонимы.
DESCRIBE
предоставляет информацию о столбцах в таблице:
mysql> DESCRIBE City; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | Id | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | Country | char(3) | NO | UNI | | | | District | char(20) | YES | MUL | | | | Population | int(11) | NO | | 0 | | +------------+----------+------+-----+---------+----------------+
DESCRIBE
сокразение для
SHOW COLUMNS
.
Эти запросытакже выводят на экран информацию для представлений. Описание для
SHOW COLUMNS
предоставляет больше информации о столбцах вывода. См.
раздел 14.7.5.5.
По умолчанию DESCRIBE
отображает информацию обо всех столбцах в таблице.
col_name
, если есть, задает название столбца в таблице.
В этом случае запрос выводит на экран информацию только для названного
столбца. wild
, если задана, строка образца. Это может
содержать подстановочные символы SQL %
и _
.
В этом случае запрос выводит на экран вывод только для столбцов с именами,
соответствующими строке. Нет никакой потребности помещать строку в пределах
кавычек, если она не содержит пробелы или другие специальные символы.
DESCRIBE
обеспечен для
совместимости с СУБД Oracle.
SHOW CREATE TABLE
,
SHOW TABLE STATUS
и
SHOW INDEX
также предоставляют
информацию о таблицах. См. раздел 14.7.5.
EXPLAIN
предоставляет
информацию о том, как MySQL выполняет запросы:
В MySQL 8.0 разрешены объяснимые запросы для
EXPLAIN
SELECT
,
DELETE
,
INSERT
,
REPLACE
и
UPDATE
.
EXPLAIN
используется с объяснимым запросом, MySQL выводит на экран информацию от
оптимизатора о плане выполнения запросы. Таким образом, MySQL объясняет, как
он обработал бы запрос, включая информацию о том, как к таблицам
присоединяются и в котором порядке. Для информации об использовании
EXPLAIN
, чтобы получить информацию
о плане выполнения см. раздел 9.8.2.
EXPLAIN
используется с
FOR CONNECTION connection_id
вместо объяснимого запроса, это выводит на экран план выполнения относительно
выполнения запросов на названном соединении. См.
раздел 9.8.4.EXPLAIN EXTENDED
может использоваться, чтобы получить дополнительную информацию о плане
выполнения. См. раздел 9.8.3.
Эффект ключевого слова EXTENDED
всегда включает
EXPLAIN
.
EXTENDED
признано для обратной совместимости, но лишнее и
устарело, его использование приводит к предупреждению. Это будет удалено из
EXPLAIN
в будущем выпуске MySQL.
EXPLAIN PARTITIONS
полезно для исследования запросов, вовлекающих разделенные таблицы. См.
раздел 20.3.5.
Эффект ключевого слова PARTITIONS
всегда включает
EXPLAIN
. PARTITIONS
признано для обратной совместимости, но лишнее и устарело, его использование
приводит к предупреждению. Это будет удалено из
EXPLAIN
в будущем выпуске MySQL.
FORMAT
может использоваться, чтобы выбрать выходной
формат. TRADITIONAL
представляет вывод в табличном формате. Это
значение по умолчанию, если нет опции FORMAT
. Формат
JSON
выводит на экран информацию в формате JSON. С
FORMAT = JSON
вывод включает расширенную
информация и сведения о разделении.С помощью EXPLAIN
Вы можете видеть, где Вы должны добавить индекс к таблицам, чтобы запрос
выполнился быстрее при использовании индекса, чтобы найти строки. Вы можете
также использовать EXPLAIN
, чтобы
проверять, присоединяется ли оптимизатор к таблицам в оптимальном порядке.
Чтобы дать подсказку оптимизатору, чтобы использовал порядок соединения,
соответствующий порядку, в котором таблицы называют в
SELECT
, начните запрос с
SELECT STRAIGHT_JOIN
вместо обычного
SELECT
. См.
раздел 14.2.9.
Оптимизатор может иногда предоставлять информацию, дополнительную к
EXPLAIN
.
Однако, формат следа оптимизатора и контент подвержены изменениям между
версиями. Для деталей см.
MySQL Internals: Tracing the Optimizer.
Если у Вас есть проблема с тем, что индекс не используется, когда Вы
полагаете, что он должен быть задействован, выполните
ANALYZE TABLE
, чтобы
обновить табличную статистику, такую как количество элементов ключей, которые
могут затронуть выбор, который делает оптимизатор. См.
раздел 14.7.2.1.
HELP 'search_string
'
HELP
возвращает информацию из
MySQL Reference manual. Его правильное функционирование требует что таблицы
справки в базе данных mysql
были инициализированы с информацией
о теме справки (см. раздел
6.1.10).
HELP
ищет в таблице справки данную
строку поиска и выводит на экран результат поиска.
Строка поиска не является чувствительной к регистру.
Строка поиска может содержать подстановочные символы
%
и _
. У них есть то же самое значение, что
касается соответствующих операций, выполненных с оператором
LIKE
. Например,
HELP 'rep%'
возвращает список тем,
которые начинаются с rep
.
Запрос HELP
понимает несколько
типов строк поиска:
На наиболее общем уровне можно использовать contents
,
чтобы получить список категорий верхнего уровня:
HELP 'contents'
Data Types
, используйте название категории:
HELP 'data types'
ASCII()
или запрос
CREATE TABLE
,
используйте связанное ключевое слово или слова:
HELP 'ascii' HELP 'create table'
Другими словами, строка поиска соответствует категории, темам или
единственной теме. Вы не можете обязательно сказать заранее, возвратит ли
данная строка поиска список элементов или справочную информацию для
единственной темы справки. Однако, Вы можете сказать, какой ответ
HELP
возвращен, исследуя число строк
и столбцов в наборе результатов.
Следующие описания указывают на формы, которые может принять набор
результатов. Вывод для запросов в качестве примера показывают, используя
знакомый вертикальный формат, который Вы видите,
используя mysql
, но отметьте, что mysql
сам переформатирует наборы результатов
HELP
по-другому.
Пустой набор результатов.
Никакое соответствие не могло быть найдено для строки поиска.
Это означает, что строка поиска привела к ответу для темы справки. У результата есть три столбца:
name
: Название темы.
description
: Описательный текст справки для темы.example
: Пример использования или примеры.
Этот столбец может быть пустым.Пример: HELP 'replace'
.
Вернет:
name: REPLACE description: Syntax: REPLACE(str,from_str,to_str) Returns the string str with all occurrences of the string from_str replaced by the string to_str. REPLACE() performs a case-sensitive match when searching for from_str. example: mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww'); -> 'WwWwWw.mysql.com'
Это означает, что строка поиска соответствовала нескольким темам справки. Набор результатов указывает на названия темы справки:
name
: Название темы справки.
is_it_category
: Y
, если имя представляет
категорию справки, N
, если нет. Если нет, name
когда определено как параметр HELP
должно привести к набору результатов из единственной строки, содержащему
описание для названного элемента.Пример: HELP 'status'
.
Выведет:
+-----------------------+----------------+ | name | is_it_category | +-----------------------+----------------+ | SHOW | N | | SHOW ENGINE | N | | SHOW MASTER STATUS | N | | SHOW PROCEDURE STATUS | N | | SHOW SLAVE STATUS | N | | SHOW STATUS | N | | SHOW TABLE STATUS | N | +-----------------------+----------------+
Это означает, что строка поиска соответствует категории. Набор результатов содержит записи категории:
source_category_name
:
Название категории справки.
name
: Название категории или название темы.is_it_category
: Y
, если имя представляет
категорию справки, N
, если это не так, в этом случае
name
когда определено как параметр
HELP
должно привести к набору
результатов из единственной строки, содержащему описание
для названного элемента.Пример: HELP 'functions'
.
Выведет:
+----------------------+-------------------------+----------------+ | source_category_name | name | is_it_category | +----------------------+-------------------------+----------------+ | Functions | CREATE FUNCTION | N | | Functions | DROP FUNCTION | N | | Functions | Bit Functions | Y | | Functions | Comparison operators | Y | | Functions | Control flow functions | Y | | Functions | Date and Time Functions | Y | | Functions | Encryption Functions | Y | | Functions | Information Functions | Y | | Functions | Logical operators | Y | | Functions | Miscellaneous Functions | Y | | Functions | Numeric Functions | Y | | Functions | String Functions | Y | +----------------------+-------------------------+----------------+
USE db_name
USE db_name
запрос говорит MySQL
использовать базу данных db_name
как значение по
умолчанию (текущую) базу данных для последующих запросов. База данных
остается значением по умолчанию до конца сеанса или другого
вызова оператора USE
:
USE db1; SELECT COUNT(*) FROM mytable; # selects from db1.mytable USE db2; SELECT COUNT(*) FROM mytable; # selects from db2.mytableСоздание особой базы данных по умолчанию посредством
USE
не устраняет Вас от доступа к таблицам в других базах данных. Следующий
пример получает доступ к таблице author
базы данных
db1
и таблице editor
базы данных db2
:
USE db1; SELECT author_name,editor_name FROM author,db2.editor WHERE author.editor_id = db2.editor.editor_id;