Справочник по языку MySQL
MySQL имеет очень сложный, но интуитивно понятный и легкий в изучении интерфейс, основанный на SQL (структурированный язык запросов). В данном разделе описываются различные команды, типы данных и функции этого языка, которые необходимо знать, чтобы использовать MySQL рационально и эффективно. Данная глава служит также справочником по всем функциональным возможностям, реализованным в MySQL. Читатель найдет в этой главе ссылки на различные источники информации, которые, возможно, будут полезными для ее эффективного использования.
6.1 Структура языка
6.1.1 Литералы: представление строк и чисел
В этом разделе описываются различные способы представления строк и чисел в MySQL. Здесь затронуты также различные нюансы и особенности, с которыми могут столкнуться программисты при работе с этими базовыми типами данных в MySQL.
6.1.1.1 Cтроки
Строка представляет собой последовательность символов, заключенных либо в одинарные кавычки (`'') - апострофы, либо в двойные кавычки (`"'). При использовании диалекта ANSI SQL допустимы только одинарные кавычки. Например:
'a string' "another string"
Внутри строки некоторые последовательности символов имеют специальное назначение. Каждая из этих последовательностей начинается обратным слешем (`\'), известным как escape-символ или символ перехода. MySQL распознает следующие escape-последовательности:
\0
-
Символ 0 (
NUL
) в ASCII коде. \'
- Символ одиночной кавычки (`'').
\"
- Символ двойной кавычки (`"').
\b
- Возврат на один символ.
\n
- Символ новой строки (перевода строки).
\r
- Символ перевода каретки.
\t
- Символ табуляции.
\z
-
Символ (Control-Z) таблицы ASCII(26). Данный символ можно закодировать,
чтобы обойти проблему, заключающуюся в том, что под Windows ASCII(26)
означает конец файла (проблемы возникают при использовании ASCII(26) в
выражении
mysql database < filename)
. \\
- Символ обратного слеша.
\%
- Символ процентов `%'. Используется для поиска копий литерала `%' в контекстах, где выражение `%' в противном случае интерпретировалось бы как групповой символ (see section 6.3.2.1 Функции сравнения строк).
\`_'
- Символ подчеркивания `_'. Используется для поиска копий литерала `_' в контекстах, где выражение `_' в противном случае интерпретировалось бы как групповой символ (see section 6.3.2.1 Функции сравнения строк).
Обратите внимание на то, что при использовании `\%' или `\_' в контекстах некоторых строк будут возвращаться значения строк `\%' и `\_', а не `%' и `_'.
Существует несколько способов включить кавычки в строку:
- Одиночная кавычка (апостроф) `'' внутри строки, заключенной в кавычки `'', может быть записана как `'''.
- Двойная кавычка `"' внутри строки, заключенной в двойные кавычки `"', может быть записана как `""'.
- Можно предварить символ кавычки символом экранирования (`\').
- Для символа `'' внутри строки, заключенной в двойные кавычки, не требуется специальной обработки; его также не требуется дублировать или предварять обратным слешем. Точно так же не требует специальной обработки двойная кавычка `"' внутри строки, заключенной в одиночные кавычки `''.
Ниже показаны возможные варианты применения кавычек и escape-символа на примерах выполнения команды SELECT:
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello'; +-------+---------+-----------+--------+--------+ | hello | "hello" | ""hello"" | hel'lo | 'hello | +-------+---------+-----------+--------+--------+ mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello"; +-------+---------+-----------+--------+--------+ | hello | 'hello' | ''hello'' | hel"lo | "hello | +-------+---------+-----------+--------+--------+ mysql> SELECT "This\nIs\nFour\nlines"; +--------------------+ | This Is Four lines | +--------------------+
Если необходимо вставить в строку двоичные данные (такие как BLOB
),
следующие символы должны быть представлены как escape-последовательности:
NUL
- ASCII 0. Необходимо представлять в виде `\0' (обратный слеш и символ ASCII `0').
\
- ASCII 92, обратный слеш. Представляется как `\\'.
'
- ASCII 39, единичная кавычка. Представляется как `\''.
"
- ASCII 34, двойная кавычка. Представляется как `\"'.
При написании программы на языке C для добавления символов экранирования в
команде INSERT
можно использовать функцию mysql_real_escape_string()
из C
API (see section 8.4.2 Обзор функций интерфейса C). При программировании на Perl
можно использовать метод quote
из пакета DBI для превращения специальных
символов в соответствующие escape-последовательности (see section 8.2.2 Интерфейс DBI
).
Не следует забывать, что указанное свойство escape-символа должно использоваться во всех строках, которые могут содержать любые специальные символы, перечисленные выше.
В качестве альтернативы многие интерфейсы прикладного программирования (API) для MySQL предоставляют определенную возможность использования символов-заменителей, что позволяет вносить специальные маркеры в строку запроса и затем связывать с ними значения данных при выдаче результатов запроса.
6.1.1.2 Числа
Целые числа представляются в виде последовательности цифр. Для чисел с плавающей точкой в качестве разделителя десятичных знаков используется символ `.'. Числа обоих типов могут предваряться символом `-', обозначающим отрицательную величину.
Примеры допустимых целых чисел:
1221 0 -32
Примеры допустимых чисел с плавающей запятой:
294.42 -32032.6809e+10 148.00
Целое число можно использовать в контексте дробных чисел, при этом оно будет интерпретироваться как эквивалент числа с плавающей запятой.
6.1.1.3 Шестнадцатеричные величины
MySQL поддерживает шестнадцатеричные величины. В числовом контексте такое число обладает всеми свойствами целого числа с 64-разрядной точностью. В строковом контексте шестнадцатеричная величина представляет собой двоичную строку, в которой каждая пара шестнадцатеричных разрядов конвертируется в символ:
mysql> SELECT x'4D7953514C'; -> MySQL mysql> SELECT 0xa+0; -> 10 mysql> SELECT 0x5061756c; -> Paul
Синтаксис выражений вида x'hexstring'
(новшество в версии 4.0) базируется
на ANSI SQL, а для обозначений вида 0x
используется синтаксис ODBC.
Шестнадцатеричные строки часто применяются в ODBC для представления
двоичных типов данных вида BLOB
. Для конвертирования строки или числа в
шестнадцатеричный вид можно применять функцию HEX()
.
6.1.1.4 Значения NULL
Значение NULL
означает ``отсутствие данных''. Они является отличным от
значения 0 для числовых типов данных или пустой строки для строковых типов
(see section A.5.3 Проблемы со значением NULL
).
При использовании форматов импорта или экспорта текстовых файлов (LOAD
DATA INFILE, SELECT ... INTO OUTFILE
) NULL
можно представить как \N
(see section 6.4.9 Синтаксис оператора LOAD DATA INFILE
).
6.1.2 Имена баз данных, таблиц, столбцов, индексы псевдонимы
Для всех имен баз данных, таблиц, столбцов, индексов и псевдонимов в MySQL приняты одни и те же правила.
Следует отметить, что эти правила были изменены, начиная с версии MySQL 3.23.6, когда было разрешено брать в одиночные скобки ``' идентификаторы (имена баз данных, таблиц и столбцов). Двойные скобки `"' тоже допустимы - при работе в режиме ANSI SQL (see section 1.9.2 Запуск MySQL в режиме ANSI).
Идентификатор | Максимальная длина строки | Допускаемые символы |
База данных | 64 | Любой символ, допустимый в имени каталога, за исключением `/', `\' или `.' |
Таблица | 64 | Любой символ, допустимый в имени файла, за исключением `/' или `.' |
Столбец | 64 | Все символы |
Псевдоним | 255 | Все символы |
Необходимо также учитывать, что не следует использовать символы ASCII(0)
,
ASCII(255)
или кавычки в самом идентификаторе.
Кроме того, если имя идентификатора относится к служебным словам или
содержит специальные символы, необходимо всегда заключать его в обратные
кавычки `
при использовании в выражениях:
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
See section 6.1.7 ``Придирчив'' ли MySQL к зарезервированным словам?.
В предыдущих версиях MySQL (до 3.23.6) для имен существовали следующие правила:
-
Имя может состоять из буквенно-цифровых символов установленного в
данное время алфавита и символов `_' and `$'. Тип кодировки по
умолчанию - ISO-8859-1 Latin1, он может быть изменен указанием иного
типа в аргументе параметра
--default-character-set
mysqld
(see section 4.6.1 Набор символов, применяющийся для записи данных и сортировки). - Имя может начинаться с любого допустимого символа, в частности, с цифры (в этом состоит отличие от правил, принятых во многих других базах данных). Однако имя не может состоять только из цифр.
- Не допускается использование в именах символа `.', так как он применяется для расширения формата имени (посредством чего можно ссылаться на столбцы - см. в этом же разделе ниже).
Не рекомендуется использовать имена, подобные 1e
, так как выражение
вида 1e+1
является неоднозначным. Оно может интерпретироваться и как
выражение 1e + 1
, и как число 1e+1
.
В MySQL разрешается делать ссылки на столбец, используя любую из следующих форм:
Ссылка на столбец | Значение |
col_name | Столбец col_name из любой используемой в запросе таблицы содержит столбец с данным именем.
|
tbl_name.col_name | Столбец col_name из таблицы tbl_name текущей базы данных.
|
db_name.tbl_name.col_name | Столбец col_name из таблицы tbl_name базы данных db_name . Эта форма доступна в версии MySQL 3.22 или более поздних.
|
`column_name` | Имя столбца является ключевым словом или содержит специальные символы. |
Нет необходимости указывать префикс tbl_name
или db_name.tbl_name
в ссылке
на столбец в каком-либо утверждении, если эта ссылка не будет
неоднозначной. Например, предположим, что каждая из таблиц t1
и t2
содержит столбец c
, по которому производится выборка командой SELECT
,
использующей обе таблицы - и t1
, и t2
. В этом случае имя столбца
c
является неоднозначным, так как оно не уникально для таблиц, указанных в
команде, поэтому необходимо уточнить, какая именно таблица имеется в виду,
конкретизировав - t1.c
или t2.c
. Аналогично, при выборке данных из таблицы
t
в базе данных db1
и из таблицы t
в базе данных db2
необходимо ссылаться
на столбцы в этих таблицах как на db1.t.col_name
и db2.t.col_name
.
Выражение .tbl_name
означает таблицу tbl_name
в текущей базе данных.
Данный синтаксис принят для совместимости с ODBC, так как некоторые
программы ODBC ставят в начале имен таблиц в качестве префикса символ `.'.
6.1.3 Чувствительность имен к регистру
В MySQL имена баз данных и таблиц соответствуют директориям и файлам внутри директорий. Следовательно, чувствительность к регистру операционной системы, под которой работает MySQL, определяет чувствительность к регистру имен баз данных и таблиц. Это означает, что имена баз данных и таблиц нечувствительны к регистру под Windows, а под большинством версий Unix проявляют чувствительность к регистру. Одно большое исключение здесь это Mac OS X, когда файловая система по умолчанию HFS+ используется. Однако Mac OS X также поддерживает тома UFS, которые чувствительны к регистру под Mac OS X также как и на Unix. See section 1.9.3 Расширения MySQL к ANSI SQL92.
Примечание: хотя имена баз данных и таблиц нечувствительны к регистру под
Windows, не следует ссылаться на конкретную базу данных или таблицу,
используя различные регистры символов внутри одного и того же запроса.
Приведенный ниже запрос не будет выполнен, поскольку в нем одна и та же
таблица указана и как my_table
, и как MY_TABLE
:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
Имена и псевдонимы столбцов нечувствительны к регистру во всех случаях.
Псевдонимы таблиц обладают чувствительностью к регистру. Приведенный ниже
запрос не будет выполнен, поскольку он ссылается на псевдоним и как на a
,
и как на A
:
mysql> SELECT col_name FROM tbl_name AS a -> WHERE a.col_name = 1 OR A.col_name = 2;
Если вы не хотите держать в памяти размер букв для имен базы данных и таблиц, при создании базы данных и таблиц придерживайтесь последовательного принципа, используя для имен только строчные буквы.
Одним из путей устранения этой проблемы является запуск демона mysqld
с
параметром -O lower_case_table_names=1
. По умолчанию этот параметр имеет
значение 1 для Windows и 0 для Unix.
Если значение параметра lower_case_table_names
равно 1, MySQL при
сохранении и поиске будет преобразовывать все имена таблиц к нижнему регистру.
С версии 4.0.2 это также касается и имен баз данных. Обратите внимание на то,
что при изменении этого параметра перед запуском mysqld
необходимо
прежде всего преобразовать имена всех старых таблиц к нижнему регистру.
При переносе MyISAM
-файлов с Windows на диск в Unix в некоторых случаях
будет полезна утилита mysql_fix_extensions
для приведения в соответствие
регистров расширений файлов в каждой указанной директории базы данных (нижний
регистр `.frm', верхний регистр `.MYI' и `.MYD'). Утилиту
mysql_fix_extensions
можно найти в подкаталоге `scripts'.
6.1.4 Переменные пользователя
Для конкретного процесса пользователь может определить локальные
переменные, которые в MySQL обозначаются как @variablename
. Имя локальной
переменной может состоять из буквенно-цифровых символов установленного в
данное время алфавита и символов `_', `$', and `.'. Тип кодировки по
умолчанию - ISO-8859-1 Latin1, он может быть изменен указанием иного типа
в аргументе параметра --default-character-set
mysqld
(see section 4.6.1 Набор символов, применяющийся для записи данных и сортировки).
Локальные переменные не требуют инициализации. Они содержат значение NULL
по умолчанию; в них могут храниться целые числа, вещественные числа или
строковые величины. При запуске конкретного процесса все объявленные в нем
локальные переменные автоматически активизируются.
Локальную переменную можно объявить, используя синтаксис команды SET
:
SET @variable= { integer expression | real expression | string expression } [,@variable= ...].
Можно также определить значение переменной иным способом, без команды SET
.
Однако в этом случае в качестве оператора присвоения более предпочтительно
использовать оператор `:=', чем оператор `=', так как последний
зарезервирован для сравнения выражений, не связанных с установкой
переменных:
mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3; +----------------------+------+------+------+ | @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 | +----------------------+------+------+------+ | 5 | 5 | 1 | 4 | +----------------------+------+------+------+
Введенные пользователем переменные могут применяться только в составе
выражений и там, где выражения допустимы. Заметим, что в область их
применения в данное время не включается контекст, в котором явно требуется
число, например, условие LIMIT
в команде SELECT
или выражение IGNORE
number LINES
в команде LOAD DATA
.
Примечание: в команде SELECT
каждое выражение оценивается только при
отправлении клиенту. Это означает, что в условиях HAVING
, GROUP BY
, or
ORDER BY
не следует ссылаться на выражение, содержащее переменные,
которые введены в части SELECT
этой команды. Например, следующая команда
НЕ будет выполняться так, как ожидалось:
mysql> SELECT (@aa:=id) AS a, (@aa+3) AS b FROM table_name HAVING b=5;
Причина в том, что переменная @aa
не будет содержать значения текущей
строки, в то время как значение id
в предыдущем выражении является
строкой.
Действует правило никогда не создавать и не использовать
одну и ту же переменную в одном
и том же выражении SQL.
6.1.5 Системные переменные
Начиная с MySQL 4.0.3 мы предоставляем лучший доступ к большинству системных переменных и переменных, относящихся к соединению. Можно менять теперь большую часть переменных без необходимости останавливать сервер.
Есть два типа системных переменных: специфичные для потока (или для соединения; мы их в дальнейшем называем потоковыми переменными для краткости), которые уникальны для данного соединения и глобальные перемененные, которые предназначаются для управления глобальными событиями. Глобальные переменные также используются для того, чтобы установить значения по умолчанию для соответствующих потоковых переменных для новых соединений.
Когда mysqld
запускается, все глобальные переменные инициализируются из командной строки
и файлов опций. Вы можете изменять значения с помощью SET GLOBAL
. Когда новый поток создается,
потоковые переменные инициализируются из глобальных и они не меняются даже если вы даете новую
команду SET GLOBAL
.
Для установки глобальной переменной, используйте один из таких синтаксисов:
(Здесь используется sort_buffer_size
в качестве примера)
SET GLOBAL sort_buffer_size=value; SET @@global.sort_buffer_size=value;
Чтобы установить значение для потоковой переменной, используйте такие синтаксисы:
SET SESSION sort_buffer_size=value; SET @@session.sort_buffer_size=value; SET sort_buffer_size=value;
Если вы не указываете режим, то тогда подразумевается SESSION
.
See section 5.5.6 Синтаксис команды SET
.
LOCAL
- синоним для SESSION
.
Для получения значения глобальной переменной используйте одну из этих команд:
SELECT @@global.sort_buffer_size; SHOW GLOBAL VARIABLES like 'sort_buffer_size';
Для получения значения потоковой переменной используйте одну из этих команд:
SELECT @@session.sort_buffer_size; SHOW SESSION VARIABLES like 'sort_buffer_size';
Когда вы запрашиваете значение переменной с помощью синтаксиса
@@variable_name
и не укзываете GLOBAL
или SESSION
, то
тогда MySQL вернет потоковое значение этой переменное, если таковое существует.
Если нет, то MySQL вернет глобальное значение.
Причина, по которой требуется указывать GLOBAL
для установки только глобальных
переменных но не для получения их значения, заключается в том, чтобы
удостовериться, что если мы в будущем не будем иметь проблем, если добавим
потоковую переменную с таким же именем или уберем некую потоковую переменную.
В этом случае вы можете ненароком изменить состояние сервера в целом, а не
исключительно вашего соединения.
Далее идет полный список всех переменных которые вы можете изменять и значения
которых можете получать, а также информация о том, можете ли вы использовать
SESSION
или GLOBAL
с ними.
Переменная | Тип значения | Тип |
autocommit | булевое | SESSION |
big_tables | булевое | SESSION |
binlog_cache_size | число | GLOBAL |
bulk_insert_buffer_size | число | GLOBAL | SESSION |
concurrent_insert | булевое | GLOBAL |
connect_timeout | число | GLOBAL |
convert_character_set | строка | SESSION |
delay_key_write | OFF | ON | ALL | GLOBAL |
delayed_insert_limit | число | GLOBAL |
delayed_insert_timeout | число | GLOBAL |
delayed_queue_size | число | GLOBAL |
error_count | число | LOCAL |
flush | булевое | GLOBAL |
flush_time | число | GLOBAL |
foreign_key_checks | булевое | SESSION |
identity | число | SESSION |
insert_id | булевое | SESSION |
interactive_timeout | число | GLOBAL | SESSION |
join_buffer_size | число | GLOBAL | SESSION |
key_buffer_size | число | GLOBAL |
last_insert_id | булевое | SESSION |
local_infile | булевое | GLOBAL |
log_warnings | булевое | GLOBAL |
long_query_time | число | GLOBAL | SESSION |
low_priority_updates | булевое | GLOBAL | SESSION |
max_allowed_packet | число | GLOBAL | SESSION |
max_binlog_cache_size | число | GLOBAL |
max_binlog_size | число | GLOBAL |
max_connect_errors | число | GLOBAL |
max_connections | число | GLOBAL |
max_error_count | число | GLOBAL | SESSION |
max_delayed_threads | число | GLOBAL |
max_heap_table_size | число | GLOBAL | SESSION |
max_join_size | число | GLOBAL | SESSION |
max_sort_length | число | GLOBAL | SESSION |
max_tmp_tables | число | GLOBAL |
max_user_connections | число | GLOBAL |
max_write_lock_count | число | GLOBAL |
myisam_max_extra_sort_file_size | число | GLOBAL | SESSION |
myisam_max_sort_file_size | число | GLOBAL | SESSION |
myisam_sort_buffer_size | число | GLOBAL | SESSION |
net_buffer_length | число | GLOBAL | SESSION |
net_read_timeout | число | GLOBAL | SESSION |
net_retry_count | число | GLOBAL | SESSION |
net_write_timeout | число | GLOBAL | SESSION |
query_cache_limit | число | GLOBAL |
query_cache_size | число | GLOBAL |
query_cache_type | enum | GLOBAL |
read_buffer_size | число | GLOBAL | SESSION |
read_rnd_buffer_size | число | GLOBAL | SESSION |
rpl_recovery_rank | число | GLOBAL |
safe_show_database | булевое | GLOBAL |
server_id | число | GLOBAL |
slave_compressed_protocol | булевое | GLOBAL |
slave_net_timeout | число | GLOBAL |
slow_launch_time | число | GLOBAL |
sort_buffer_size | число | GLOBAL | SESSION |
sql_auto_is_null | булевое | SESSION |
sql_big_selects | булевое | SESSION |
sql_big_tables | булевое | SESSION |
sql_buffer_result | булевое | SESSION |
sql_log_binlog | булевое | SESSION |
sql_log_off | булевое | SESSION |
sql_log_update | булевое | SESSION |
sql_low_priority_updates | булевое | GLOBAL | SESSION |
sql_max_join_size | число | GLOBAL | SESSION |
sql_quote_show_create | булевое | SESSION |
sql_safe_updates | булевое | SESSION |
sql_select_limit | булевое | SESSION |
sql_slave_skip_counter | число | GLOBAL |
sql_warnings | булевое | SESSION |
table_cache | число | GLOBAL |
table_type | enum | GLOBAL | SESSION |
thread_cache_size | число | GLOBAL |
timestamp | булевое | SESSION |
tmp_table_size | enum | GLOBAL | SESSION |
tx_isolation | enum | GLOBAL | SESSION |
version | строка | GLOBAL |
wait_timeout | число | GLOBAL | SESSION |
warning_count | число | LOCAL |
unique_checks | булевое | SESSION |
Переменные, помеченные как число
могут иметь числовое значение.
Переменные, помеченные как булевое
могут быть установлены в 0
,
1
, ON
или OFF
. Переменные типа enum
должны в общем
случае быть установлены в одно из возможных значений для переменной, но также
могут быть установлены в значение числа, соответствующего значению выбора enum.
Первый элемент списка enum - номер 0.
Вот описание некоторых переменных:
Переменная | Описание |
identity | Синоним для last_insert_id (совместимость с Sybase) |
sql_low_priority_updates | Синоним для low_priority_updates |
sql_max_join_size | Синоним для max_join_size |
delay_key_write_for_all_tables | Если это и delay_key_write установлены, то тогда все вновь открываемые таблицы MyISAM открываются с задержкой записи ключей. |
version | Синоним для VERSION() (совместимость (?) с Sybase) |
Описания других переменных можно найти в описании переменных запуска
mysql
, в описании команды SHOW VARIABLES
и в разделе SET
.
See section 4.1.1 Параметры командной строки mysqld
. See section 4.5.6.4 SHOW VARIABLES
. See section 5.5.6 Синтаксис команды SET
.
6.1.6 Синтаксис комментариев
Сервер MySQL поддерживает следующие способы задания комментариев: с
помощью символа `#', за которым следует текст комментария до конца строки;
с помощью двух символов --
, за которыми идет текст комментария до конца
строки; и (для многострочных комментариев) с помощью символов /*
(начало
комментария) и */
(конец комментария):
mysql> SELECT 1+1; # Этот комментарий продолжается до конца строки mysql> SELECT 1+1; -- Этот комментарий продолжается до конца строки mysql> SELECT 1 /* Это комментарий в строке */ + 1; mysql> SELECT 1+ /* Это многострочный комментарий */ 1;
Обратите внимание: при использовании для комментирования способа с --
(двойное тире) требуется наличие хотя бы одного пробела после второго
тире!
Хотя сервер ``понимает'' все описанные выше варианты комментирования,
существует ряд ограничений на способ синтаксического анализа комментариев
вида /* ... */
клиентом mysql
:
-
Символы одинарной и двойной кавычек, даже внутри комментария,
считаются началом заключенной в кавычки строки. Если внутри
комментария не встречается вторая такая же кавычка, синтаксический
анализатор не считает комментарий законченным. При работе с
mysql
в интерактивном режиме эта ошибка проявится в том, что окно запроса изменит свое состояние сmysql>
на'>
или">
. - Точка с запятой используется для обозначения окончания данной SQL-команды и что-либо, следующее за этим символом, указывает на начало следующего выражения.
Эти ограничения относятся как к интерактивному режиму работы mysql
(из
командной строки), так и к вызову команд из файла, читаемого с ввода
командой mysql < some-file
.
MySQL поддерживает принятый в ANSI SQL способ комментирования с помощью двойного тире `--' только в том случае, если после второго тире следует пробел (see section 1.9.4.7 Символы `--' как начало комментария).
6.1.7 ``Придирчив'' ли MySQL к зарезервированным словам?
Это общая проблема, возникающая при попытке создать таблицу с именами
столбцов, использующих принятые в MySQL названия типов данных или функций,
такие как TIMESTAMP
или GROUP
. Иногда это возможно (например, ABS
является
разрешенным именем для столбца), но не допускается пробел между именем
функции и сразу же следующей за ним скобкой `(' при использовании имен
функций, совпадающих с именами столбцов.
Следующие слова являются зарезервированными в MySQL. Большинство из них не
допускаются в ANSI SQL92 как имена столбцов и/или таблиц (например
GROUP). Некоторые зарезервированы для нужд MySQL и используются (в
настоящее время) синтаксическим анализатором yacc
:
Word | Word | Word |
ADD
| ALL
| ALTER
|
ANALYZE
| AND
| AS
|
ASC
| ASENSITIVE
| AUTO_INCREMENT
|
BDB
| BEFORE
| BERKELEYDB
|
BETWEEN
| BIGINT
| BINARY
|
BLOB
| BOTH
| BY
|
CALL
| CASCADE
| CASE
|
CHANGE
| CHAR
| CHARACTER
|
CHECK
| COLLATE
| COLUMN
|
COLUMNS
| CONDITION
| CONNECTION
|
CONSTRAINT
| CONTINUE
| CREATE
|
CROSS
| CURRENT_DATE
| CURRENT_TIME
|
CURRENT_TIMESTAMP
| CURSOR
| DATABASE
|
DATABASES
| DAY_HOUR
| DAY_MICROSECOND
|
DAY_MINUTE
| DAY_SECOND
| DEC
|
DECIMAL
| DECLARE
| DEFAULT
|
DELAYED
| DELETE
| DESC
|
DESCRIBE
| DETERMINISTIC
| DISTINCT
|
DISTINCTROW
| DIV
| DOUBLE
|
DROP
| ELSE
| ELSEIF
|
ENCLOSED
| ESCAPED
| EXISTS
|
EXIT
| EXPLAIN
| FALSE
|
FETCH
| FIELDS
| FLOAT
|
FOR
| FORCE
| FOREIGN
|
FOUND
| FRAC_SECOND
| FROM
|
FULLTEXT
| GRANT
| GROUP
|
HAVING
| HIGH_PRIORITY
| HOUR_MICROSECOND
|
HOUR_MINUTE
| HOUR_SECOND
| IF
|
IGNORE
| IN
| INDEX
|
INFILE
| INNER
| INNODB
|
INOUT
| INSENSITIVE
| INSERT
|
INT
| INTEGER
| INTERVAL
|
INTO
| IO_THREAD
| IS
|
ITERATE
| JOIN
| KEY
|
KEYS
| KILL
| LEADING
|
LEAVE
| LEFT
| LIKE
|
LIMIT
| LINES
| LOAD
|
LOCALTIME
| LOCALTIMESTAMP
| LOCK
|
LONG
| LONGBLOB
| LONGTEXT
|
LOOP
| LOW_PRIORITY
| MASTER_SERVER_ID
|
MATCH
| MEDIUMBLOB
| MEDIUMINT
|
MEDIUMTEXT
| MIDDLEINT
| MINUTE_MICROSECOND
|
MINUTE_SECOND
| MOD
| NATURAL
|
NOT
| NO_WRITE_TO_BINLOG
| NULL
|
NUMERIC
| ON
| OPTIMIZE
|
OPTION
| OPTIONALLY
| OR
|
ORDER
| OUT
| OUTER
|
OUTFILE
| PRECISION
| PRIMARY
|
PRIVILEGES
| PROCEDURE
| PURGE
|
READ
| REAL
| REFERENCES
|
REGEXP
| RENAME
| REPEAT
|
REPLACE
| REQUIRE
| RESTRICT
|
RETURN
| REVOKE
| RIGHT
|
RLIKE
| SECOND_MICROSECOND
| SELECT
|
SENSITIVE
| SEPARATOR
| SET
|
SHOW
| SMALLINT
| SOME
|
SONAME
| SPATIAL
| SPECIFIC
|
SQL
| SQLEXCEPTION
| SQLSTATE
|
SQLWARNING
| SQL_BIG_RESULT
| SQL_CALC_FOUND_ROWS
|
SQL_SMALL_RESULT
| SQL_TSI_DAY
| SQL_TSI_FRAC_SECOND
|
SQL_TSI_HOUR
| SQL_TSI_MINUTE
| SQL_TSI_MONTH
|
SQL_TSI_QUARTER
| SQL_TSI_SECOND
| SQL_TSI_WEEK
|
SQL_TSI_YEAR
| SSL
| STARTING
|
STRAIGHT_JOIN
| STRIPED
| TABLE
|
TABLES
| TERMINATED
| THEN
|
TIMESTAMPADD
| TIMESTAMPDIFF
| TINYBLOB
|
TINYINT
| TINYTEXT
| TO
|
TRAILING
| TRUE
| UNDO
|
UNION
| UNIQUE
| UNLOCK
|
UNSIGNED
| UPDATE
| USAGE
|
USE
| USER_RESOURCES
| USING
|
UTC_DATE
| UTC_TIME
| UTC_TIMESTAMP
|
VALUES
| VARBINARY
| VARCHAR
|
VARCHARACTER
| VARYING
| WHEN
|
WHERE
| WHILE
| WITH
|
WRITE
| XOR
| YEAR_MONTH
|
ZEROFILL
|
Следующие символы (из приведенной выше таблицы таблицы) не разрешены в ANSI SQL, но допускаются в MySQL как имена столбцов/таблиц. Это объясняется тем, что некоторые из этих имен являются словами естественного языка и уже использованы многими потребителями.
ACTION
BIT
DATE
ENUM
NO
TEXT
TIME
TIMESTAMP
6.2 Типы данных столбцов
MySQL поддерживает несколько типов столбцов, которые можно разделить на три категории: числовые типы данных, типы данных для хранения даты и времени и символьные (строковые) типы данных. В данном разделе вначале дается обзор всех возможных типов и приводятся требования по хранению для каждого типа столбца, затем свойства типов описываются более подробно по каждой категории. Мы намеренно сделали обзор кратким, поскольку более детальные описания требуют дополнительной информации о конкретных типах столбцов, например, о допустимых форматах представления величин.
Ниже перечислены типы столбцов, поддерживаемые MySQL. В описаниях используются следующие обозначения:
M
- Указывает максимальный размер вывода. Максимально допустимый размер вывода составляет 255 символов.
D
-
Употребляется для типов данных с плавающей точкой и указывает количество
разрядов, следующих за десятичной точкой. Максимально возможная величина
составляет 30 разрядов, но не может быть больше, чем
M
-2.
Квадратные скобки (`[' и `]') указывают для типа данных группы необязательных признаков.
Заметьте, что если для столбца указать параметр ZEROFILL
, то MySQL будет
автоматически добавлять в этот столбец атрибут UNSIGNED
.
Предупреждение: следует помнить, что при выполнении вычитания между
числовыми величинами, одна из которых относится к типу UNSIGNED
, результат
будет беззнаковым! See section 6.3.5 Функции приведения типов.
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
-
Очень малое целое число. Диапазон со знаком от
-128
до127
. Диапазон без знака от0
до255
. BIT
BOOL
-
Являются синонимами для
TINYINT(1)
. SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
-
Малое целое число. Диапазон со знаком от
-32768
до32767
. Диапазон без знака от0
до65535
. MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
-
Целое число среднего размера. Диапазон со знаком от
-8388608
до8388607
. Диапазон без знака от0
до16777215
. INT[(M)] [UNSIGNED] [ZEROFILL]
-
Целое число нормального размера. Диапазон со знаком от
-2147483648
до2147483647
. Диапазон без знака от0
до4294967295
. INTEGER[(M)] [UNSIGNED] [ZEROFILL]
-
Синоним для
INT
. BIGINT[(M)] [UNSIGNED] [ZEROFILL]
-
Большое целое число. Диапазон со знаком от
-9223372036854775808
до9223372036854775807
. Диапазон без знака от 0 до18446744073709551615
. Для столбцов типаBIGINT
необходимо учитывать некоторые особенности:-
Все арифметические операции выполняются с использованием значений
BIGINT
илиDOUBLE
со знаком, так что не следует использовать беззнаковые целые числа больше чем9223372036854775807
(63 бита), кроме операций, выполняемых логическими функциями. В противном случае несколько последних разрядов результата могут оказаться ошибочными из-за ошибок округления при преобразованииBIGINT
вDOUBLE
. MySQL 4.0 может обрабатывать данные типаBIGINT
в следующих случаях:-
Использование целых чисел для хранения больших беззнаковых
величин в столбце с типом
BIGINT
. -
В случаях
MIN(big_int_column)
иMAX(big_int_column)
. - При использовании операторов (`+', `-', `*' и т.д.), когда оба операнда являются целыми числами.
-
Использование целых чисел для хранения больших беззнаковых
величин в столбце с типом
-
Точное значение целого числа всегда можно хранить в столбце с типом
BIGINT
в виде строки. В этом случае MySQL выполнит преобразование строки в число без промежуточного преобразования. -
Если оба аргумента являются целочисленными величинами, то при
выполнении над ними операций `-', `+', и `*' будут использоваться
правила
BIGINT
-арифметики. Это означает, что при умножении двух больших целых чисел (или результатов вычислений функций, возвращающих целые числа) результат операции может оказаться непредсказуемым, если он превосходит значение9223372036854775807
.
-
Все арифметические операции выполняются с использованием значений
FLOAT(точность) [UNSIGNED] [ZEROFILL]
-
Число с плавающей точкой. Атрибут точности может иметь значение
<=24
для числа с плавающей точкой обычной (одинарной) точности и между25
и53
- для числа с плавающей точкой удвоенной точности. Эти типы данных сходны с типамиFLOAT
иDOUBLE
, описанными ниже.FLOAT(X)
относится к тому же интервалу, что и соответствующие типыFLOAT
иDOUBLE
, но диапазон значений и количество десятичных знаков не определены. В версии MySQL 3.23 это истинная величина числа с плавающей точкой. В более ранних версиях MySQL тип данныхFLOAT(точность)
всегда имеет два десятичных знака. Следует отметить, что использование типа данныхFLOAT
может привести к неожиданным проблемам, так как все вычисления в MySQL выполняются с удвоенной точностью. See section A.5.6 Решение проблем с отсутствием строк, удовлетворяющих условиям поиска. Данный синтаксис обеспечивает совместимость с ODBC. FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
-
Малое число с плавающей точкой обычной точности. Допустимые значения: от
-3,402823466E+38
до-1,175494351E-38
,0
, и от1,175494351E-38
до3,402823466E+38
. Если указан атрибутUNSIGNED
, отрицательные значения недопустимы. АтрибутM
указывает количество выводимых пользователю знаков, а атрибутD
- количество разрядов, следующих за десятичной точкой. ОбозначениеFLOAT
без указания аргументов или запись видаFLOAT(X)
, гдеX
<=24
справедливы для числа с плавающей точкой обычной точности. DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
-
Число с плавающей точкой удвоенной точности нормального размера.
Допустимые значения: от
-1,7976931348623157E+308
до-2,2250738585072014E-308
,0
, и от2,2250738585072014E-308
до1,7976931348623157E+308
. Если указан атрибутUNSIGNED
, отрицательные значения недопустимы. АтрибутM
указывает количество выводимых пользователю знаков, а атрибутD
- количество разрядов, следующих за десятичной точкой. ОбозначениеDOUBLE
без указания аргументов или запись видаFLOAT(X)
, где25 <= X <= 53
справедливы для числа с плавающей точкой двойной точности. DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL]
REAL[(M,D)] [UNSIGNED] [ZEROFILL]
-
Данные обозначения являются синонимами для
DOUBLE
. DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
-
``Неупакованное'' число с плавающей точкой. Ведет себя подобно столбцу
CHAR
, содержащему цифровое значение. Термин ``неупакованное'' означает, что число хранится в виде строки и при этом для каждого десятичного знака используется один символ. Разделительный знак десятичных разрядов, а также знак `-' для отрицательных чисел не учитываются вM
(но место для них зарезервировано). Если атрибутD
равен0
, величины будут представлены без десятичного знака, т.е. без дробной части. Максимальный интервал значений типаDECIMAL
тот же, что и для типаDOUBLE
, но действительный интервал для конкретного столбцаDECIMAL
может быть ограничен выбором значений атрибутовM
иD
. Если указан атрибутUNSIGNED
, отрицательные значения недопустимы. Если атрибутD
не указан, его значение по умолчанию равно0
. Если не указанM
, его значение по умолчанию равно10
. В более ранних, чем MySQL 3.23, версиях аргументM
должен содержать в себе место для знака числа и десятичного знака. DEC[(M[,D])] [UNSIGNED] [ZEROFILL]
NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL]
-
Данные обозначения являются синонимами для
DECIMAL
. DATE
-
Дата. Поддерживается интервал от
'1000-01-01'
до'9999-12-31'
. MySQL выводит значенияDATE
в формате'YYYY-MM-DD'
, но можно установить значения в столбецDATE
, используя как строки, так и числа. See section 6.2.2.2 Типы данныхDATETIME
,DATE
иTIMESTAMP
. DATETIME
-
Комбинация даты и времени. Поддерживается интервал от
'1000-01-01 00:00:00'
до'9999-12-31 23:59:59'
. MySQL выводит значенияDATETIME
в формате'YYYY-MM-DD HH:MM:SS'
, но можно устанавливать значения в столбцеDATETIME
, используя как строки, так и числа. See section 6.2.2.2 Типы данныхDATETIME
,DATE
иTIMESTAMP
. TIMESTAMP[(M)]
-
Временная метка. Интервал от
'1970-01-01 00:00:00'
до некоторого значения времени в 2037 году. MySQL выводит значенияTIMESTAMP
в форматахYYYYMMDDHHMMSS
,YYMMDDHHMMSS
,YYYYMMDD
илиYYMMDD
в зависимости от значенийM
:14
(или отсутствующее),12
,8
, или6
; но можно также устанавливать значения в столбцеTIMESTAMP
, используя как строки, так и числа. СтолбецTIMESTAMP
полезен для записи даты и времени при выполнении операцийINSERT
илиUPDATE
, так как при этом автоматически вносятся значения даты и времени самой последней операции, если эти величины не введены программой. Можно также устанавливать текущее значение даты и времени, задавая значениеNULL
. See section 6.2.2 Типы данных даты и времени. АргументM
влияет только на способ вывода столбцаTIMESTAMP
; для хранения его значений всегда используется 4 байта. Следует учитывать, что столбцыTIMESTAMP(M)
, гдеM
равно8
или14
, представляют собой числа, в то время, как столбцыTIMESTAMP(M)
с иным значением аргументаM
являются строками. Это убеждает, что можно надежно сделать дамп и восстановить таблицу с этими типами столбцов! See section 6.2.2.2 Типы данныхDATETIME
,DATE
иTIMESTAMP
. TIME
-
Время. Интервал от
'-838:59:59'
до'838:59:59'
. MySQL выводит значенияTIME
в формате'HH:MM:SS'
, но можно устанавливать значения в столбцеTIME
, используя как строки, так и числа. See section 6.2.2.3 Тип данныхTIME
. YEAR[(2|4)]
-
Год в двухзначном или четырехзначном форматах (по умолчанию формат
четырехзначный). Допустимы следующие значения: с
1901
по2155
,0000
для четырехзначного формата года и1970-2069
при использовании двухзначного формата (70-69
). MySQL выводит значенияYEAR
в форматеYYYY
, но можно задавать значения в столбцеYEAR
, используя как строки, так и числа (тип данныхYEAR
недоступен в версиях, предшествующих MySQL 3.22). See section 6.2.2.4 Тип данныхYEAR
. [NATIONAL] CHAR(M) [BINARY]
-
Строка фиксированной длины, при хранении всегда дополняется пробелами в
конце строки до заданного размера. Диапазон аргумента
M
составляет от0
до255
символов (от1
до255
в версиях, предшествующих MySQL 3.23). Концевые пробелы удаляются при выводе значения. Если не задан атрибут чувствительности к региструBINARY
, то величиныCHAR
сортируются и сравниваются как независимые от регистра в соответствии с установленным по умолчанию алфавитом. АтрибутNATIONAL CHAR
(или его эквивалентная краткая формаNCHAR
) представляет собой принятый в ANSI SQL способ указания, что в столбцеCHAR
должен использоваться установленный по умолчанию набор символов (CHARACTER
). В MySQL это принято по умолчанию.CHAR
является сокращением отCHARACTER
. MySQL позволяет создавать столбец типаCHAR(0)
. В основном это полезно, если необходимо обеспечить совместимость с некоторыми старыми приложениями, которые зависят от наличия столбца, но реально эту величину не используют. Кроме того, такая возможность может очень пригодиться в случае, если необходим столбец, который может содержать только 2 значения, а именноCHAR(0)
(т.е. столбец, который не определен какNOT NULL
, занимает только один бит и принимает только 2 значения:NULL
или""
). See section 6.2.3.1 Типы данных CHAR и VARCHAR. CHAR
-
Это синоним для
CHAR(1)
. [NATIONAL] VARCHAR(M) [BINARY]
-
Строка переменной длины. Примечание: концевые пробелы удаляются при
сохранении значения (в этом заключается отличие от спецификации ANSI
SQL). Диапазон аргумента
M
составляет от0
до255
символов (от1
до255
в версиях, предшествующих MySQL Version 4.0.2). Если не задан атрибут чувствительности к региструBINARY
, то величиныVARCHAR
сортируются и сравниваются как независимые от регистра. See section 6.5.3.1 Молчаливые изменения определений столбцов. ТерминVARCHAR
является сокращением отCHARACTER VARYING
. See section 6.2.3.1 Типы данных CHAR и VARCHAR. TINYBLOB
TINYTEXT
-
Столбец типа
BLOB
илиTEXT
с максимальной длиной255
(2^8 - 1
) символов. See section 6.5.3.1 Молчаливые изменения определений столбцов. See section 6.2.3.2 Типы данныхBLOB
иTEXT
. BLOB
TEXT
-
Столбец типа
BLOB
илиTEXT
с максимальной длиной65535
(2^16 - 1
) символов. See section 6.5.3.1 Молчаливые изменения определений столбцов. See section 6.2.3.2 Типы данныхBLOB
иTEXT
. MEDIUMBLOB
MEDIUMTEXT
-
Столбец типа
BLOB
илиTEXT
с максимальной длиной16777215
(2^24 - 1
) символов. See section 6.5.3.1 Молчаливые изменения определений столбцов. See section 6.2.3.2 Типы данныхBLOB
иTEXT
. LONGBLOB
LONGTEXT
-
Столбец типа
BLOB
илиTEXT
с максимальной длиной4294967295
(2^32 - 1
) символов. See section 6.5.3.1 Молчаливые изменения определений столбцов. Следует учитывать, что в настоящее время протокол передачи данных сервер/клиент и таблицыMyISAM
имеют ограничение 16 Мб на передаваемый пакет/строку таблицы, поэтому пока нельзя использовать этот тип данных в его полном диапазоне. See section 6.2.3.2 Типы данныхBLOB
иTEXT
. ENUM('значение1','значение2',...)
-
Перечисление. Перечисляемый тип данных. Объект строки может иметь только
одно значение, выбранное из заданного списка величин
'значение1'
,'значение2'
,...
,NULL
или специальная величина ошибки""
. СписокENUM
может содержать максимум65535
различных величин. See section 6.2.3.3 Тип перечисленияENUM
. SET('значение1','значение2',...)
-
Набор. Объект строки может иметь ноль или более значений, каждое из
которых должно быть выбрано из заданного списка величин
'значение1'
,'значение2'
,...
СписокSET
может содержать максимум 64 элемента. See section 6.2.3.4 Тип множестваSET
.
6.2.1 Числовые типы данных
MySQL поддерживает все числовые типы данных языка SQL92 по стандартам
ANSI/ISO. Они включают в себя типы точных числовых данных (NUMERIC
,
DECIMAL
, INTEGER
и SMALLINT
) и типы приближенных числовых данных (FLOAT
,
REAL
и DOUBLE PRECISION
). Ключевое слово INT
является синонимом для
INTEGER
, а ключевое слово DEC
- синонимом для DECIMAL
.
Типы данных NUMERIC
и DECIMAL
реализованы в MySQL как один и тот же тип -
это разрешается стандартом SQL92. Они используются для величин, для
которых важно сохранить повышенную точность, например для денежных данных.
Требуемая точность данных и масштаб могут задаваться (и обычно задаются)
при объявлении столбца данных одного из этих типов, например:
salary DECIMAL(5,2)
В этом примере - 5
(точность) представляет собой общее количество значащих
десятичных знаков, с которыми будет храниться данная величина, а цифра 2
(масштаб) задает количество десятичных знаков после запятой.
Следовательно, в этом случае интервал величин, которые могут храниться в
столбце salary
, составляет от -99,99
до 99,99
(в действительности для
данного столбца MySQL обеспечивает возможность хранения чисел вплоть до
999,99
, поскольку можно не хранить знак для положительных чисел).
В SQL92 по стандарту ANSI/ISO выражение DECIMAL(p)
эквивалентно
DECIMAL(p,0)
. Аналогично, выражение DECIMAL
также эквивалентно
DECIMAL(p,0)
, при этом предполагается, что величина p
определяется
конкретной реализацией. В настоящее время MySQL не поддерживает ни одну из
рассматриваемых двух различных форм типов данных DECIMAL/NUMERIC
. В общем
случае это не является серьезной проблемой, так как основные преимущества
данных типов состоят в возможности явно управлять как точностью, так и
масштабом представления данных.
Величины типов DECIMAL
и NUMERIC
хранятся как строки, а не как двоичные
числа с плавающей точкой, чтобы сохранить точность представления этих
величин в десятичном виде. При этом используется по одному символу строки
для каждого разряда хранимой величины, для десятичного знака (если масштаб > 0
)
и для знака `-' (для отрицательных чисел). Если параметр масштаба
равен 0
,
то величины DECIMAL
и NUMERIC
не содержат десятичного знака или дробной
части.
Максимальный интервал величин DECIMAL
и NUMERIC
тот же, что и для типа
DOUBLE
, но реальный интервал может быть ограничен выбором значений
параметров точности
или масштаба
для данного столбца с типом данных DECIMAL
или NUMERIC
. Если конкретному столбцу присваивается значение, имеющее
большее количество разрядов после десятичного знака, чем разрешено
параметром масштаба
, то данное значение округляется до количества разрядов,
разрешенного масштаба
. Если столбцу с типом DECIMAL
или NUMERIC
присваивается значение, выходящее за границы интервала, заданного
значениями точности
и масштаба
(или принятого по умолчанию), то MySQL
сохранит данную величину со значением соответствующей граничной точки
данного интервала.
В качестве расширения стандарта ANSI/ISO SQL92 MySQL также поддерживает
числовые типы представления данных TINYINT
, MEDIUMINT
и BIGINT
, кратко
описанные в таблице выше. Еще одно расширение указанного стандарта,
поддерживаемое MySQL, позволяет при необходимости указывать количество
показываемых пользователю символов целого числа в круглых скобках,
следующих за базовым ключевым словом данного типа (например INT(4)
). Это
необязательное указание количества выводимых символов используется для
дополнения слева выводимых значений, которые содержат символов меньше, чем
заданная ширина столбца, однако не накладывает ограничений ни на диапазон
величин, которые могут храниться в столбце, ни на количество разрядов,
которые могут выводиться для величин, у которых количество символов
превосходит ширину данного столбца. Если дополнительно указан
необязательный атрибут ZEROFILL
, свободные позиции по умолчанию
заполняются нолями. Например, для столбца, объявленного как INT(5)
ZEROFILL
, величина 4
извлекается как 00004
. Следует учитывать, что если в
столбце для целых чисел хранится величина с количеством символов,
превышающим заданную ширину столбца, могут возникнуть проблемы, когда
MySQL будет генерировать временные таблицы для некоторых сложных связей,
так как в подобных случаях MySQL полагает, что данные действительно
поместились в столбец имеющейся ширины.
Все типы целочисленных данных могут иметь необязательный и не оговоренный
в стандарте атрибут UNSIGNED
. Беззнаковые величины можно использовать для
разрешения записи в столбец только положительных чисел, если необходимо
немного увеличить числовой интервал в столбце.
В версии MySQL 4.0.2 числовые типы данных с плавающей точкой также могут
иметь параметр UNSIGNED
. Как и в целочисленных типах, этот атрибут
предотвращает хранение в отмеченном столбце отрицательных величин. Но, в
отличие от целочисленных типов, максимальный интервал для величин столбца
остается прежним.
Тип FLOAT
обычно используется для представления приблизительных числовых
типов данных. Стандарт ANSI/ISO SQL92 допускает факультативное указание
точности (но не интервала порядка числа) в битах в круглых скобках,
следующих за ключевым словом FLOAT
. Реализация MySQL также поддерживает
это факультативное указание точности. При этом если ключевое слово FLOAT
в
обозначении типа столбца используется без указания точности, MySQL
выделяет 4 байта для хранения величин в этом столбце. Возможно также иное
обозначение, с двумя числами в круглых скобках за ключевым словом FLOAT
. В
этом варианте первое число по-прежнему определяет требования к хранению
величины в байтах, а второе число указывает количество разрядов после
десятичной запятой, которые будут храниться и показываться (как для типов
DECIMAL
и NUMERIC
). Если в столбец подобного типа попытаться записать
число, содержащее больше десятичных знаков после запятой, чем указано для
данного столбца, то значение величины при ее хранении в MySQL округляется
для устранения излишних разрядов.
Для типов REAL
и DOUBLE PRECISION
не предусмотрены установки точности.
MySQL воспринимает DOUBLE
как синоним типа DOUBLE PRECISION
- это еще
одно расширение стандарта ANSI/ISO SQL92. Но, вопреки требованию
стандарта, указывающему, что точность для REAL
меньше, чем для DOUBLE
PRECISION
, в MySQL оба типа реализуются как 8-байтовые числа с плавающей
точкой удвоенной точности (если не установлен ``ANSI-режим''). Чтобы
обеспечить максимальную совместимость, в коде, требующем хранения
приблизительных числовых величин, должны использоваться типы FLOAT
или
DOUBLE PRECISION
без указаний точности или количества десятичных знаков.
Если в числовой столбец попытаться записать величину, выходящую за границы допустимого интервала для столбца данного типа, то MySQL ограничит величину до соответствующей граничной точки данного интервала и сохранит результат вместо исходной величины.
Например, интервал столбца INT
составляет от -2147483648
до 2147483647
.
Если попытаться записать в столбец INT
число -9999999999
, то оно будет
усечено до нижней конечной точки интервала и вместо записываемого значения
в столбце будет храниться величина -2147483648
. Аналогично, если
попытаться записать число 9999999999
, то взамен запишется число
2147483647
.
Если для столбца INT
указан параметр UNSIGNED
, то величина допустимого
интервала для столбца останется той же, но его граничные точки сдвинутся к
0
и 4294967295
. Если попытаться записать числа -9999999999
и 9999999999
,
то в столбце окажутся величины 0
и 4294967296
.
Для команд ALTER TABLE
, LOAD DATA INFILE
, UPDATE
и многострочной INSERT
выводится предупреждение, если могут возникнуть преобразования данных
вследствие вышеописанных усечений.
Тип | Байт | От | До |
TINYINT | 1 | -128 | 127 |
SMALLINT | 2 | -32768 | 32767 |
MEDIUMINT | 3 | -8388608 | 8388607 |
INT | 4 | -2147483648 | 2147483647 |
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
6.2.2 Типы данных даты и времени
Существуют следующие типы данных даты и времени: DATETIME
, DATE
,
TIMESTAMP
, TIME
и YEAR
. Каждый из них имеет интервал допустимых значений,
а также значение ``ноль'', которое используется, когда пользователь вводит
действительно недопустимое значение. Отметим, что MySQL позволяет хранить
некоторые не вполне достоверные значения даты, например 1999-11-31
.
Причина в том, что, по нашему мнению, управление проверкой даты входит в
обязанности конкретного приложения, а не SQL-серверов. Для ускорения
проверки правильности даты MySQL только проверяет, находится ли месяц в
интервале 0-12
и день в интервале 0-31
. Данные интервалы начинаются с 0
,
это сделано для того, чтобы обеспечить для MySQL возможность хранить в
столбцах DATE
или DATETIME
даты, в которых день или месяц равен нулю. Эта
возможность особенно полезна для приложений, которые предполагают хранение
даты рождения - здесь не всегда известен день или месяц рождения. В таких
случаях дата хранится просто в виде 1999-00-00
или 1999-01-00
(при этом не
следует рассчитывать на то, что для подобных дат функции DATE_SUB()
или
DATE_ADD
дадут правильные значения).
Ниже приведены некоторые общие соображения, полезные при работе с типами данных даты и времени:
-
MySQL извлекает значения для данного типа даты или времени только в
стандартном формате, но в то же время пытается интерпретировать
разнообразные форматы, которые могут поступать от пользователей
(например, когда задается величина, которой следует присвоить тип даты
или времени или сравнить со значением, имеющим один из этих типов).
Тем не менее, поддерживаются только форматы, описанные в следующих
разделах. Предполагается, что пользователь будет вводить допустимые
значения величин, так как использование величин в других форматах
может дать непредсказуемые результаты.
-
Хотя MySQL пытается интерпретировать значения в нескольких форматах,
во всех случаях ожидается, что крайним слева будет раздел значения
даты, содержащий год. Даты должны задаваться в порядке
год-месяц-день
(например,'98-09-04'
), а не в порядкемесяц-день-год
илидень-месяц-год
, т.е. не так, как мы их обычно записываем (например'09-04-98'
,'04-09-98'
). - MySQL автоматически преобразует значение, имеющее тип даты или времени, в число, если данная величина используется в числовом контексте, и наоборот.
-
Значение, имеющее тип даты или времени, которое выходит за границы
установленного интервала или является недопустимым для этого типа
данных (см. начало раздела), преобразуется в значение ``ноль'' для
данного типа. (Исключение составляют выходящие за границы
установленного интервала величины типа
TIME
, которые усекаются до соответствующей граничной точки заданного интервалаTIME
). В следующей таблице представлены форматы значения ``ноль'' для каждого из типов столбцов:Тип столбца Значение ``Ноль'' DATETIME
'0000-00-00 00:00:00'
DATE
'0000-00-00'
TIMESTAMP
00000000000000
(длина зависит от количества выводимых символов)TIME
'00:00:00'
YEAR
0000
- Значения ``ноль'' - особые. Для их хранения или ссылок на них можно явно применять представленные в таблице значения, а можно использовать `0' или `0', что легче в написании.
-
Значения ``ноль'' даты или времени при использовании MyODBC
автоматически конвертируются в
NULL
в версии MyODBC 2.50.12 и выше, так как ODBC не оперирует с подобными величинами.
6.2.2.1 Проблема 2000 года и типы данных
Ядро MySQL само по себе устойчиво к ``проблеме 2000 года'' (see section 1.4.5 Вопросы, связанные с Проблемой-2000), но некоторые представленные в MySQL входные величины могут являться источниками ошибок. Так, любое вводимое значение, содержащее двухразрядное значение года, является неоднозначным, поскольку неизвестно столетие. Подобные величины должны быть переведены в четырехразрядную форму, так как для внутреннего представления года в MySQL используется 4 разряда.
Для типов DATETIME
, DATE
, TIMESTAMP
и YEAR
даты с неоднозначным годом
интерпретируются в MySQL по следующим правилам:
-
Величина года в интервале
00-69
конвертируется в2000-2069
. -
Величина года в интервале
70-99
конвертируется в1970-1999
.
Следует помнить, что эти правила дают только правдоподобные предположения о том, что ваши данные в действительности означают. Если применяемая MySQL эвристика не дает правильных величин, необходимо обеспечить недвусмысленные входные данные, содержащие четырехразрядные величины года.
ORDER BY
отсортирует двухразрядные YEAR/DATE/DATETIME
типы корректно.
Необходимо также отметить, что некоторые функции, такие как MIN()
и MAX()
будут преобразовывать TIMESTAMP/DATE
в число. Это означает, что столбец с
данными типа TIMESTAMP
, содержащими год в виде двух разрядов, не будет
правильно работать с указанными функциями. Выход из этого положения
состоит в преобразовании TIMESTAMP/DATE
к четырехразрядному формату или
использовании чего-нибудь вроде MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS))
.
6.2.2.2 Типы данных DATETIME
, DATE
и TIMESTAMP
Типы DATETIME
, DATE
и TIMESTAMP
являются родственными типами данных. В
данном разделе описаны их свойства, общие черты и различия.
Тип данных DATETIME
используется для величин, содержащих информацию как о
дате, так и о времени. MySQL извлекает и выводит величины DATETIME
в
формате 'YYYY-MM-DD HH:MM:SS'
. Поддерживается диапазон величин от
'1000-01-01 00:00:00'
до '9999-12-31 23:59:59'
. (''поддерживается''
означает, что хотя величины с более ранними временными значениями,
возможно, тоже будут работать, но нет гарантии того, что они будут
правильно храниться и отображаться).
Тип DATE
используется для величин с информацией только о дате, без части,
содержащей время. MySQL извлекает и выводит величины DATE
в формате
'YYYY-MM-DD'
. Поддерживается диапазон величин от '1000-01-01'
до
'9999-12-31'
.
Тип столбца TIMESTAMP
обеспечивает тип представления данных, который можно
использовать для автоматической записи текущих даты и времени при
выполнении операций INSERT
или UPDATE
. При наличии нескольких столбцов
типа TIMESTAMP
только первый из них обновляется автоматически.
Автоматическое обновление первого столбца с типом TIMESTAMP
происходит при
выполнении любого из следующих условий:
-
Столбец не указан явно в команде
INSERT
илиLOAD DATA INFILE
. -
Столбец не указан явно в команде
UPDATE
, и при этом изменяется величина в некотором другом столбце (следует отметить, что командаUPDATE
, устанавливающая столбец в то же самое значение, которое было до выполнения команды, не вызовет обновления столбцаTIMESTAMP
, поскольку в целях повышения производительности MySQL игнорирует подобные обновления при установке столбца в его текущее значение). -
Величина в столбце
TIMESTAMP
явно установлена вNULL
.
Для остальных (кроме первого) столбцов типа TIMESTAMP
также можно задать
установку в значение текущих даты и времени. Для этого необходимо просто
установить столбец в NULL
или в NOW()
.
Любой столбец типа TIMESTAMP
(даже первый столбец данного типа) можно
установить в значение, отличное от текущих даты и времени. Это делается
путем явной установки его в желаемое значение. Данное свойство можно
использовать, например, если необходимо установить столбец TIMESTAMP
в
значение текущих даты и времени при создании строки, а при последующем
обновлении этой строки значение столбца не должно изменяться:
-
Пусть MySQL автоматически установит значение столбца с типом
TIMESTAMP
при создании данной строки. Столбец будет установлен в исходное состояние со значением текущих даты и времени. -
При выполнении последующих обновлений других столбцов в данной строке
необходимо явно установить столбец
TIMESTAMP
в его текущее значение.
Однако, с другой стороны, для этих целей, возможно, будет проще
использовать столбец DATETIME
. При создании строки его следует
инициализировать функцией NOW()
и оставить в покое при последующих
обновлениях.
Величины типа TIMESTAMP
могут принимать значения от начала 1970
года до
некоторого значения в 2037
году с разрешением в одну секунду. Эти величины
выводятся в виде числовых значений.
Формат данных, в котором MySQL извлекает и показывает величины TIMESTAMP
,
зависит от количества показываемых символов. Это проиллюстрировано в
приведенной ниже таблице. Полный формат TIMESTAMP
составляет 14 десятичных
разрядов, но можно создавать столбцы типа TIMESTAMP
и с более короткой
строкой вывода:
Тип столбца | Формат вывода |
TIMESTAMP(14) | YYYYMMDDHHMMSS
|
TIMESTAMP(12) | YYMMDDHHMMSS
|
TIMESTAMP(10) | YYMMDDHHMM
|
TIMESTAMP(8) | YYYYMMDD
|
TIMESTAMP(6) | YYMMDD
|
TIMESTAMP(4) | YYMM
|
TIMESTAMP(2) | YY
|
Независимо от размера выводимого значения размер данных, хранящихся в
столбцах типа TIMESTAMP
, всегда один и тот же. Чаще всего используется
формат вывода с 6, 8, 12 или 14 десятичными знаками. При создании таблицы
можно указать произвольный размер выводимых значений, однако если этот
размер задать равным 0 или превышающим 14, то будет использоваться
значение 14. Нечетные значения размеров в интервале от 1 до 13 будут
приведены к ближайшему большему четному числу.
Величины DATETIME
, DATE
и TIMESTAMP
могут быть заданы любым стандартным
набором форматов:
-
Как строка в формате
'YYYY-MM-DD HH:MM:SS'
или в формате'YY-MM-DD HH:MM:SS'
. Допускается ``облегченный'' синтаксис - можно использовать любой знак пунктуации в качестве разделительного между частями разделов даты или времени. Например, величины'98-12-31 11:30:45'
,'98.12.31 11+30+45'
,'98/12/31 11*30*45'
и'98@12@31 11^30^45'
являются эквивалентными. -
Как строка в формате
'YYYY-MM-DD'
или в формате'YY-MM-DD'
. Здесь также допустим ``облегченный'' синтаксис. Например, величины'98-12-31'
,'98.12.31'
,'98/12/31'
и'98@12@31'
являются эквивалентными. -
Как строка без разделительных знаков в формате
'YYYYMMDDHHMMSS'
или в формате'YYMMDDHHMMSS'
, при условии, что строка понимается как дата. Например, величины'19970523091528'
и'970523091528'
можно интерпретировать как'1997-05-23 09:15:28'
, но величина'971122129015'
является недопустимой (значение раздела минут является абсурдным) и преобразуется в'0000-00-00 00:00:00'
. -
Как строка без разделительных знаков в формате
'YYYYMMDD'
или в формате'YYMMDD'
, при условии, что строка интерпретируется как дата. Например, величины'19970523'
и'970523'
можно интерпретировать как'1997-05-23'
, но величина'971332'
является недопустимой (значения разделов месяца и дня не имеют смысла) и преобразуется в'0000-00-00'
. -
Как число в формате
YYYYMMDDHHMMSS
или в форматеYYMMDDHHMMSS
, при условии, что число интерпретируется как дата. Например, величины19830905132800
и830905132800
интерпретируются как'1983-09-05 13:28:00'
. -
Как число в формате
YYYYMMDD
или в форматеYYMMDD
, при условии, что число интерпретируется как дата. Например, величины19830905
и830905
интерпретируются как'1983-09-05'
. -
Как результат выполнения функции, возвращающей величину, приемлемую в
контекстах типов данных
DATETIME
,DATE
илиTIMESTAMP
(например, функцииNOW()
илиCURRENT_DATE()
.
Недопустимые значения величин DATETIME
, DATE
или TIMESTAMP
преобразуются в
значение ``ноль'' соответствующего типа величин ('0000-00-00 00:00:00'
,
'0000-00-00'
, или 00000000000000
).
Для величин, представленных как строки, содержащие разделительные знаки
между частями даты, нет необходимости указывать два разряда для значений
месяца или дня, меньших, чем 10
. Так, величина '1979-6-9'
эквивалентна
величине '1979-06-09'
. Аналогично, для величин, представленных как строки,
содержащие разделительные знаки внутри обозначения времени, нет
необходимости указывать два разряда для значений часов, минут или секунд,
меньших, чем 10
. Так,
Величины, определенные как числа, должны иметь 6
, 8
, 12
, или 14
десятичных
разрядов. Предполагается, что число, имеющее 8
или 14
разрядов,
представлено в форматах YYYYMMDD
или YYYYMMDDHHMMSS
соответственно, причем
год указан в первых четырех разрядах. Если же длина числа 6
или 12
разрядов, то предполагаются соответственно форматы YYMMDD
или
YYMMDDHHMMSS
, где год указан в первых двух разрядах. Числа, длина которых
не соответствует ни одному из описанных вариантов, интерпретируются как
дополненные спереди нулями до ближайшей вышеуказанной длины.
Величины, представленные строками без разделительных знаков,
интерпретируются с учетом их длины согласно приведенным далее правилам.
Если длина строки равна 8
или 14
символам, то предполагается, что год
задан первыми четырьмя символами. В противном случае предполагается, что
год задан двумя первыми символами. Строка интерпретируется слева направо,
при этом определяются значения для года, месяца, дня, часов, минут и
секунд для всех представленных в строке разделов. Это означает, что строка
с длиной меньше, чем 6
символов, не может быть использована. Например,
если задать строку вида '9903'
, полагая, что это будет означать март 1999
года, то MySQL внесет в таблицу ``нулевую'' дату. Год и месяц в данной
записи равны 99
и 03
соответственно, но раздел, представляющий день,
пропущен (значение равно нулю), поэтому в целом данная величина не
является достоверным значением даты.
При хранении допустимых величин в столбцах типа TIMESTAMP
используется
полная точность, указанная при их задании, независимо от количества
выводимых символов. Это свойство имеет несколько следствий:
-
Необходимо всегда указывать год, месяц и день даже для типов
TIMESTAMP(4)
илиTIMESTAMP(2)
. В противном случае задаваемая величина не будет допустимым значением даты и будет храниться как0
. -
При увеличении ширины узкого столбца
TIMESTAMP
путем использования командыALTER TABLE
будет выводиться ранее ``скрытая'' информация. -
И аналогично, при сужении столбца
TIMESTAMP
хранимая информация не будет потеряна, если не принимать во внимание, что при выводе информации будет выдаваться меньше. -
Хотя величины
TIMESTAMP
хранятся с полной точностью, непосредственно может работать с этим исходным хранимым значением величины только функцияUNIX_TIMESTAMP()
. Остальные функции оперируют форматированными значениями извлеченной величины. Это означает, что нельзя использовать такие функции, какHOUR()
илиSECOND()
, пока соответствующая часть величиныTIMESTAMP
не будет включена в ее форматированное значение. Например, разделHH
столбцаTIMESTAMP
не будет выводиться, пока количество выводимых символов не станет по меньшей мере равным10
, так что попытки использоватьHOUR()
для более коротких величинTIMESTAMP
приведут к бессмысленным результатам.
Величины одного типа даты можно в ряде случаев присвоить объекту другого типа даты. Однако при этом возможны некоторое изменение величины или потеря информации:
-
Если присвоить значение типа
DATE
объектуDATETIME
илиTIMESTAMP
, то в результирующей величине ``временная'' часть будет установлена в'00:00:00'
, так как величинаDATE
не содержит информации о времени. -
Если присвоить значение типа
DATE
,DATETIME
илиTIMESTAMP
объектуDATE
, то ``временная'' часть в результирующей величине будет удалена, так как типDATE
не включает информацию о времени. -
Несмотря на то что все величины
DATETIME
,DATE
иTIMESTAMP
могут быть указаны с использованием одного и того же набора форматов, следует помнить, что указанные типы имеют разные интервалы допустимых значений. Например, величины типаTIMESTAMP
не могут иметь значения даты более ранние, чем относящиеся к1970
году или более поздние, чем относящиеся к2037
году. Это означает, что такая дата, как'1968-01-01'
, будучи разрешенной для величины типаDATETIME
илиDATE
, недопустима для величины типаTIMESTAMP
и будет преобразована в0
при присвоении этому объекту.
Задавая величины даты, следует иметь в виду некоторые ``подводные камни'':
-
Упрощенный формат, который допускается для величин, заданных строками,
может ввести в заблуждение. Например, такая величина, как
'10:11:12'
, благодаря разделителю `:' могла бы оказаться величиной времени, но, используемая в контексте даты, она будет интерпретирована как год'2010-11-12'
. В то же время величина'10:45:15'
будет преобразована в'0000-00-00'
, так как для месяца значение'45'
недопустимо. -
Сервер MySQL выполняет только первичную проверку истинности даты: дни
00-31
, месяцы00-12
, года1000-9999
. Любая дата вне этого диапазона преобразуется в0000-00-00
. Следует отметить, что, тем не менее, при этом не запрещается хранить неверные даты, такие как2002-04-31
. Это позволяет веб-приложениям сохранять данные форм без дополнительной проверки. Чтобы убедиться в достоверности даты, выполняется проверка в самом приложении. -
Величины года, представленные двумя разрядами, допускают неоднозначное
толкование, так как неизвестно столетие. MySQL интерпретирует
двухразрядные величины года по следующим правилам:
-
Величины года в интервале
00-69
преобразуются в2000-2069
. -
Величины года в интервале
70-99
преобразуются в1970-1999
.
-
Величины года в интервале
6.2.2.3 Тип данных TIME
MySQL извлекает и выводит величины типа TIME
в формате 'HH:MM:SS'
(или в
формате 'HHH:MM:SS'
для больших значений часов). Величины TIME
могут
изменяться в пределах от '-838:59:59'
до '838:59:59'
. Причина того, что
``часовая'' часть величины может быть настолько большой, заключается в
том, что тип TIME
может использоваться не только для представления времени
дня (которое должно быть меньше 24 часов), но также для представления
общего истекшего времени или временного интервала между двумя событиями
(который может быть значительно больше 24 часов или даже отрицательным).
Величины TIME
могут быть заданы в различных форматах:
-
Как строка в формате
-
Как строка без разделителей в формате
'HHMMSS'
, при условии, что строка интерпретируется как дата. Например, величина'101112'
понимается как'10:11:12'
, но величина'109712'
будет недопустимой (значение раздела минут является абсурдным) и преобразуется в'00:00:00'
. -
Как число в формате
HHMMSS
, при условии, что строка интерпретируется как дата. Например, величина101112
понимается как'10:11:12'
. MySQL понимает и следующие альтернативные форматы:SS
,MMSS
,HHMMSS
,HHMMSS.дробная часть
. При этом следует учитывать, что хранения дробной части MySQL пока не обеспечивает. -
Как результат выполнения функции, возвращающей величину, приемлемую в
контексте типа данных типа
TIME
(например, такой функции, какCURRENT_TIME
).
'D HH:MM:SS.дробная часть'
(следует учитывать,
что MySQL пока не обеспечивает хранения дробной части величины в
столбце рассматриваемого типа). Можно также использовать одно из
следующих ``облегченных'' представлений: HH:MM:SS.дробная часть
,
HH:MM:SS
, HH:MM
, D HH:MM:SS
, D HH:MM
, D HH
или SS
. Здесь D
- это
дни из интервала значений 0-33
.
Для величин типа TIME
, представленных как строки, содержащие
разделительные знаки между частями значения времени, нет необходимости
указывать два разряда для значений часов, минут или секунд, меньших 10
.
Так, величина '8:3:2'
эквивалентна величине '08:03:02'
.
Будьте внимательны в отношении использования ``укороченных'' величин TIME
в столбце типа TIME
. MySQL интерпретирует выражения без разделительных
двоеточий исходя из предположения, что крайние справа разряды представляют
секунды (MySQL интерпретирует величины TIME
как общее истекшее время, а не
как время дня). Например, можно подразумевать, что величины '1112'
и 1112
обозначают '11:12:00'
(11 часов и 12 минут дня по показаниям часов), но
MySQL понимает их как '00:11:12'
(11 минут, 12 секунд). Подобно этому,
'12'
и 12
интерпретируются как '00:00:12'
. Величины TIME
с разделительными
двоеточиями, наоборот, всегда трактуются как время дня. Т.е. выражение
'11:12'
будет пониматься как '11:12:00'
, а не '00:11:12'
.
Величины, лежащие вне разрешенного интервала TIME
, но во всем остальном
представляющие собой допустимые значения, усекаются до соответствующей
граничной точки данного интервала. Например, величины '-850:00:00'
и
'850:00:00'
преобразуются соответственно в '-838:59:59'
и '838:59:59'
.
Недопустимые значения величин TIME
преобразуются в значение '00:00:00'
.
Отметим, что поскольку выражение '00:00:00'
само по себе представляет
разрешенное значение величины TIME
, то по хранящейся в таблице величине
'00:00:00'
невозможно определить, была ли эта величина изначально задана
как '00:00:00'
или является преобразованным значением недопустимой
величины.
6.2.2.4 Тип данных YEAR
Тип YEAR
- это однобайтный тип данных для представления значений года.
MySQL извлекает и выводит величины YEAR
в формате YYYY
. Диапазон возможных
значений - от 1901
до 2155
.
Величины типа YEAR
могут быть заданы в различных форматах:
-
Как четырехзначная строка в интервале значений от
'1901'
до'2155'
. -
Как четырехзначное число в интервале значений от
1901
до2155
. -
Как двухзначная строка в интервале значений от
'00'
до'99'
. Величины в интервалах от'00'
до'69'
и от'70'
до'99'
при этом преобразуются в величиныYEAR
в интервалах от2000
до2069
и от1970
до1999
соответственно. -
Как двухзначное число в интервале значений от
1
до99
. Величины в интервалах от1
до69
и от70
до99
при этом преобразуются в величиныYEAR
в интервалах от2001
до2069
и от1970
до1999
соответственно. Необходимо принять во внимание, что интервалы для двухзначных чисел и двухзначных строк несколько различаются, так как нельзя указать ``ноль'' непосредственно как число и интерпретировать его как2000
. Необходимо задать его как строку'0'
или'00'
, или же оно будет интерпретировано как0000
. -
Как результат выполнения функции, возвращающей величину, приемлемую в
контексте типа данных
YEAR
(такой какNOW()
).
Недопустимые величины YEAR
преобразуются в 0000
.
6.2.3 Символьные типы данных
Существуют следующие символьные типы данных: CHAR
, VARCHAR
, BLOB
, TEXT
,
ENUM
и SET
. В данном разделе дается описание их работы, требований к их
хранению и использования их в запросах.
Тип | Макс.размер | Байт |
TINYTEXT или TINYBLOB | 2^8-1 | 255 |
TEXT или BLOB | 2^16-1 (64K-1) | 65535 |
MEDIUMTEXT или MEDIUMBLOB | 2^24-1 (16M-1) | 16777215 |
LONGBLOB | 2^32-1 (4G-1) | 4294967295 |
6.2.3.1 Типы данных CHAR и VARCHAR
Типы данных CHAR
и VARCHAR
очень схожи между собой, но различаются по
способам их хранения и извлечения.
В столбце типа CHAR
длина поля постоянна и задается при создании таблицы.
Эта длина может принимать любое значение между 1
и 255
(что же касается
версии MySQL 3.23, то в ней длина столбца CHAR
может быть от 0
до 255
).
Величины типа CHAR
при хранении дополняются справа пробелами до заданной
длины. Эти концевые пробелы удаляются при извлечении хранимых величин.
Величины в столбцах VARCHAR
представляют собой строки переменной длины.
Так же как и для столбцов CHAR
, можно задать столбец VARCHAR
любой длины
между 1
и 255
. Однако, в противоположность CHAR
, при хранении величин типа
VARCHAR
используется только то количество символов, которое необходимо,
плюс один байт для записи длины. Хранимые величины пробелами не
дополняются, наоборот, концевые пробелы при хранении удаляются (описанный
процесс удаления пробелов отличается от предусмотренного спецификацией
ANSI SQL).
Если задаваемая в столбце CHAR
или VARCHAR
величина превосходит
максимально допустимую длину столбца, то эта величина соответствующим
образом усекается.
Различие между этими двумя типами столбцов в представлении результата
хранения величин с разной длиной строки в столбцах CHAR(4)
и
VARCHAR(4)
проиллюстрировано следующей таблицей:
Величина | CHAR(4) | Требуемая память | VARCHAR(4) | Требуемая память |
'' | ' ' | 4 байта | '' | 1 байт |
'ab' | 'ab ' | 4 байта | 'ab' | 3 байта |
'abcd' | 'abcd' | 4 байта | 'abcd' | 5 байтов |
'abcdefgh' | 'abcd' | 4 байта | 'abcd' | 5 байтов |
Извлеченные из столбцов CHAR(4)
и VARCHAR(4)
величины в каждом случае
будут одними и теми же, поскольку при извлечении концевые пробелы из
столбца CHAR удаляются.
Если при создании таблицы не был задан атрибут BINARY
для столбцов, то
величины в столбцах типа CHAR
и VARCHAR
сортируются и сравниваются без
учета регистра. При задании атрибута BINARY
величины в столбце сортируются
и сравниваются с учетом регистра в соответствии с порядком таблицы ASCII
на том компьютере, где работает сервер MySQL. Атрибут BINARY
не влияет на
процессы хранения или извлечения данных из столбца.
Атрибут BINARY
является ``прилипчивым''. Это значит, что, если в
каком-либо выражении использовать столбец, помеченный как BINARY
, то
сравнение всего выражения будет выполняться как сравнение величины типа
BINARY
.
MySQL может без предупреждения изменить тип столбца CHAR
или VARCHAR
во
время создания таблицы. See section 6.5.3.1 Молчаливые изменения определений столбцов.
6.2.3.2 Типы данных BLOB
и TEXT
Тип данных BLOB
представляет собой двоичный объект большого размера,
который может содержать переменное количество данных. Существуют 4
модификации этого типа - TINYBLOB
, BLOB
, MEDIUMBLOB
и LONGBLOB
,
отличающиеся только максимальной длиной хранимых величин.
See section 6.2.6 Требования к памяти для различных типов столбцов.
Тип данных TEXT
также имеет 4 модификации - TINYTEXT
, TEXT
, MEDIUMTEXT
и
LONGTEXT
, соответствующие упомянутым четырем типам BLOB
и имеющие те же
максимальную длину и требования к объему памяти. Единственное различие
между типами BLOB
и TEXT
состоит в том, что сортировка и сравнение данных
выполняются с учетом регистра для величин BLOB
и без учета регистра для
величин TEXT
. Другими словами, TEXT
- это независимый от регистра BLOB
.
Если размер задаваемого в столбце BLOB
или TEXT
значения превосходит
максимально допустимую длину столбца, то это значение соответствующим
образом усекается.
В большинстве случаев столбец TEXT
может рассматриваться как столбец
VARCHAR
неограниченного размера. И, аналогично, BLOB
- как столбец типа
VARCHAR BINARY
. Различия при этом следующие:
-
Столбцы типов
BLOB
иTEXT
могут индексироваться в версии MySQL 3.23.2 и более новых. Более старые версии MySQL не поддерживают индексацию этих столбцов. -
В столбцах типов
BLOB
иTEXT
не производится удаление концевых символов, как это делается для столбцов типаVARCHAR
. -
Для столбцов
BLOB
иTEXT
не может быть задан атрибутDEFAULT
- значения величин по умолчанию.
В MyODBC величины типа BLOB
определяются как LONGVARBINARY
и величины типа
TEXT - как LONGVARCHAR
.
Так как величины типов BLOB
и TEXT
могут быть чрезмерно большими, при их
использовании целесообразно предусмотреть некоторые ограничения:
-
Чтобы обеспечить возможность использования команд
GROUP BY
или ORDER
BY
в столбце типа BLOB
или TEXT
, необходимо преобразовать значение
столбца в объект с фиксированной длиной. Обычно это делается с помощью
функции SUBSTRING
. Например:
mysql> SELECT comment FROM tbl_name,SUBSTRING(comment,20) AS substr -> ORDER BY substr;Если этого не сделать, то операция сортировки в столбце будет выполнена только для первых байтов, количество которых задается параметром
max_sort_length
. Значение по умолчанию величины max_sort_length
равно
1024
; это значение можно изменить, используя параметр -O
сервера mysqld
при его запуске. Группировка выражения, включающего в себя величины BLOB
или TEXT
, возможна при указании позиции столбца или использовании
псевдонима:
mysql> SELECT id,SUBSTRING(blob_col,1,100) FROM tbl_name GROUP BY 2; mysql> SELECT id,SUBSTRING(blob_col,1,100) AS b FROM tbl_name GROUP BY b;
BLOB
или TEXT
определяется его типом,
но наибольшее значение, которое фактически может быть передано между
клиентом и сервером, ограничено величиной доступной памяти и размером
буферов связи. Можно изменить размер буфера блока передачи, но сделать
это необходимо как на стороне сервера, так и на стороне клиента.
See section 5.5.2 Настройка параметров сервера.
Следует учитывать, что внутренним представлением любой величины типа BLOB
или TEXT
является отдельно размещенный объект - в противоположность всем
остальным типам столбцов, для которых память выделяется единовременно для
столбца при открытии таблицы.
6.2.3.3 Тип перечисления ENUM
ENUM (перечисление) - это столбец, который может принимать значение из списка допустимых значений, явно перечисленных в спецификации столбца в момент создания таблицы.
Этим значением также может быть пустая строка ("") или NULL при определенных условиях:
- Если делается всавка некорректного значения в столбец ENUM (т.е. вставка строки, не перечисленной в списке допустимых), то вставляется пустая строка, что является указанием на ошибочное значение. Эта строка отличается от "обычной" пустой строки по тому признаку, что она имеет цифровое значение, равное 0. Об этом чуть ниже.
- Если ENUM определяется как NULL, то тогда NULL тоже является допустимым значением столбца и значение по умолчанию - NULL. Если ENUM определяется как NOT NULL, то значением по умолчанию является первый элемент из списка допустимых значений.
Каждая величина из допустимы имеет индекс:
- Значение из списка допустимых величин, определенных при создании таблицы нумеруются, начиная с 1.
-
Индекс пустой ошибочной строки - 0. Это означает что вы можете использовать следующий SELECT для того, чтобы найти записи, в которые были вставлены некорректные значения ENUM:
mysql> SELECT * FROM tbl_name WHERE enum_col=0;
- Индекс значения NULL - NULL.
Например, столбец, определенный как ENUM("один", "два", "три") может иметь любую из перечисленных величин. Индекс каждой величины также известен:
Величина | Индекс |
NULL | NULL
|
"" | 0 |
"один" | 1 |
"два" | 2 |
"три" | 3 |
Перечисление может иметь максимум 65535 элементов.
Начиная с 3.23.51, оконечные пробелы автоматически удаляются из величин этого столбца в момент создания таблицы.
Регистр не играет роли, когда вы делаете вставку в столбец ENUM. Однако регистр значений, получаемых из этого столбца, совпадает с регистром в написании соответствующего значения, заданного во время создания таблицы.
Если вы делаете выборку столбца ENUM в числовом контексте, возвращается индекс значения. Например, вы можете получить численное значение ENUM таким образом:
mysql> SELECT enum_col+0 FROM tbl_name;
Если вы вставляете число в столбец ENUM, это число воспринимается как индекс, и в таблицу записывается соответствующее этому индексу значение перечисления. (Однако, это не будет работать с LOAD DATA, который воспринимает все входящие данные как строки.) Не рекомендуется сохранять числа в перечислении, т.к. это может привести к излишней путаннице.
Значения перечисления сортируются в соответствии с порядком, в котором
допустимые значения были заданы при создании таблицы. (Другими словами,
значения ENUM сортируются в соответствии с ихними индексами.) Например,
"a"
в отсортированном выводе будет присутствовать раньше чем "b"
для ENUM("a", "b")
, но "b"
появится раньше "a"
для
ENUM("b","a")
. Пустые строки возвращаются перед непустыми строками, и
NULL-значения будут выведены в самую первую очередь.
Для предотвращения неожиданностей, указывайте список ENUM
в алфавитном
порядке. Вы также можете использовать GROUP BY CONCAT(col)
чтобы
удостовериться, что столбец отсортирован в алфавитном порядке, а не по индексу.
Если вам нужно получить список возможных значения для столбца ENUM, вы должны вызвать
SHOW COLUMNS FROM имя_таблицы LIKE имя_столбца_enum
и проанализировать определение ENUM во втором столбце.
6.2.3.4 Тип множества SET
SET - это строковый тип, который может принимать ноль или более значений, каждое из которых должно быть выбрано из списка допустимых значений, определенных при создании таблицы. Элементы множества SET разделяются запятыми. Как следствие, сами элементы множества не могут содержать запятых.
Например, столбец, определенный как SET("один", "два") NOT NULL
может принимать
такие значения:
"" "один" "два" "один,два"
Множество SET может иметь максимум 64 различных элемента.
Начиная с 3.23.51, оконечные пробелы удаляются из значений множества SET в момент создания таблицы.
MySQL сохраняет значения SET в численном виде, где младший бит сохраненной величины соответствует первому элементу множества. Если вы делаете выборку столбца SET в числовом контексте, полученное значение содержит соответствующим образом установленные биты, создающие значение столбца. Например, вы можете сделать выборку численного значения SET-столбца таким образом:
mysql> SELECT set_col+0 FROM tbl_name;
Если делается вставка в столбец SET, биты, установленные в двоичном
представлении числа определяют элементы множества. Допустим, столбец определен как
SET("a","b","c","d")
. Тогда элементы имеют такие биты установленными:
SET элемент | числовое значение | двоичное значение |
a | 1 | 0001
|
b | 2 | 0010
|
c | 4 | 0100
|
d | 8 | 1000
|
Если вы вставляет значение 9
в этот столбец, это соответствует 1001
в двоичном представлении,
так что первый ("a"
) и четвертый ("d"
) элементы множества выбираются, что в результате дает "a,d"
.
Для значения, содержащего более чем один элемент множестве, не играет никакой роли, в каком
порядке эти элементы перечисляются в момент вставки значения. Также не играет роли,
как много раз то или иное значение перечислено. Когда позже это значение выбирается, каждый
элемент будет присутствовать только единожды, и элементы будут перечислены в том порядке,
в котором они перечисляются в определении таблицы. Например, если столбец определен как
SET("a","b","c","d")
, тогда "a,d"
, "d,a"
, и
"d,a,a,d,d"
будут представлены как "a,d"
.
Если вы вставляете в столбец SET некорректую величины, это значение будет проигнорировано.
SET-значения сортируются в соответствии с числовым представлением. NULL-значения идут в первую очередь.
Обычно, следует выполнять SELECT
для SET-столбца, используя оператор LIKE
или функцию FIND_IN_SET()
:
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%'; mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
Но и такая форма также работает:
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2'; mysql> SELECT * FROM tbl_name WHERE set_col & 1;
Первый оператор в каждом примере делает выборку точного значения. Второй оператор делает выборку значений, содержащих первого элемента множества.
Если вам нужно получить все возможные значения для столбца SET, вам следует вызвать
SHOW COLUMNS FROM table_name LIKE set_column_name
и проанализировать SET-определение во втором столбце.
6.2.4 Выбор правильного типа данных в столбце
Для того чтобы память использовалась наиболее эффективно, всегда следует
стараться применять тип данных, обеспечивающий максимальную точность.
Например, для величин в диапазоне между 1
и 99999
в целочисленном столбце
наилучшим типом будет MEDIUMINT UNSIGNED
.
Часто приходится сталкиваться с такой проблемой, как точное представление
денежных величин. В MySQL для представления таких величин необходимо
использовать тип данных DECIMAL
. Поскольку данные этого типа хранятся в
виде строки, потерь в точности не происходит. А в случаях, когда точность
не имеет слишком большого значения, вполне подойдет и тип данных DOUBLE
.
Если же требуется высокая точность, всегда можно выполнить конвертирование
в тип данных с фиксированной точкой. Такие данные хранятся в виде BIGINT
.
Это позволяет выполнять все вычисления с ними как с целыми числами, а
впоследствии при необходимости результаты можно преобразовать обратно в
величины с плавающей точкой.
6.2.5 Использование типов столбцов из других баз данных
Чтобы облегчить использование SQL-кода, написанного для баз данных других поставщиков, в MySQL установлено соответствие типов столбцов, как показано в следующей таблице. Это соответствие упрощает применение описаний таблиц баз данных других поставщиков в MySQL:
Тип иного поставщика | Тип MySQL |
BINARY(NUM) | CHAR(NUM) BINARY
|
CHAR VARYING(NUM) | VARCHAR(NUM)
|
FLOAT4 | FLOAT
|
FLOAT8 | DOUBLE
|
INT1 | TINYINT
|
INT2 | SMALLINT
|
INT3 | MEDIUMINT
|
INT4 | INT
|
INT8 | BIGINT
|
LONG VARBINARY | MEDIUMBLOB
|
LONG VARCHAR | MEDIUMTEXT
|
MIDDLEINT | MEDIUMINT
|
VARBINARY(NUM) | VARCHAR(NUM) BINARY
|
Соотнесение типов столбцов происходит во время создания таблицы. При
создании таблицы с типами столбцов, которые используются другими
поставщиками, после запуска команды DESCRIBE имя_таблицы
выдается структура
данной таблицы с применением принятых в MySQL эквивалентных типов.
6.2.6 Требования к памяти для различных типов столбцов
Требования к объему памяти для столбцов каждого типа, поддерживаемого MySQL, перечислены ниже по категориям.
Требования к памяти для числовых типов
Тип столбца | Требуемая память |
TINYINT | 1 byte |
SMALLINT | 2 байта |
MEDIUMINT | 3 байта |
INT | 4 байта |
INTEGER | 4 байта |
BIGINT | 8 байтов |
FLOAT(X) | 4, если X <= 24 или 8, если 25 <= X <= 53 |
FLOAT | 4 байта |
DOUBLE | 8 байтов |
DOUBLE PRECISION | 8 байтов |
REAL | 8 байтов |
DECIMAL(M,D) | M+2 байт, если D > 0, M+1 байт, если D = 0 (D +2, если M < D )
|
NUMERIC(M,D) | M+2 байт, если D > 0, M+1 байт, если D = 0 (D +2, если M < D )
|
Требования к памяти для типов даты и времени
Тип столбца | Требуемая память |
DATE | 3 байта |
DATETIME | 8 байтов |
TIMESTAMP | 4 байта |
TIME | 3 байта |
YEAR | 1 байт |
Требования к памяти для символьных типов
Тип столбца | Требуемая память |
CHAR(M) | M байт, 1 <= M <= 255
|
VARCHAR(M) | L +1 байт, где L <= M и 1 <= M <= 255
|
TINYBLOB , TINYTEXT | L +1 байт, где L < 2^8
|
BLOB , TEXT | L +2 байт, где L < 2^16
|
MEDIUMBLOB , MEDIUMTEXT | L +3 байт, где L < 2^24
|
LONGBLOB , LONGTEXT | L +4 байт, где L < 2^32
|
ENUM('value1','value2',...) | 1 или 2 байт, в зависимости от количества перечисляемых величин (максимум 65535) |
SET('value1','value2',...) | 1, 2, 3, 4 или 8 байт, в зависимости от количества элементов множества (максимум 64) |
VARCHAR
, BLOB
и TEXT
являются типами данных с переменной длиной строки,
для таких типов требования к памяти в общем случае определяются реальным
размером величин в столбце (представлен символом L
в приведенной выше
таблице), а не максимально возможным для данного типа размером. Например,
столбец VARCHAR(10)
может содержать строку с максимальной длиной 10
символов. Реально требуемый объем памяти равен длине строки (L
) плюс 1
байт для записи длины строки. Для строки 'abcd'
L
равно 4 и требуемый
объем памяти равен 5 байтов.
В случае типов данных BLOB
и TEXT
требуется 1, 2, 3 или 4 байта для записи
длины значения данного столбца в зависимости от максимально возможной
длины для данного типа. See section 6.2.3.2 Типы данных BLOB
и TEXT
.
Если таблица включает в себя столбец какого-либо типа с переменной длиной строки, то формат записи также будет переменной длины. Следует учитывать, что при создании таблицы MySQL может при определенных условиях преобразовать тип столбца с переменной длиной в тип с постоянной длиной строки или наоборот. See section 6.5.3.1 Молчаливые изменения определений столбцов.
Размер объекта ENUM
определяется количеством различных перечисляемых
величин. Один байт используется для перечисления до 255
возможных величин.
Используя два байта, можно перечислить до 65535
величин. See section 6.2.3.3 Тип перечисления ENUM
.
Размер объекта SET
определяется количеством различных элементов
множества. Если это количество равно N
, то размер объекта вычисляется
по формуле (N+7)/8
и полученное число округляется до 1
, 2
,
3
, 4
или 8
байтов. Множество SET
может иметь
максимум 64
элемента. See section 6.2.3.4 Тип множества SET
.
Максимальный размер записи в MyISAM составляет 65534 байтов. Каждый BLOB
или
TEXT
-столбец засчитывается здесь как 5-9 байтов.
6.3 Функции, используемые в операторах SELECT
и WHERE
В команде SQL выражение SELECT
или определение WHERE
могут включать в
себя любое выражение, в котором используются описанные ниже функции.
Выражение, содержащее NULL
, всегда будет давать в результате величину
NULL
, если иное не оговорено в документации для операторов и функций,
задействованных в данном выражении.
Примечание: между именем функции и следующими за ним скобками не должно быть пробелов. Это поможет синтаксическому анализатору MySQL отличать вызовы функций от ссылок на таблицы или столбцы, имена которых случайно окажутся теми же, что и у функций. Однако допускаются пробелы до или после аргументов.
Если нужно, чтобы в MySQL допускались пробелы после имени функции, следует
запустить mysqld
с параметром --ansi
или использовать CLIENT_IGNORE_SPACE
в mysql_connect()
, но в этом случае все имена функций станут
зарезервированными словами. See section 1.9.2 Запуск MySQL в режиме ANSI.
В целях упрощения в данной документации результат выполнения программы
mysql
в примерах представлен в сокращенной форме. Таким образом вывод:
mysql> SELECT MOD(29,9); 1 rows in set (0.00 sec) +-----------+ | mod(29,9) | +-----------+ | 2 | +-----------+
будет представлен следующим образом:
mysql> SELECT MOD(29,9); -> 2
6.3.1 Операторы и функции общего назначения
6.3.1.1 Круглые скобки
( ... )
Круглые скобки используются для задания порядка вычислений в выражении. Например:
mysql> SELECT 1+2*3; -> 7 mysql> SELECT (1+2)*3; -> 9
6.3.1.2 Операторы сравнения
Операторы сравнения дают в результате величину 1
(истина, TRUE), 0
(ложь, FALSE) или
NULL
. Эти функции работают как с числами, так и со строками. Строки при
необходимости автоматически преобразуются в числа, а числа - в строки (как
в Perl).
Операции сравнения в MySQL выполняются по следующим правилам:
-
Если один или оба аргумента -
NULL
, то и результат сравнения будетNULL
. Справедливо для всех операторов кроме<=>
. - Если оба аргумента в операторе сравнения являются строками, то они сравниваются как строки.
- Если оба аргумента - целые числа, то они сравниваются как целые числа.
- Шестнадцатеричные величины, если они не сравниваются с числом, трактуются как строки с двоичными данными.
-
Если один из аргументов представляет собой столбец типа
TIMESTAMP
илиDATETIME
, а второй аргумент - константа, то константа перед выполнением сравнения преобразуется к типуTIMESTAMP
. Это сделано для лучшей совместимости с ODBC. - Во всех других случаях аргументы сравниваются как действительные числа с плавающей точкой.
По умолчанию сравнение строк производится без учета регистра символов с использованием текущего набора символов (по умолчанию ISO-8859-1 Latin1, который, к тому же, прекрасно подходит для английского языка).
Ниже приведены примеры, иллюстрирующие преобразование строк в числа для операторов сравнения:
mysql> SELECT 1 > '6x'; -> 0 mysql> SELECT 7 > '6x'; -> 1 mysql> SELECT 0 > 'x6'; -> 0 mysql> SELECT 0 = 'x6'; -> 1
=
-
Равно:
mysql> SELECT 1 = 0; -> 0 mysql> SELECT '0' = 0; -> 1 mysql> SELECT '0.0' = 0; -> 1 mysql> SELECT '0.01' = 0; -> 0 mysql> SELECT '.01' = 0.01; -> 1
<>
!=
-
Не равно:
mysql> SELECT '.01' <> '0.01'; -> 1 mysql> SELECT .01 <> '0.01'; -> 0 mysql> SELECT 'zapp' <> 'zappp'; -> 1
<=
-
Меньше или равно:
mysql> SELECT 0.1 <= 2; -> 1
<
-
Меньше чем:
mysql> SELECT 2 < 2; -> 0
>=
-
Больше или равно:
mysql> SELECT 2 >= 2; -> 1
>
-
Больше чем:
mysql> SELECT 2 > 2; -> 0
<=>
-
NULL-безопасное сравнение (равно):
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1 1 0
IS NULL
IS NOT NULL
-
Тест для определения, является величина равной
NULL
или нет:mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL; -> 0 0 1 mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL; -> 1 1 0
Для того, чтобы MySQL хорошо работал с другими программами, обеспечивается поддержка следующих дополнительных возможностей для функцииIS NULL
:-
Можно найти последнюю вставленную строку, используя выражение:
SELECT * FROM tbl_name WHERE auto_col IS NULL
Это свойство можно блокировать установкойSQL_AUTO_IS_NULL=0
. See section 5.5.6 Синтаксис командыSET
. -
Для данных типа
NOT NULL DATE
и столбцовDATETIME
можно найти особую дату0000-00-00
, используя выражение:SELECT * FROM tbl_name WHERE date_column IS NULL
Это необходимо для работы некоторых приложений ODBC (так как ODBC не поддерживает значение даты0000-00-00
).
-
Можно найти последнюю вставленную строку, используя выражение:
expr BETWEEN min AND max
-
Если величина выражения expr больше или равна заданному значению
min
и меньше или равна заданному значениюmax
, то функцияBETWEEN
возвращает1
, в противном случае -0
. Это эквивалентно выражению (min <= expr AND expr <= max
), в котором все аргументы представлены одним и тем же типом данных. В противном случае имеет место быть преобразование типов так, как сказано выше, но применительно ко всем трем аргументами. Внимание: до 4.0.5 аргументы приводились к типуexpr
.mysql> SELECT 1 BETWEEN 2 AND 3; -> 0 mysql> SELECT 'b' BETWEEN 'a' AND 'c'; -> 1 mysql> SELECT 2 BETWEEN 2 AND '3'; -> 1 mysql> SELECT 2 BETWEEN 2 AND 'x-3'; -> 0
expr NOT BETWEEN min AND max
-
То же справедливо и для функции
NOT (expr BETWEEN min AND max)
. expr IN (value,...)
-
Возвращает
1
, если выражение expr равно любой величине из спискаIN
, иначе -0
. Если все величины - константы, то они оцениваются в соответствии с типом выражения expr и сортируются. Поиск элемента в этом случае производится методом логического поиска. Это означает, что функцияIN
является очень быстрой, если список значенийIN
состоит полностью из констант. Если expr является зависимым от регистра строковым выражением, то сравнение строк производится с учетом регистра:mysql> SELECT 2 IN (0,3,5,'wefwf'); -> 0 mysql> SELECT 'wefwf' IN (0,3,5,'wefwf'); -> 1
Начиная с 4.1 (в соответствии со стандартом SQL-99),IN
возвращаетNULL
не только если выражение в левой части являетсяNULL
, но также если не найдено соответствия в списке и одно из выражений в списке является величинойNULL
. expr NOT IN (value,...)
-
То же справедливо и для функции
NOT (expr IN (value,...))
. ISNULL(expr)
-
Если
expr
равноNULL
, тоISNULL()
возвращает1
, в противном случае -0
:mysql> SELECT ISNULL(1+1); -> 0 mysql> SELECT ISNULL(1/0); -> 1
Обратите внимание: при сравнении величинNULL
с использованием оператора=
всегда будет возвращаться значениеFALSE
! COALESCE(list)
-
Возвращает первый в списке элемент со значением, не равным
NULL
:mysql> SELECT COALESCE(NULL,1); -> 1 mysql> SELECT COALESCE(NULL,NULL,NULL); -> NULL
INTERVAL(N,N1,N2,N3,...)
-
Возвращает
0
, еслиN < N1
, и1
, еслиN < N2
, и так далее. Все аргументы трактуются как целые числа. Для корректной работы этой функции необходимо условиеN1 < N2 < N3 < ... < Nn
. Это обусловлено тем, что используется логический поиск (очень быстрый):mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200); -> 3 mysql> SELECT INTERVAL(10, 1, 10, 100, 1000); -> 2 mysql> SELECT INTERVAL(22, 23, 30, 44, 200); -> 0
Если регистронезависимая строка сравнивается с помощью любого
стандартного оператора (=,
<>
, ..., но не LIKE
), то конечные пустые символы (т.е. пробелы, табуляторы и переводы строк) игнорируются:
игнорируется.
mysql> SELECT "a" ="A \n"; -> 1
6.3.1.3 Логические операторы
В SQL, все логические операторы возвращают
TRUE (ИСТИНА), FALSE (ЛОЖЬ) или NULL (UNKNOWN, неизвестно).
В MySQL это реализовано как 1
(TRUE, ИСТИНА), 0
(FALSE, ЛОЖЬ)
или NULL
. Это справедливо для большинства SQL СУБД, однако некоторые
возвращают любое положительное значение как значение TRUE.
NOT
!
-
Логическое НЕ.
Возвращает
1
, если операнд равен0
,0
если операнд - ненулевая величина, иNOT NULL
возвращаетNULL
.mysql> SELECT NOT 10; -> 0 mysql> SELECT NOT 0; -> 1 mysql> SELECT NOT NULL; -> NULL mysql> SELECT ! (1+1); -> 0 mysql> SELECT ! 1+1; -> 1
Последний пример дает1
, поскольку данное выражение вычисляется тем же способом, что и(!1)+1
. AND
&&
-
Логическое И.
Дает
1
если все операнды ненулевые и неNULL
,0
если один или более операндов равны0
, илиNULL
в остальных случаях.mysql> SELECT 1 && 1; -> 1 mysql> SELECT 1 && 0; -> 0 mysql> SELECT 1 && NULL; -> NULL mysql> SELECT 0 && NULL; -> 0 mysql> SELECT NULL && 0; -> 0
Обратите внимание, что версии MySQL до 4.0.5 прекращали вычисление, встретив первыйNULL
, вместо того, чтобы продолжать вычисление выражений с целью нахождения возможных значений0
. Это означает, что в этих версиях выражениеSELECT (NULL AND 0)
возвращаетNULL
вместо0
. В 4.0.5 код был переписан так, чтобы оптимизация сохранилась, но результат всегда был таков, как требует того ANSI. OR
||
-
Логическое ИЛИ.
Возвращает
1
, если любой из операндов не0
,NULL
если один из операндовNULL
, в остальных случаях возвращает0
.mysql> SELECT 1 || 1; -> 1 mysql> SELECT 1 || 0; -> 1 mysql> SELECT 0 || 0; -> 0 mysql> SELECT 0 || NULL; -> NULL mysql> SELECT 1 || NULL; -> 1
XOR
-
Логический XOR (побитовое сложение по модулю 2) Возвращает
NULL
если любой из операндов -NULL
. Для не-NULL
операндов, возвращает1
если нечетное количество операндов - не0
.mysql> SELECT 1 XOR 1; -> 0 mysql> SELECT 1 XOR 0; -> 1 mysql> SELECT 1 XOR NULL; -> NULL mysql> SELECT 1 XOR 1 XOR 1; -> 1
a XOR b
математически эквалиентно(a AND (NOT b)) OR ((NOT a) and b)
.XOR
был реализован в 4.0.2.
6.3.1.4 Функции потока управления программой
IFNULL(expr1,expr2)
-
Если
expr1
не равноNULL
, то функцияIFNULL()
возвращает значениеexpr1
, в противном случае -expr2
. В зависимости от контекста функцияIFNULL()
может возвращать либо числовое, либо строковое значение:mysql> SELECT IFNULL(1,0); -> 1 mysql> SELECT IFNULL(NULL,10); -> 10 mysql> SELECT IFNULL(1/0,10); -> 10 mysql> SELECT IFNULL(1/0,'yes'); -> 'yes'
В 4.0.6 и раньше по умолчанию возвращал дляIFNULL(expr1,expr2)
более "общее" из двух выражений в порядкеSTRING
,REAL
илиINTEGER
. Разница с более ранними версиями MySQL больше всего заметна тогда, когда вы создаете таблицу, основанную на выражении или MySQL внутренне сохраняет величину, основанную на выраженииIFNULL()
во временной таблице.CREATE TABLE foo SELECT IFNULL(1,"test") as test;
В 4.0.6 тип для столбца "test" -CHAR(4)
в то время как на более ранних типом был быBIGINT
. NULLIF(expr1,expr2)
-
Если выражение
expr1 = expr2
истинно, то возвращаетNULL
, в противном случае -expr1
. Эквивалентна операторуCASE WHEN x = y THEN NULL ELSE x END
:mysql> SELECT NULLIF(1,1); -> NULL mysql> SELECT NULLIF(1,2); -> 1
Отметим, что если аргументы не равны, то величинаexpr1
вычисляется в MySQL дважды. IF(expr1,expr2,expr3)
-
Если
expr1
равно значению ИСТИНА (expr1 <> 0
иexpr1 <> NULL
), то функцияIF()
возвращаетexpr2
, в противном случае -expr3
. В зависимости от контекста функцияIF()
может возвращать либо числовое, либо строковое значение:mysql> SELECT IF(1>2,2,3); -> 3 mysql> SELECT IF(1<2,'yes','no'); -> 'yes' mysql> SELECT IF(STRCMP('test','test1'),'no','yes'); -> 'no'
Еслиexpr2
илиexpr3
являютсяNULL
тогда результирующим типомIF()
будет тип, который не естьNULL
. Это нововведение в MySQL 4.0.3.expr1
вычисляется как целое число; это означает, что при исследовании чисел с плавающей точкой или строковых величин в этой функции необходимо использовать операцию сравнения:mysql> SELECT IF(0.1,1,0); -> 0 mysql> SELECT IF(0.1<>0,1,0); -> 1
В первом случае из приведенных выше функцияIF(0.1)
возвращает0
, так как0.1
преобразуется в целое число и в результате выполняется функцияIF(0)
. Но это вовсе не то, что должно было бы получиться. Во втором случае исходная величина с плавающей точкой исследуется при помощи оператора сравнения, чтобы определить, является ли она ненулевой, и в качестве аргумента функции используется результат сравнения - целое число. В версии MySQL 3.23 возвращаемый по умолчанию тип функцииIF()
(это может иметь значение при сохранении его во временной таблице) вычисляется, как показано ниже:
ЕслиВыражение Возвращаемая величина expr2 или expr3 возвращает строку строка expr2 or expr3 возвращает величину с плавающей точкой с плавающей точкой expr2 or expr3 возвращает целое число целое число expr2
иexpr3
являются строками, и обе регистро-независимы, то и результат является регистро-независимым (начиная с 3.23.51). CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END
-
В первом варианте возвращается значение
result
, еслиvalue=compare-value
. Во втором - результат для первого указанного условияcondition
, если оно истинно. Если соответствующая величина результата не определена, то возвращается значениеresult
, указанное после оператораELSE
. Если частьELSE
в выражении отсутствует, возвращаетсяNULL
:mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END; -> "one" mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END; -> "true" mysql> SELECT CASE BINARY "B" WHEN "a" THEN 1 WHEN "b" THEN 2 END; -> NULL
Тип возвращаемой величины будет такой же (INTEGER
, DOUBLE
или STRING
),
как и у первой возвращаемой величины (выражение после первого оператора
THEN
).
6.3.2 Строковые функции
Строковые функции возвращают NULL
, если длина результата оказывается
больше, чем указано в значении серверного параметра max_allowed_packet
.
See section 5.5.2 Настройка параметров сервера.
Для функций, работающих с позициями в строке, нумерация позиций начинается с 1.
-
Возвращает значение ASCII-кода крайнего слева символа строки
ORD(str)
-
Если крайний слева символ строки
str
представляет собой многобайтный символ, то данная функция возвращает его код, который вычисляется на основе ASCII-кодов составляющих его символов по формуле: ((первый байт ASCII-кода)*256+(второй байт ASCII-кода))[*256+третий байт ASCII-кода...]. Если крайний слева символ не является многобайтным, то данная функция возвращает то же значение, что и ASCII():mysql> SELECT ORD('2'); -> 50
CONV(N,from_base,to_base)
-
Преобразует числа из одной системы счисления в другую. Возвращает
строковое представление числа
N
, преобразованного из системы счисления с основойfrom_base
в систему счисления с основойto_base
. Если хотя бы один из аргументов равенNULL
, то возвращаетсяNULL
. АргументN
интерпретируется как целое число, но может быть задан как целое число или строка. Минимальное значение основы системы счисления равно2
, а максимальное -36
. Если аргументto_base
представлен отрицательным числом, то принимается, чтоN
- число со знаком. В противном случаеN
трактуется как беззнаковое число. ФункцияCONV
работает с 64-битовой точностью:mysql> SELECT CONV("a",16,2); -> '1010' mysql> SELECT CONV("6E",18,8); -> '172' mysql> SELECT CONV(-17,10,-18); -> '-H' mysql> SELECT CONV(10+"10"+'10'+0xa,10,10); -> '40'
BIN(N)
-
Возвращает строку, представляющую двоичную величину
N
, гдеN
- целое число большого размера (BIGINT
). Эквивалентна функцииCONV(N,10,2)
. ЕслиN
равноNULL
, возвращаетсяNULL
:mysql> SELECT BIN(12); -> '1100'
OCT(N)
-
Возвращает строковое представление восьмеричного значения числа
N
, гдеN
- целое число большого размера. Эквивалентно функцииCONV(N,10,8)
. ЕслиN
равноNULL
, возвращаетсяNULL
:mysql> SELECT OCT(12); -> '14'
HEX(N_or_S)
-
Если
N_OR_S
- число, то возвращается строковое представление шестнадцатеричного числаN
, гдеN
- целое число большого размера (BIGINT
). Эквивалентна функцииCONV(N,10,16)
. ЕслиN_OR_S
- строка, то функция возвращает шестнадцатеричную строкуN_OR_S
, где каждый символ вN_OR_S
конвертируется в 2 шестнадцатеричных числа. Является обратной по отношению к строкам0xff
.mysql> SELECT HEX(255); -> 'FF' mysql> SELECT HEX("abc"); -> 616263 mysql> SELECT 0x616263; -> "abc"
CHAR(N,...)
-
CHAR()
интерпретирует аргументы как целые числа и возвращает строку, состоящую из символов, соответствующих ASCII-коду этих чисел. ВеличиныNULL
пропускаются:mysql> SELECT CHAR(77,121,83,81,'76'); -> 'MySQL' mysql> SELECT CHAR(77,77.3,'77.3'); -> 'MMM'
CONCAT(str1,str2,...)
-
Возвращает строку, являющуюся результатом конкатенации аргументов. Если
хотя бы один из аргументов равен
NULL
, возвращаетсяNULL
. Может принимать более 2 аргументов. Числовой аргумент преобразуется в эквивалентную строковую форму:mysql> SELECT CONCAT('My', 'S', 'QL'); -> 'MySQL' mysql> SELECT CONCAT('My', NULL, 'QL'); -> NULL mysql> SELECT CONCAT(14.3); -> '14.3'
CONCAT_WS(separator, str1, str2,...)
-
Функция
CONCAT_WS
() обозначаетCONCAT With Separator
(конкатенация с разделителем) и представляет собой специальную форму функцииCONCAT()
. Первый аргумент является разделителем для остальных аргументов. Разделитель, так же как и остальные аргументы, может быть строкой. Если разделитель равенNULL
, то результат будетNULL
. Данная функция будет пропускать все величиныNULL
и пустые строки, расположенные после аргумента-разделителя. Разделитель будет добавляться между строками, подлежащими конкатенации:mysql> SELECT CONCAT_WS(",","First name","Second name","Last Name"); -> 'First name,Second name,Last Name' mysql> SELECT CONCAT_WS(",","First name",NULL,"Last Name"); -> 'First name,Last Name'
LENGTH(str)
OCTET_LENGTH(str)
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)
-
Возвращает длину строки str:
mysql> SELECT LENGTH('text'); -> 4 mysql> SELECT OCTET_LENGTH('text'); -> 4
Обратите внимание: дляCHAR_LENGTH()
иCHARACTER_LENGTH()
многобайтные символы учитываются только однажды. BIT_LENGTH(str)
-
Возвращает длину строки
str
в битах:mysql> SELECT BIT_LENGTH('text'); -> 32
LOCATE(substr,str)
POSITION(substr IN str)
-
Возвращает позицию первого вхождения подстроки
substr
в строкуstr
. Если подстрока substr в строкеstr
отсутствует, возвращается0
:mysql> SELECT LOCATE('bar', 'foobarbar'); -> 4 mysql> SELECT LOCATE('xbar', 'foobar'); -> 0
Данная функция поддерживает многобайтные величины. В MySQL 3.23 эта функция чувствительна к регистру, а в 4.0 она чувствительна к регистру только в случае, если хотя бы один из аргументов является строкой с двоичными данными. LOCATE(substr,str,pos)
-
Возвращает позицию первого вхождения подстроки
substr
в строкуstr
, начиная с позицииpos
. Если подстрокаsubstr
в строкеstr
отсутствует, возвращается0
:mysql> SELECT LOCATE('bar', 'foobarbar',5); -> 7
Данная функция поддерживает многобайтные величины. В MySQL 3.23 эта функция чувствительна к регистру, а в 4.0 она чувствительна к регистру, только в случае, если хотя бы один из аргументов является строкой с двоичными данными. INSTR(str,substr)
-
Возвращает позицию первого вхождения подстроки
substr
в строкуstr
. То же, что и двухаргументная форма функцииLOCATE()
, за исключением перемены мест аргументов:mysql> SELECT INSTR('foobarbar', 'bar'); -> 4 mysql> SELECT INSTR('xbar', 'foobar'); -> 0
Данная функция поддерживает многобайтные величины. В MySQL 3.23 эта функция чувствительна к регистру, а в 4.0 она чувствительна к регистру только в случае, если хотя бы один из аргументов является строкой с двоичными данными. LPAD(str,len,padstr)
-
Возвращает строку
str
, которая дополняется слева строкойpadstr
, пока строкаstr
не достигнет длиныlen
символов. Если строкаstr
длиннее, чемlen
, то она будет укорочена доlen
символов.mysql> SELECT LPAD('hi',4,'??'); -> '??hi'
RPAD(str,len,padstr)
-
Возвращает строку
str
, которая дополняется справа строкойpadstr
, пока строкаstr
не достигнет длиныlen
символов. Если строкаstr
длиннее, чемlen
, то она будет укорочена доlen
символов.mysql> SELECT RPAD('hi',5,'?'); -> 'hi???'
LEFT(str,len)
-
Возвращает крайние слева
len
символов из строкиstr
:mysql> SELECT LEFT('foobarbar', 5); -> 'fooba'
Данная функция поддерживает многобайтные величины. RIGHT(str,len)
-
Возвращает крайние справа
len
символов из строкиstr
:mysql> SELECT RIGHT('foobarbar', 4); -> 'rbar'
Данная функция поддерживает многобайтные величины. SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
MID(str,pos,len)
-
Возвращает подстроку длиной
len
символов из строкиstr
, начиная от позицииpos
. Существует форма с операторомFROM
, для которой используется синтаксис ANSI SQL92:mysql> SELECT SUBSTRING('Quadratically',5,6); -> 'ratica'
Данная функция поддерживает многобайтные величины. SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
-
Возвращает подстроку из строки
str
, начиная с позицииpos
:mysql> SELECT SUBSTRING('Quadratically',5); -> 'ratically' mysql> SELECT SUBSTRING('foobarbar' FROM 4); -> 'barbar'
Данная функция поддерживает многобайтные величины. SUBSTRING_INDEX(str,delim,count)
-
Возвращает подстроку из строки
str
перед появлениямcount
вхождений разделителяdelim
. Еслиcount
положителен, то возвращается все, что находится слева от последнего разделителя (считая слева). Еслиcount
отрицателен, то возвращается все, что находится справа от последнего разделителя (считая справа):mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2); -> 'www.mysql' mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2); -> 'mysql.com'
Данная функция поддерживает многобайтные величины. LTRIM(str)
-
Возвращает строку
str
с удаленными начальными пробелами:mysql> SELECT LTRIM(' barbar'); -> 'barbar'
Данная функция поддерживает многобайтные величины. RTRIM(str)
-
Возвращает строку
str
с удаленными конечными пробелами:mysql> SELECT RTRIM('barbar '); -> 'barbar'
Данная функция поддерживает многобайтные величины. TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
-
Возвращает строку
str
с удаленными всеми префиксами и/или суффиксами, указанными вremstr
. Если не указан ни один из спецификаторовBOTH
,LEADING
илиTRAILING
, то подразумеваетсяBOTH
. Если аргументremstr
не задан, то удаляются пробелы:mysql> SELECT TRIM(' bar '); -> 'bar' mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx'); -> 'barxxx' mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx'); -> 'bar' mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz'); -> 'barx'
Данная функция поддерживает многобайтные величины. SOUNDEX(str)
-
Возвращает саундекс от str.
Soundex - ``идентификатор звучания строки''. Словосочетания
``К скалам бурым'' и ``С каламбуроми'' должны давать одинаковый
саундекс, т.к. на слух они звучат одинаково. Заметим, однако,
что этой функции для русского языка не существует. MySQL нуждается
в ней, и если кто-то может предоставить алгоритм саундекса на русском
языке - свяжитесь с нами. - Прим. переводчика.
Две созвучные строки, создающие впечатление почти одинаковых, могут иметь
идентичные саундексы. Обычно стандартная саундекс-строка имеет длину 4
символа, но функция
SOUNDEX()
возвращает строку произвольной длины. Можно использовать функциюSUBSTRING()
для извлечения стандартного саундекса строки из результата функцииSOUNDEX()
. В строкеstr
игнорируются все символы, не являющиеся буквами или цифрами. Все международные буквенные символы, не входящие в диапазонA-Z
, трактуются как гласные:mysql> SELECT SOUNDEX('Hello'); -> 'H400' mysql> SELECT SOUNDEX('Quadratically'); -> 'Q36324'
SPACE(N)
-
Возвращает строку, состоящую из
N
пробелов:mysql> SELECT SPACE(6); -> ' '
REPLACE(str,from_str,to_str)
-
Возвращает строку
str
, в которой все вхождения строкиfrom_str
заменены наto_str
:mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww'); -> 'WwWwWw.mysql.com'
Данная функция поддерживает многобайтные величины. REPEAT(str,count)
-
Возвращает строку, состоящую из строки
str
, повтореннойcount
раз. Если значениеcount <= 0
, возвращает пустую строку. ВозвращаетNULL
, еслиstr
илиcount
равныNULL
:mysql> SELECT REPEAT('MySQL', 3); -> 'MySQLMySQLMySQL'
REVERSE(str)
-
Возвращает строку
str
с обратным порядком символов:mysql> SELECT REVERSE('abc'); -> 'cba'
Данная функция поддерживает многобайтные величины. INSERT(str,pos,len,newstr)
-
Возвращает строку
str
, в которой подстрока начиная с позицииpos
, имеющая длинуlen
замещена наnewstr
:mysql> SELECT INSERT('Quadratic', 3, 4, 'What'); -> 'QuWhattic'
Данная функция поддерживает многобайтные величины. ELT(N,str1,str2,str3,...)
-
Возвращает
str1
, еслиN = 1
,str2
, еслиN = 2
, и так далее. ЕслиN
меньше, чем1
или больше, чем число аргументов, возвращаетсяNULL
. ФункцияELT()
является дополненительной по отношению к функцииFIELD()
:mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo'); -> 'ej' mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo'); -> 'foo'
FIELD(str,str1,str2,str3,...)
-
Возвращает индекс строки
str
в спискеstr1, str2, str3, ...
. Если строкаstr
не найдена, возвращается0
. ФункцияFIELD()
является дополнительной по отношению к функцииELT()
:mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 2 mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 0
FIND_IN_SET(str,strlist)
-
Возвращает значение от
1
доN
, если строкаstr
присутствует в спискеstrlist
, состоящем изN
подстрок. Список строк представляет собой строку, состоящую из подстрок, разделенных символами `,'. Если первый аргумент представляет собой строку констант, а второй является столбцом типаSET
, функцияFIND_IN_SET()
оптимизируется для использования двоичной арифметики! Возвращает0
, еслиstr
отсутствует в спискеstrlist
или еслиstrlist
является пустой строкой. Если один из аргументов равенNULL
, возвращается0
. Данная функция не будет корректно работать, если первый аргумент содержит символ `,':mysql> SELECT FIND_IN_SET('b','a,b,c,d'); -> 2
MAKE_SET(bits,str1,str2,...)
-
Возвращает множество (строку, содержащую подстроки, разделенные символами
`,'), состоящее из строк, имеющих соответствующий бит в наборе
bits
. Аргументstr1
соответствует биту0
,str2
- биту1
, и так далее. Нулевые строки в наборахstr1
,str2
,...
не прибавляются к результату:mysql> SELECT MAKE_SET(1,'a','b','c'); -> 'a' mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world'); -> 'hello,world' mysql> SELECT MAKE_SET(0,'a','b','c'); -> ''
EXPORT_SET(bits,on,off,[separator,[number_of_bits]])
-
Возвращает строку, где для каждому установленному биту в аргументе
bits
соответствует строкаon
, а каждому сброшенному биту -off
. Каждая строка отделена разделителем, указанным в параметреseparator
(по умолчанию - `,'), причем используется только количество битов, заданное аргументомnumber_of_bits
(по умолчанию 64), из всего количества, указанного вbits
:mysql> SELECT EXPORT_SET(5,'Y','N',',',4) -> Y,N,Y,N
LCASE(str)
LOWER(str)
-
Возвращает строку
str
, в которой все символы переведены в нижний регистр в соответствии с текущей установкой набора символов (по умолчанию - ISO-8859-1 Latin1):mysql> SELECT LCASE('QUADRATICALLY'); -> 'quadratically'
Данная функция поддерживает многобайтные величины. UCASE(str)
UPPER(str)
-
Возвращает строку
str
, в которой все символы переведены в верхний регистр в соответствии с текущей установкой набора символов (по умолчанию - ISO-8859-1 Latin1):mysql> SELECT UCASE('Hej'); -> 'HEJ'
Данная функция поддерживает многобайтные величины. LOAD_FILE(file_name)
-
Читает заданный файл и возвращает его содержимое в виде строки. Данный
файл должен находится на сервере, должен быть указан полный путь к этому
файлу и пользователь должен обладать привилегией
FILE
. Размер данного файла должен быть меньше указанного вmax_allowed_packet
и файл должен быть открыт для чтения для всех. Если файл не существует или не может быть прочитан по одной из вышеупомянутых причин, то функция возвращаетNULL
:mysql> UPDATE tbl_name SET blob_column=LOAD_FILE("/tmp/picture") WHERE id=1;
При использовании версии MySQL, отличной от 3.23, чтение файла необходимо выполнять внутри вашего приложения и использовать командуINSERT
для внесения в базу данных информации, содержащейся в файле. Один из путей реализации этого с использованием библиотекиMySQL++
можно найти на http://www.mysql.com/documentation/mysql++/mysql++-examples.php. QUOTE(str)
-
Экранирует строку с тем, чтобы получить корректное значение для SQL-выражения.
Строка заключается в одинарные кавычки, и каждое вхождение одинарной кавычки (`''),
обратного слеша (`\'), значения ASCII NUL и Control-Z экранируются обратным слешом.
Если аргумент -
NULL
, то тогда результатом будет слово "NULL" без окружающих кавычек.mysql> SELECT QUOTE("Don't"); -> 'Don\'t!' mysql> SELECT QUOTE(NULL); -> NULL
str
; 0
если
str
является пустой строкой; NULL
, если str
равна NULL
:
mysql> SELECT ASCII('2'); -> 50 mysql> SELECT ASCII(2); -> 50 mysql> SELECT ASCII('dx'); -> 100См. также функцию
ORD()
.
MySQL при необходимости автоматически конвертирует числа в строки и наоборот:
mysql> SELECT 1+"1"; -> 2 mysql> SELECT CONCAT(2,' test'); -> '2 test'
Для преобразования числа в строку явным образом, необходимо передать его в
качестве аргумента функции CONCAT()
.
Если строковая функция содержит в качестве аргумента строку с двоичными данными, то и результирующая строка также будет строкой с двоичными данными. При этом число, конвертированное в строку, воспринимается как строка с двоичными данными. Это имеет значение только при выполнении операций сравнения.
6.3.2.1 Функции сравнения строк
Обычно если при выполнении сравнения строк одно из выражений является зависимым от регистра, то сравнение выполняется также с учетом регистра.
expr LIKE pat [ESCAPE 'escape-char']
-
Функция производит сравнение с шаблоном, используя операции сравнения
простых регулярных выражений в SQL. Возвращает
1
(ИСТИНА) или0
(ЛОЖЬ). ВыражениеLIKE
предусматривает использование следующих двух шаблонных символов вpat
:Символ Описание %
Соответствует любому количеству символов, даже нулевых _
Соответствует ровно одному символу mysql> SELECT 'David!' LIKE 'David_'; -> 1 mysql> SELECT 'David!' LIKE '%D%v%'; -> 1 mysql> select TRUNCATE(-1.999,1); -> -1.9
Начиная с MySQL 3.23.51 все числа округляются к нулю. ЕслиD
является негативным, то тогда вся часть числа округляется к нулю.mysql> select truncate(122,-2); -> 100
Если требуется исследовать литералы при помощи шаблонного символа, следует предварить шаблонный символ экранирующим символом. Если экранирующий символ конкретно не указывается, то подразумевается применение символа `\':Строка Описание \%
Соответствует одному символу `%' \_
Соответствует одному символу `_' mysql> SELECT 'David!' LIKE 'David\_'; -> 0 mysql> SELECT 'David_' LIKE 'David\_'; -> 1
Для указания конкретного экранирующего символа используется выражениеESCAPE
:mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|'; -> 1
В следующих двух примерах показано, что сравнение строк производится с учетом регистра, если ни один из операндов не является строкой с двоичными данными:mysql> SELECT 'abc' LIKE 'ABC'; -> 1 mysql> SELECT 'abc' LIKE BINARY 'ABC'; -> 0
В функцииLIKE
допускаются даже числовые выражения! (Это расширение MySQL по сравнению с ANSI SQL LIKE.)mysql> SELECT 10 LIKE '1%'; -> 1
Примечание: поскольку в MySQL применяются правила экранирования в строках, применяемые в языке C (например, `\n'), необходимо дублировать все символы `\', используемые в строках функцииLIKE
. Например, для поиска сочетания символов `\n' его необходимо указать как `\\n'. Чтобы выполнить поиск символа `\', он должен быть указан как `\\\\' (обратные слеши удаляются дважды: сначала синтаксическим анализатором, а потом - при выполнении сравнения с шаблоном, таким образом остается только один обратный слеш, который и будет обрабатываться). expr NOT LIKE pat [ESCAPE 'escape-char']
-
То же, что и
NOT (expr LIKE pat [ESCAPE 'escape-char'])
. expr SOUNDS LIKE expr
-
Тоже самое что и
SOUNDEX(expr)=SOUNDEX(expr)
(доступно в версии 4.1 или новее). expr REGEXP pat
expr RLIKE pat
-
Выполняет сравнение строкового выражения
expr
с шаблономpat
. Шаблон может представлять собой расширенное регулярное выражение. See section F Регулярные выражения в MySQL. Возвращает1
, еслиexpr
соответствуетpat
, в противном случае -0
. ФункцияRLIKE
является синонимом дляREGEXP
, она предусмотрена для совместимости с mSQL. Примечание: поскольку в MySQL используются правила экранирования в строках, применяемые в языке C (например, `\n'), необходимо дублировать все символы `\', используемые в строках функцииREGEXP
. Что касается версии MySQL 3.23.4, функцияREGEXP
является независимой от регистра для нормальных строк (т.е. строк не с двоичными данными):mysql> SELECT 'Monty!' REGEXP 'm%y%%'; -> 0 mysql> SELECT 'Monty!' REGEXP '.*'; -> 1 mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line'; -> 1 mysql> SELECT "a" REGEXP "A", "a" REGEXP BINARY "A"; -> 1 0 mysql> SELECT "a" REGEXP "^[a-d]"; -> 1
ВREGEXP
иRLIKE
используется текущий набор символов (ISO-8859-1 Latin1 по умолчанию), expr NOT REGEXP pat
expr NOT RLIKE pat
-
То же, что и
NOT (expr REGEXP pat)
. STRCMP(expr1,expr2)
-
Функция
STRCMP()
возвращает:0
, если строки идентичны,-1
- если первый аргумент меньше второго (в соответствии с имеющимся порядком сортировки), и1
- в остальных случаях:mysql> SELECT STRCMP('text', 'text2'); -> -1 mysql> SELECT STRCMP('text2', 'text'); -> 1 mysql> SELECT STRCMP('text', 'text'); -> 0
MATCH (col1,col2,...) AGAINST (expr)
MATCH (col1,col2,...) AGAINST (expr IN BOOLEAN MODE)
-
Функция
MATCH ... AGAINST()
используется для полнотекстового поиска и возвращает величину релевантности - степень сходства между текстом в столбцах(col1,col2,...)
и запросомexpr
. Величина релевантности представляет собой положительное число с плавающей точкой. Нулевая релевантность означает отсутствие сходства. ФункцияMATCH ... AGAINST()
работает в версиях MySQL 3.23.23 или более поздних. РасширениеIN BOOLEAN MODE
было добавлено в версии 4.0.1. Более подробное описание и примеры использования приведены в разделе section 6.8 Полнотекстовый поиск в MySQL.
6.3.2.2 Чувствительность к регистру
BINARY
-
Оператор
BINARY
преобразует следующую за ним строку в строку с двоичными данными. Это простой способ обеспечить сравнение в столбце с учетом регистра, даже если данный столбец не определен какBINARY
илиBLOB
:mysql> SELECT "a" = "A"; -> 1 mysql> SELECT BINARY "a" = "A"; -> 0
BINARY string
является сокращением дляCAST(string AS BINARY)
. See section 6.3.5 Функции приведения типов. ОператорBINARY
был введен в версии MySQL 3.23.0. Следует учитывать, что при приведении индексированного столбца к типуBINARY
MySQL в некоторых случаях не сможет эффективно использовать индексы. Для сравнения двоичных данных типаBLOB
без учета регистра данные с типомBLOB
перед выполнением сравнения всегда можно конвертировать в верхний регистр:SELECT 'A' LIKE UPPER(blob_col) FROM table_name;
В скором времени мы планируем ввести преобразование между различными кодировками, чтобы сделать сравнение строк еще более гибким.
6.3.3 Числовые функции
6.3.3.1 Арифметические операции
В MySQL можно применять обычные арифметические операторы. Следует иметь в
виду, что если оба аргумента являются целыми числами, то при использовании
операторов `-', `+' и `*' результат вычисляется с точностью BIGINT
(64
бита). Если один из аргументов - беззнаковое целое число, а второй
аргумент - также целое число, то результат будет беззнаковым целым числом.
See section 6.3.5 Функции приведения типов.
+
-
Сложение:
mysql> SELECT 3+5; -> 8
-
-
Вычитание:
mysql> SELECT 3-5; -> -2
*
-
Умножение:
mysql> SELECT 3*5; -> 15 mysql> SELECT 18014398509481984*18014398509481984.0; -> 324518553658426726783156020576256.0 mysql> SELECT 18014398509481984*18014398509481984; -> 0
В последнем выражении мы получим неверный результат, так как произведение умножения целых чисел выходит за границы 64-битового диапазона для вычислений с точностьюBIGINT
. /
-
Деление:
mysql> SELECT 3/5; -> 0.60
Деление на ноль приводит к результатуNULL
:mysql> SELECT 102/(1-1); -> NULL
Деление будет выполняться по правиламBIGINT
-арифметики только в случае, если эта операция представлена в контексте, где ее результат преобразуется вINTEGER
!
6.3.3.2 Математические функции
Все математические функции в случае ошибки возвращают NULL
.
-
-
Унарный минус. Изменяет знак аргумента:
mysql> SELECT - 2; -> -2
Необходимо учитывать, что если этот оператор используется с данными типаBIGINT
, возвращаемое значение также будет иметь типBIGINT
! Это означает, что следует избегать использования оператора для целых чисел, которые могут иметь величину-2^63
! ABS(X)
-
Возвращает абсолютное значение величины
X
:mysql> SELECT ABS(2); -> 2 mysql> SELECT ABS(-32); -> 32
Эту функцию можно уверенно применять для величин типаBIGINT
. SIGN(X)
-
Возвращает знак аргумента в виде
-1
,0
или1
, в зависимости от того, является лиX
отрицательным, нулем или положительным:mysql> SELECT SIGN(-32); -> -1 mysql> SELECT SIGN(0); -> 0 mysql> SELECT SIGN(234); -> 1
MOD(N,M)
%
-
Значение по модулю (подобно оператору
%
в C). Возвращает остаток от деленияN
наM
:mysql> SELECT MOD(234, 10); -> 4 mysql> SELECT 253 % 7; -> 1 mysql> SELECT MOD(29,9); -> 2
Эту функцию можно уверенно применять для величин типаBIGINT
. FLOOR(X)
-
Возвращает наибольшее целое число, не превышающее
X
:mysql> SELECT FLOOR(1.23); -> 1 mysql> SELECT FLOOR(-1.23); -> -2
Следует учитывать, что возвращаемая величина преобразуется вBIGINT
! CEILING(X)
-
Возвращает наименьшее целое число, не меньшее, чем
X
:mysql> SELECT CEILING(1.23); -> 2 mysql> SELECT CEILING(-1.23); -> -1
Следует учитывать, что возвращаемая величина преобразуется вBIGINT
! ROUND(X)
-
Возвращает аргумент
X
, округленный до ближайшего целого числа:mysql> SELECT ROUND(-1.23); -> -1 mysql> SELECT ROUND(-1.58); -> -2 mysql> SELECT ROUND(1.58); -> 2
Следует учитывать, что поведение функцииROUND()
при значении аргумента, равном середине между двумя целыми числами, зависит от конкретной реализации библиотеки C. Округление может выполняться: к ближайшему четному числу, всегда к ближайшему большему, всегда к ближайшему меньшему, всегда быть направленным к нулю. Чтобы округление всегда происходило только в одном направлении, необходимо использовать вместо данной хорошо определенные функции, такие какTRUNCATE()
илиFLOOR()
. ROUND(X,D)
-
Возвращает аргумент
X
, округленный до числа сD
десятичными знаками. ЕслиD
равно0
, результат будет представлен без десятичного знака или дробной части:mysql> SELECT ROUND(1.298, 1); -> 1.3 mysql> SELECT ROUND(1.298, 0); -> 1
EXP(X)
-
Возвращает значение
e
(основа натуральных логарифмов), возведенное в степеньX
:mysql> SELECT EXP(2); -> 7.389056 mysql> SELECT EXP(-2); -> 0.135335
LN(X)
-
Возвращает натуральный логарифм числа
X
:mysql> SELECT LN(2); -> 0.693147 mysql> SELECT LN(-2); -> NULL
Эта функция появилась в MySQL 4.0.3. Это синонимLOG(X)
. LOG(B, X)
-
Если вызывается с одним параметром, возвращает натуральный логарифм числа
X
:mysql> SELECT LOG(2); -> 0.693147 mysql> SELECT LOG(-2); -> NULL
Если вызывается с двумя параметрами, функция возвращает логарифм числаX
по базеB
:mysql> SELECT LOG(2,65536); -> 16.000000 mysql> SELECT LOG(1,100); -> NULL
Опция указания базы логарифма появилась в MySQL 4.0.3.LOG(B,X)
эквалиентноLOG(X)/LOG(B)
. LOG2(X)
-
Возвращает логарифм числа
X
по базе 2:mysql> SELECT LOG2(65536); -> 16.000000 mysql> SELECT LOG2(-100); -> NULL
ФункцияLOG2()
полезна с тем, чтобы узнать, сколько бит число потребует для хранения. Эта функция добавлена в MySQL 4.0.3. В более старых версиях вызывайте вместо нее:LOG(X)/LOG(2)
LOG10(X)
-
Возвращает десятичный логарифм числа
X
:mysql> SELECT LOG10(2); -> 0.301030 mysql> SELECT LOG10(100); -> 2.000000 mysql> SELECT LOG10(-100); -> NULL
POW(X,Y)
POWER(X,Y)
-
Возвращает значение аргумента
X
, возведенное в степеньY
:mysql> SELECT POW(2,2); -> 4.000000 mysql> SELECT POW(2,-2); -> 0.250000
SQRT(X)
-
Возвращает неотрицательный квадратный корень числа
X
:mysql> SELECT SQRT(4); -> 2.000000 mysql> SELECT SQRT(20); -> 4.472136
PI()
-
Возвращает значение числа "пи". По умолчанию представлено 5 десятичных
знаков, но в MySQL для представления числа "пи" при внутренних вычислениях
используется полная двойная точность.
mysql> SELECT PI(); -> 3.141593 mysql> SELECT PI()+0.000000000000000000; -> 3.141592653589793116
COS(X)
-
Возвращает косинус числа
X
, гдеX
задается в радианах:mysql> SELECT COS(PI()); -> -1.000000
SIN(X)
-
Возвращает синус числа
X
, гдеX
задается в радианах:mysql> SELECT SIN(PI()); -> 0.000000
TAN(X)
-
Возвращает тангенс числа
X
, гдеX
задается в радианах:mysql> SELECT TAN(PI()+1); -> 1.557408
ACOS(X)
-
Возвращает арккосинус числа
X
, т.е. величину, косинус которой равенX
. ЕслиX
не находится в диапазоне от-1
до1
, возвращаетNULL
:mysql> SELECT ACOS(1); -> 0.000000 mysql> SELECT ACOS(1.0001); -> NULL mysql> SELECT ACOS(0); -> 1.570796
ASIN(X)
-
Возвращает арксинус числа
X
, т.е. величину, синус которой равенX
. ЕслиX
не находится в диапазоне от-1
до1
, возвращаетNULL
:mysql> SELECT ASIN(0.2); -> 0.201358 mysql> SELECT ASIN('foo'); -> 0.000000
ATAN(X)
-
Возвращает арктангенс числа
X
, т.е. величину, тангенс которой равенX
:mysql> SELECT ATAN(2); -> 1.107149 mysql> SELECT ATAN(-2); -> -1.107149
ATAN(Y,X)
ATAN2(Y,X)
-
Возвращает арктангенс двух переменных
X
иY
. Вычисление производится так же, как и вычисление арктангенсаY / X
, за исключением того, что знаки обоих аргументов используются для определения квадранта результата:mysql> SELECT ATAN(-2,2); -> -0.785398 mysql> SELECT ATAN2(PI(),0); -> 1.570796
COT(X)
-
Возвращает котангенс числа
X
:mysql> SELECT COT(12); -> -1.57267341 mysql> SELECT COT(0); -> NULL
RAND()
RAND(N)
-
Возвращает случайную величину с плавающей точкой в диапазоне от
0
до1,0
. Если целочисленный аргументN
указан, то он используется как начальное значение этой величины:mysql> SELECT RAND(); -> 0.9233482386203 mysql> SELECT RAND(20); -> 0.15888261251047 mysql> SELECT RAND(20); -> 0.15888261251047 mysql> SELECT RAND(); -> 0.63553050033332 mysql> SELECT RAND(); -> 0.70100469486881
В выражениях видаORDER BY
не следует использовать столбец с величинамиRAND()
, поскольку применение оператораORDER BY
приведет к многократным вычислениям в этом столбце. В версии MySQL 3.23 можно, однако, выполнить следующий оператор:SELECT * FROM table_name ORDER BY RAND()
: он полезен для получения случайного экземпляра из множестваSELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000
. Следует учитывать, что операторRAND()
в выраженииWHERE
при выполнении выраженияWHERE
будет вычисляться каждый раз заново. ОператорRAND()
не следует воспринимать как полноценный генератор случайных чисел: это просто быстрый способ динамической генерации случайных чисел, переносимых между платформами для одной и той же версии MySQL. LEAST(X,Y,...)
-
Если задано два или более аргументов, возвращает наименьший (с минимальным
значением) аргумент. Сравнение аргументов происходит по следующим
правилам:
-
Если возвращаемая величина используется в целочисленном контексте
(
INTEGER
), или все аргументы являются целочисленными, то они сравниваются как целые числа. -
Если возвращаемая величина используется в контексте действительных
чисел (
REAL
) или все аргументы являются действительными числами, то они сравниваются как числа типаREAL
. - Если один из аргументов является зависимой от регистра строкой, то данные аргументы сравниваются с учетом регистра.
- В остальных случаях аргументы сравниваются как строки, независимые от регистра.
mysql> SELECT LEAST(2,0); -> 0 mysql> SELECT LEAST(34.0,3.0,5.0,767.0); -> 3.0 mysql> SELECT LEAST("B","A","C"); -> "A"
В версиях MySQL до 3.22.5 можно использовать MIN() вместо LEAST. -
Если возвращаемая величина используется в целочисленном контексте
(
GREATEST(X,Y,...)
-
Возвращает наибольший (с максимальным значением) аргумент. Сравнение
аргументов происходит по тем же правилам, что и для
LEAST
:mysql> SELECT GREATEST(2,0); -> 2 mysql> SELECT GREATEST(34.0,3.0,5.0,767.0); -> 767.0 mysql> SELECT GREATEST("B","A","C"); -> "C"
В версиях MySQL до 3.22.5 можно использоватьMAX()
вместоGREATEST
. DEGREES(X)
-
Возвращает аргумент
X
, преобразованный из радианов в градусы:mysql> SELECT DEGREES(PI()); -> 180.000000
RADIANS(X)
-
Возвращает аргумент
X
, преобразованный из градусов в радианы:mysql> SELECT RADIANS(90); -> 1.570796
TRUNCATE(X,D)
-
Возвращает число
X
, усеченное доD
десятичных знаков. ЕслиD
равно0
, результат будет представлен без десятичного знака или дробной части:mysql> SELECT TRUNCATE(1.223,1); -> 1.2 mysql> SELECT TRUNCATE(1.999,1); -> 1.9 mysql> SELECT TRUNCATE(1.999,0); -> 1 mysql> SELECT TRUNCATE(-1.999,1); -> -1.9
Начиная с MySQL 3.23.51 все числа округляются к нулю. ЕслиD
- негативное, то тогда вся часть числа обнуляется:mysql> SELECT TRUNCATE(122,-2); -> 100
Следует учитывать, что обычно в компьютерах десятичные числа хранятся не так, как целые, а как числа двойной точности с плавающим десятичным знаком (DOUBLE
). Поэтому иногда результат может вводить в заблуждение, как в следующем примере:mysql> SELECT TRUNCATE(10.28*100,0); -> 1027
Это происходит потому, что в действительности10,28
хранится как нечто вроде10,2799999999999999
.
6.3.4 Функции даты и времени
Описание диапазона величин для каждого типа и возможные форматы представления даты и времени приведены в разделе section 6.2.2 Типы данных даты и времени.
Ниже представлен пример, в котором используются функции даты. Приведенный
запрос выбирает все записи с величиной date_col
в течение последних 30
дней:
mysql> SELECT something FROM tbl_name WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date)
-
Возвращает индекс дня недели для аргумента
date
(1 = воскресенье, 2 = понедельник, ... 7 = суббота). Эти индексные величины соответствуют стандарту ODBC.mysql> SELECT DAYOFWEEK('1998-02-03'); -> 3
WEEKDAY(date)
-
Возвращает индекс дня недели для аргумента date (0 =понедельник, 1 =
вторник, ... 6 = воскресенье):
mysql> SELECT WEEKDAY('1998-02-03 22:23:00'); -> 1 mysql> SELECT WEEKDAY('1997-11-05'); -> 2
DAYOFMONTH(date)
-
Возвращает порядковый номер дня месяца для аргумента
date
в диапазоне от 1 до 31:mysql> SELECT DAYOFMONTH('1998-02-03'); -> 3
DAYOFYEAR(date)
-
Возвращает порядковый номер дня года для аргумента
date
в диапазоне от 1 до 366:mysql> SELECT DAYOFYEAR('1998-02-03'); -> 34
MONTH(date)
-
Возвращает порядковый номер месяца в году для аргумента
date
в диапазоне от 1 до 12:mysql> SELECT MONTH('1998-02-03'); -> 2
DAYNAME(date)
-
Возвращает название дня недели для аргумента
date
:mysql> SELECT DAYNAME("1998-02-05"); -> 'Thursday'
MONTHNAME(date)
-
Возвращает название месяца для аргумента
date
:mysql> SELECT MONTHNAME("1998-02-05"); -> 'February'
QUARTER(date)
-
Возвращает номер квартала года для аргумента
date
в диапазоне от 1 до 4:mysql> SELECT QUARTER('98-04-01'); -> 2
WEEK(date)
WEEK(date,first)
-
При наличии одного аргумента возвращает порядковый номер недели в году для
date
в диапазоне от 0 до 53 (да, возможно начало 53-й недели) для регионов, где воскресенье считается первым днем недели. ФормаWEEK()
с двумя аргументами позволяет уточнить, с какого дня начинается неделя - с воскресенья или с понедельника. Результат будет в пределах0-53
или1-52
. Вот как работает второй аргумент:Величина Означает
0 Неделя начинается с воскресенья; возвращаемое значение - в промежутке 0-53 1 Неделя начинается с понедельника; возвращаемое значение - в промежутке 0-53 2 Неделя начинается с воскресенья; возвращаемое значение - в промежутке 1-53 3 Неделя начинается с понедельника; возвращаемое значение - в промежутке 1-53 (ISO 8601) mysql> SELECT WEEK('1998-02-20'); -> 7 mysql> SELECT WEEK('1998-02-20',0); -> 7 mysql> SELECT WEEK('1998-02-20',1); -> 8 mysql> SELECT WEEK('1998-12-31',1); -> 53
Примечание: в версии 4.0 функцияWEEK(#,0)
была изменена с целью соответствия календарю США. Заметьте, если неделя является последней неделей прошлого года, MySQL вернет0
если вы не указали2
или3
как опциональный аргумент:mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0); -> 2000, 0 mysql> SELECT WEEK('2000-01-01',2); -> 52
Можно считать, что MySQL должен вернуть52
, так как данная дата и является 52-ой неделей года 1999. Мы решили возвращать0
, так как мы хотим, чтобы функция давала "номер недели в указанном году". Это делает функциюWEEK()
более надежной при использовании совместно с другими функциями, которые вычисляют части дат. Если вам все же важно уточнить корректную неделю в году, тогда вы можете использовать2
или3
как опциональный аргумент или использоватьYEARWEEK()
mysql> SELECT YEARWEEK('2000-01-01'); -> 199952 mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2); -> 52
YEAR(date)
-
Возвращает год для аргумента
date
в диапазоне от 1000 до 9999:mysql> SELECT YEAR('98-02-03'); -> 1998
YEARWEEK(date)
YEARWEEK(date,first)
-
Возвращает год и неделю для аргумента
date
. Второй аргумент в данной функции работает подобно второму аргументу в функцииWEEK()
. Следует учитывать, что год может отличаться от указанного в аргументеdate
для первой и последней недель года:mysql> SELECT YEARWEEK('1987-01-01'); -> 198653
Обратите внимание, что номер недели отличается от того, который возвращает функцияWEEK()
(0
), будучи вызванной с опциональным аргументом0
или1
. Это потому, чтоWEEK()
возвращает номер недели именно в указанном году. HOUR(time)
-
Возвращает час для аргумента
time
в диапазоне от 0 до 23:mysql> SELECT HOUR('10:05:03'); -> 10
MINUTE(time)
-
Возвращает количество минут для аргумента
time
в диапазоне от 0 до 59:mysql> SELECT MINUTE('98-02-03 10:05:03'); -> 5
SECOND(time)
-
Возвращает количество секунд для аргумента
time
в диапазоне от 0 до 59:mysql> SELECT SECOND('10:05:03'); -> 3
PERIOD_ADD(P,N)
-
Добавляет
N
месяцев к периодуP
(в форматеYYMM
илиYYYYMM
). Возвращает величину в форматеYYYYMM
. Следует учитывать, что аргумент периодаP
не является значением даты:mysql> SELECT PERIOD_ADD(9801,2); -> 199803
PERIOD_DIFF(P1,P2)
-
Возвращает количество месяцев между периодами
P1
иP2
.P1
иP2
должны быть в форматеYYMM
илиYYYYMM
. Следует учитывать, что аргументы периодаP1
иP2
не являются значениями даты:mysql> SELECT PERIOD_DIFF(9802,199703); -> 11
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)
-
Данные функции производят арифметические действия над датами. Обе являются
нововведением версии MySQL 3.22. Функции
ADDDATE()
иSUBDATE()
- синонимы дляDATE_ADD()
иDATE_SUB()
. В версии MySQL 3.23 вместо функцийDATE_ADD()
иDATE_SUB()
можно использовать операторы+
и-
, если выражение с правой стороны представляет собой столбец типаDATE
илиDATETIME
(см. пример ниже). Аргументdate
является величиной типаDATETIME
илиDATE
, задающей начальную дату. Выражениеexpr
задает величину интервала, который следует добавить к начальной дате или вычесть из начальной даты. Выражениеexpr
представляет собой строку, которая может начинаться с-
для отрицательных значений интервалов. Ключевое словоtype
показывает, каким образом необходимо интерпретировать данное выражение. Вспомогательная функцияEXTRACT(type FROM date)
возвращает интервал указанного типа (type
) из значения даты. В следующей таблице показана взаимосвязь аргументовtype
иexpr
:
В MySQL формат выраженияЗначение Type
Ожидаемый формат expr
SECOND
SECONDS
MINUTE
MINUTES
HOUR
HOURS
DAY
DAYS
MONTH
MONTHS
YEAR
YEARS
MINUTE_SECOND
"MINUTES:SECONDS"
HOUR_MINUTE
"HOURS:MINUTES"
DAY_HOUR
"DAYS HOURS"
YEAR_MONTH
"YEARS-MONTHS"
HOUR_SECOND
"HOURS:MINUTES:SECONDS"
DAY_MINUTE
"DAYS HOURS:MINUTES"
DAY_SECOND
"DAYS HOURS:MINUTES:SECONDS"
expr
допускает любые разделительные знаки. Разделители, представленные в данной таблице, приведены в качестве примеров. Если аргументdate
является величиной типаDATE
и предполагаемые вычисления включают в себя только частиYEAR
,MONTH
, иDAY
(т.е. не содержат временной частиTIME
), то результат представляется величиной типаDATE
. В других случаях результат представляет собой величинуDATETIME
:mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND; -> 1998-01-01 00:00:00 mysql> SELECT INTERVAL 1 DAY + "1997-12-31"; -> 1998-01-01 mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND; -> 1997-12-31 23:59:59 mysql> SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 SECOND); -> 1998-01-01 00:00:00 mysql> SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 DAY); -> 1998-01-01 23:59:59 mysql> SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL "1:1" MINUTE_SECOND); -> 1998-01-01 00:01:00 mysql> SELECT DATE_SUB("1998-01-01 00:00:00", INTERVAL "1 1:1:1" DAY_SECOND); -> 1997-12-30 22:58:59 mysql> SELECT DATE_ADD("1998-01-01 00:00:00", INTERVAL "-1 10" DAY_HOUR); -> 1997-12-30 14:00:00 mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY); -> 1997-12-02
Если указанный интервал слишком короткий (т.е. не включает все части интервала, ожидаемые при заданном ключевом словеtype
), то MySQL предполагает, что опущены крайние слева части интервала. Например, если указан аргументtype
в видеDAY_SECOND
, то ожидаемое выражениеexpr
должно иметь следующие части: дни, часы, минуты и секунды. Если в этом случае указать значение интервала в виде"1:10"
, то MySQL предполагает, что опущены дни и часы, а данная величина включает только минуты и секунды. Другими словами, сочетание"1:10"
DAY_SECOND
интерпретируется как эквивалент"1:10"
MINUTE_SECOND
. Аналогичным образом в MySQL интерпретируются и значенияTIME
- скорее как представляющие прошедшее время, чем как время дня. Следует учитывать, что при операциях сложения или вычитания с участием величиныDATE
и выражения, содержащего временную часть, данная величинаDATE
будет автоматически конвертироваться в величину типаDATETIME
:mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 DAY); -> 1999-01-02 mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 HOUR); -> 1999-01-01 01:00:00
При использовании некорректных значений дат результат будет равенNULL
. Если при суммированииMONTH
,YEAR_MONTH
илиYEAR
номер дня в результирующей дате превышает максимальное количество дней в новом месяце, то номер дня результирующей даты принимается равным последнему дню нового месяца:mysql> SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH); -> 1998-02-28
Из предыдущего примера видно, что словоINTERVAL
и ключевое словоtype
не являются регистро-зависимыми. EXTRACT(type FROM date)
-
Типы интервалов для функции
EXTRACT()
используются те же, что и для функцийDATE_ADD()
илиDATE_SUB()
, ноEXTRACT()
производит скорее извлечение части из значения даты, чем выполнение арифметических действий.mysql> SELECT EXTRACT(YEAR FROM "1999-07-02"); -> 1999 mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03"); -> 199907 mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03"); -> 20102
TO_DAYS(date)
-
функция возвращает номер дня для даты, указанной в аргументе
date
, (количество дней, прошедших с года 0):mysql> SELECT TO_DAYS(950501); -> 728779 mysql> SELECT TO_DAYS('1997-10-07'); -> 729669
ФункцияTO_DAYS()
не предназначена для использования с величинами, предшествующими введению григорианского календаря (1582), поскольку не учитывает дни, утерянные при изменении календаря. FROM_DAYS(N)
-
Возвращает величину
DATE
для заданного номера дняN
:mysql> SELECT FROM_DAYS(729669); -> '1997-10-07'
ФункцияFROM_DAYS()
не предназначена для использования с величинами, предшествующими введению григорианского календаря (1582), поскольку она не учитывает дни, утерянные при изменении календаря. DATE_FORMAT(date,format)
-
Форматирует величину
date
в соответствии со строкойformat
. В строкеformat
могут использоваться следующие определители:
Все другие символы просто копируются в результирующее выражение без интерпретации:Определитель Описание %M
Название месяца (январь...декабрь) %W
Название дня недели (воскресенье...суббота) %D
День месяца с английским суффиксом (0st, 1st, 2nd, 3rd и т.д.) %Y
Год, число, 4 разряда %y
Год, число, 2 разряда %X
Год для недели, где воскресенье считается первым днем недели, число, 4 разряда, используется с '%V' %x
Год для недели, где воскресенье считается первым днем недели, число, 4 разряда, используется с '%v' %a
Сокращенное наименование дня недели (Вс...Сб) %d
День месяца, число (00..31) %e
День месяца, число (0..31) %m
Месяц, число (00..12) %c
Месяц, число (0..12) %b
Сокращенное наименование месяца (Янв...Дек) %j
День года (001..366) %H
Час (00..23) %k
Час (0..23) %h
Час (01..12) %I
Час (01..12) %l
Час (1..12) %i
Минуты, число (00..59) %r
Время, 12-часовой формат (hh:mm:ss [AP]M) %T
Время, 24-часовой формат (hh:mm:ss) %S
Секунды (00..59) %s
Секунды (00..59) %p
AM или PM %w
День недели (0=воскресенье..6=суббота) %U
Неделя (00..53), где воскресенье считается первым днем недели %u
Неделя (00..53), где понедельник считается первым днем недели %V
Неделя (01..53), где воскресенье считается первым днем недели. Используется с `%X' %v
Неделя (01..53), где понедельник считается первым днем недели. Используется с `%x' %%
Литерал `%'. mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y'); -> 'Saturday October 1997' mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s'); -> '22:23:00' mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%D %y %a %d %m %b %j'); -> '4th 97 Sat 04 10 Oct 277' mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w'); -> '22 22 10 10:23:00 PM 22:23:00 00 6' mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V'); -> '1998 52'
В MySQL 3.23 символ `%' должен предшествовать символам определителя формата. В более ранних версиях MySQL символ `%' необязателен. Причина того, что промежутки для месяца и дня начинаются с нуля заключается в том, что MySQL позволяет использовать неполные даты, такие как'2004-00-00'
, начиная с MySQL 3.23. TIME_FORMAT(time,format)
-
Данная функция используется аналогично описанной выше функции
DATE_FORMAT()
, но строкаformat
может содержать только те определители формата, которые относятся к часам, минутам и секундам. При указании других определителей будет выдана величинаNULL
или0
. CURDATE()
CURRENT_DATE
-
Возвращает сегодняшнюю дату как величину в формате
YYYY-MM-DD
илиYYYYMMDD
, в зависимости от того, в каком контексте используется функция - в строковом или числовом:mysql> SELECT CURDATE(); -> '1997-12-15' mysql> SELECT CURDATE() + 0; -> 19971215
CURTIME()
CURRENT_TIME
-
Возвращает текущее время как величину в формате
HH:MM:SS
илиHHMMS
, в зависимости от того, в каком контексте используется функция - в строковом или числовом:mysql> SELECT CURTIME(); -> '23:50:26' mysql> SELECT CURTIME() + 0; -> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
-
Возвращает текущую дату и время как величину в формате
YYYY-MM-DD HH:MM:SS
илиYYYYMMDDHHMMSS
, в зависимости от того, в каком контексте используется функция - в строковом или числовом:mysql> SELECT NOW(); -> '1997-12-15 23:50:26' mysql> SELECT NOW() + 0; -> 19971215235026
Заметьте, чтоNOW()
вычисляется только единожды для каждого запроса, а именно - в начале его выполнения. Это позволяет быть уверенным в том, что множественные ссылки наNOW()
в рамках одного запроса дадут одно и то же значение. UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
-
При вызове данной функции без аргумента она возвращает временную метку
UNIX_TIMESTAMP
(секунды с 1970-01-01 00:00:00 GMT) как беззнаковое целое число. Если функцияUNIX_TIMESTAMP()
вызывается с аргументомdate
, она возвращает величину аргумента как количество секунд с 1970-01-01 00:00:00 GMT. Аргумент date может представлять собой строку типаDATE
, строкуDATETIME
, величину типаTIMESTAMP
или число в форматеYYMMDD
илиYYYYMMDD
местного времени:mysql> SELECT UNIX_TIMESTAMP(); -> 882226357 mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00'); -> 875996580
При использовании функцииUNIX_TIMESTAMP
в столбцеTIMESTAMP
эта функция будет возвращать величину внутренней временной метки непосредственно, без подразумеваемого преобразования строки во временную метку (``string-to-unix-timestamp'' ). Если заданная дата выходит за пределы допустимого диапазона, то функцияUNIX_TIMESTAMP()
возвратит0
, но следует учитывать, что выполняется только базовая проверка (год 1970-2037, месяц 01-12, день 01-31). Если необходимо выполнить вычитание столбцовUNIX_TIMESTAMP()
, результат можно преобразовать к целым числам со знаком. See section 6.3.5 Функции приведения типов. FROM_UNIXTIME(unix_timestamp)
-
Возвращает представление аргумента
unix_timestamp
как величину в форматеYYYY-MM-DD HH:MM:SS
илиYYYYMMDDHHMMSS
, в зависимости от того, в каком контексте используется функция - в строковом или числовом:mysql> SELECT FROM_UNIXTIME(875996580); -> '1997-10-04 22:23:00' mysql> SELECT FROM_UNIXTIME(875996580) + 0; -> 19971004222300
FROM_UNIXTIME(unix_timestamp,format)
-
Возвращает строковое представление аргумента
unix_timestamp
, отформатированное в соответствии со строкойformat
. Строкаformat
может содержать те же определители, которые перечислены в описании для функцииDATE_FORMAT()
:mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x'); -> '1997 23rd December 03:43:30 1997'
SEC_TO_TIME(seconds)
-
Возвращает аргумент seconds, преобразованный в часы, минуты и секунды, как
величину в формате
HH:MM:SS
илиHHMMSS
, в зависимости от того, в каком контексте используется функция - в строковом или числовом:mysql> SELECT SEC_TO_TIME(2378); -> '00:39:38' mysql> SELECT SEC_TO_TIME(2378) + 0; -> 3938
TIME_TO_SEC(time)
-
Возвращает аргумент
time
, преобразованный в секунды:mysql> SELECT TIME_TO_SEC('22:23:00'); -> 80580 mysql> SELECT TIME_TO_SEC('00:39:38'); -> 2378
6.3.5 Функции приведения типов
Функция CAST
имеет следующий синтаксис:
CAST(expression AS type)
или
CONVERT(expression,type)
где аргумент type
представляет один из типов:
-
BINARY
-
CHAR
(Новшество в 4.0.6) -
DATE
-
DATETIME
-
SIGNED {INTEGER}
-
TIME
-
UNSIGNED {INTEGER}
Функция CAST()
соответствует синтаксису ANSI SQL99, а функция CONVERT()
-
синтаксису ODBC.
Данная функция приведения типов используется главным образом для создания
столбца конкретного типа с помощью команды CREATE ... SELECT
:
CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE);
Выражение CAST string AS BINARY
эквивалентно BINARY string
.
CAST(expr AS CHAR
считает что данное выражение есть строка в
кодировке по умолчанию.
Для преобразования строки в числовую величину обычно не нужно ничего делать: просто используйте строку так, как будто это число:
mysql> SELECT 1+'1'; -> 2
Если вы указываете номер в строковом контексте, номер будет автоматически преобразован
к строке типа BINARY
.
mysql> SELECT concat("hello you ",2); -> "hello you 2"
MySQL поддерживает арифметические операции с 64-битовыми величинами - как
со знаковыми, так и с беззнаковыми. Если используются числовые операции
(такие как +) и один из операндов представлен в виде unsigned integer
, то
результат будет беззнаковым. Его можно переопределить, используя операторы
приведения SIGNED
и UNSIGNED
, чтобы получить 64-битовое целое число со
знаком или без знака соответственно.
mysql> SELECT CAST(1-2 AS UNSIGNED) -> 18446744073709551615 mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED); -> -1
Следует учитывать, что если один из операндов представлен величиной с
плавающей точкой (в данном контексте DECIMAL()
рассматривается как
величина с плавающей точкой), результат также является величиной с
плавающей точкой и не подчиняется вышеприведенному правилу приведения.
mysql> SELECT CAST(1 AS UNSIGNED) -2.0 -> -1.0
Если в арифметической операции используется строка, то результат преобразуется в число с плавающей точкой.
Функции CAST()
и CONVERT()
были добавлены в MySQL 4.0.2.
В MySQL 4.0 была изменены правила обработки беззнаковых величин, чтобы
обеспечить более полную поддержку величин типа BIGINT
. Если код необходимо
использовать и для MySQL 4.0, и для версии 3.23 (в которой функция CAST
,
скорее всего, не будет работать), то можно, применив следующий трюк,
получить при вычитании двух беззнаковых целочисленных столбцов результат
со знаком:
SELECT (unsigned_column_1+0.0)-(unsigned_column_2+0.0);
Идея состоит в том, что перед выполнением вычитания данные столбцы приводятся к типу с плавающей точкой.
Если возникнут проблемы со столбцами типа UNSIGNED
в старых приложениях
MySQL при переносе их на MySQL 4.0, можно использовать параметр
--sql-mode=NO_UNSIGNED_SUBTRACTION
при запуске mysqld
. Однако следует
учитывать, что при этом теряется возможность эффективного использования
столбцов типа UNSIGNED BIGINT
.
6.3.6 Другие функции
6.3.6.1 Битовые функции
MySQL использует для двоичных операций 64-битовые величины BIGINT
,
следовательно, для двоичных операторов максимальный диапазон составляет 64
бита.
|
-
Побитовое ИЛИ
mysql> SELECT 29 | 15; -> 31
Результат является беззнаковым 64-битовым целым числом. &
-
Побитовое И
mysql> SELECT 29 & 15; -> 13
Результат является беззнаковым 64-битовым целым числом. ^
-
Побитовый XOR (побитовое сложение по модулю 2)
mysql> SELECT 1 ^ 1; -> 0 mysql> SELECT 1 ^ 0; -> 1 mysql> SELECT 11 ^ 3; -> 8
Результат - беззнаковое 64-битное целое число.XOR
был реализован в MySQL 4.0.2. <<
-
Сдвиг числа двойной длины (
BIGINT
) влево:mysql> SELECT 1 << 2; -> 4
Результат является беззнаковым 64-битовым целым числом. >>
-
Сдвиг числа двойной длины (
BIGINT
) вправо:mysql> SELECT 4 >> 2; -> 1
Результат является беззнаковым 64-битовым целым числом. ~
-
Инвертировать все биты:
mysql> SELECT 5 & ~1; -> 4
Результат является беззнаковым 64-битовым целым числом. BIT_COUNT(N)
-
Возвращает число битов, указанное в аргументе
N
:mysql> SELECT BIT_COUNT(29); -> 4
6.3.6.2 Разные функции
DATABASE()
-
Возвращает имя текущей базы данных:
mysql> SELECT DATABASE(); -> 'test'
Если в данное время нет активной базы данных, то функцияDATABASE()
возвращает пустую строку. USER()
SYSTEM_USER()
SESSION_USER()
-
Возвращает имя текущего активного пользователя MySQL:
mysql> SELECT USER(); -> 'davida@localhost'
В версии MySQL 3.22.11 или более поздней данная функция включает в себя имя хоста клиента, а также имя пользователя. Можно извлечь часть, касающуюся только имени пользователя, приведенным ниже способом (проверяется, включает ли данная величина имя хоста):mysql> SELECT SUBSTRING_INDEX(USER(),"@",1); -> 'davida'
CURRENT_USER()
-
Возвращает текущее имя пользователя, под которым пользователь аутентифицировался в текущей сессии:
mysql> SELECT USER(); -> 'davida@localhost' mysql> SELECT * FROM mysql.user; -> ERROR 1044: Access denied for user: '@localhost' to database 'mysql' mysql> SELECT CURRENT_USER(); -> '@localhost'
PASSWORD(str)
OLD_PASSWORD(str)
-
Создает строку "пароля" из простого текста в аргументе
str
. Именно эта функция используется в целях шифрования паролей MySQL для хранения в столбцеPassword
в таблице привилегийuser
:mysql> SELECT PASSWORD('badpwd'); -> '7f84554057dd964b'
Шифрование, которое выполняет функцияPASSWORD()
, необратимо. Способ шифрования пароля, который используется функциейPASSWORD()
, отличается от применяемого для шифрования паролей в Unix. ФункцияPASSWORD()
используется в системе аутентификации в сервер MySQL, вам не следует использовать ее для ваших собственных приложений. С этой целью, лучше используйте функцииMD5()
иSHA1()
. ENCRYPT(str[,salt])
-
Шифрует аргумент
str
, используя вызов системной функции кодированияcrypt()
из Unix. Аргументsalt
должен быть строкой из двух символов (в версии MySQL 3.22.16 аргументsalt
может содержать более двух символов):mysql> SELECT ENCRYPT("hello"); -> 'VxuFAJXVARROc'
Если функцияcrypt()
в данной операционной системе недоступна, функцияENCRYPT()
всегда возвращаетNULL
. ФункцияENCRYPT()
игнорирует все символы в аргументеstr
, за исключением первых восьми, по крайней мере в некоторых операционных системах - это определяется тем, как реализован системный вызов базовой функцииcrypt()
. ENCODE(str,pass_str)
-
Шифрует
str
, используя аргументpass_str
как пароль. Для расшифровки результата следует использовать функциюDECODE()
. Результат представляет собой двоичную строку той же длины, что иstring
. Для хранения результата в столбце следует использовать столбец типаBLOB
. DECODE(crypt_str,pass_str)
-
Расшифровывает зашифрованную строку
crypt_str
, используя аргументpass_str
как пароль. Аргументcrypt_str
должен быть строкой, возвращаемой функциейENCODE()
. MD5(string)
-
Вычисляет 128-битовую контрольную сумму
MD5
для аргументаstring
. Возвращаемая величина представляет собой 32-разрядное шестнадцатеричное число, которое может быть использовано, например, в качестве хеш-ключа:mysql> SELECT MD5("testing"); -> 'ae2b1fca515949e5d54fb22b8ed95575'
Это "RSA Data Security, Inc. MD5 Message-Digest Algorithm
". SHA1(string)
SHA(string)
-
Вычисляет 160-битовую контрольную сумму
SHA1
для аргументаstring
, как описано в RFC 3174 (Secure Hash Algorithm). Возвращаемая величина представляет собой 40-разрядное шестнадцатеричное число илиNULL
(в том случае, если входной аргумент был равенNULL
). Одно из возможных применений для этой функции - в качестве хеш-ключа. Можно ее использовать и как криптографически безопасную функцию для сохранения паролей.mysql> SELECT SHA1("abc"); -> 'a9993e364706816aba3e25717850c26c9cd0d89d'
ФункцияSHA1()
была добавлена в версии 4.0.2, и может рассматриваться как более защищенный криптографически эквивалент функцииMD5()
.SHA()
является синонимом для функцииSHA1()
. AES_ENCRYPT(string,key_string)
AES_DECRYPT(string,key_string)
-
Эти функции позволяют шифровать/дешифровать данные, используя официальный
алгоритм AES (Advanced Encryption Standard) (предыдущее название -
Rijndael). В нем применяется кодирование с 128-битовым ключом, однако при
помощи патча к исходному коду длину ключа можно увеличить до 256 битов. В
MySQL выбран 128-битовый ключ, поскольку он работает намного быстрее и
обычно обеспечивает вполне достаточную защищенность. Входные аргументы
могут быть любой длины. Если один из аргументов равен
NULL
, то результат этой функции также будет иметь значениеNULL
. Так как AES является алгоритмом блочного уровня, то для декодирования используется дополнение строк нечетной длины, так, чтобы длина результирующей строки могла вычисляться как выражение16*(trunc(длина_строки/16)+1)
. ЕслиAES_DECRYPT()
обнаруживает некорректные данные или некорректное заполнение строки (имеет в виду padding - прим. пер.), функция вернетNULL
. ОднакоAES_DECRYPT()
вполне может вернуть не-NULL
величину, или, возможно, просто мусор, если входные данных или ключ - некорректны.AES_DECRYPT()
имеет также модификацию, возвращающую величину со значением, не равнымNULL
, даже при неправильном ключе. Функции AES можно использовать для хранения данных в зашифрованном виде путем модификации запросов:INSERT INTO t VALUES (1,AES_ENCRYPT("text","password"));
Можно добиться еще более высокого уровня защищенности за счет исключения передачи ключа через соединение для каждого запроса - для этого ключ на время соединения должен сохраняться в переменной на сервере:SELECT @password:="my password"; INSERT INTO t VALUES (1,AES_ENCRYPT("text",@password));
ФункцииAES_ENCRYPT()
иAES_DECRYPT()
были добавлены в версию 4.0.2 и могут рассматриваться как наиболее криптографически защищенные шифрующие функции, в настоящее время доступные в MySQL. DES_ENCRYPT(string_to_encrypt [, (key_number | key_string) ] )
-
Шифрует строку с заданным ключом, используя алгоритм тройного DES. Следует
учитывать, что эта функция работает только тогда, когда конфигурация MySQL
поддерживает SSL. See section 4.3.9 Использование безопасных соединений. Ключ для
использования при шифровании выбирается следующим образом:
Функция возвращает двоичную строку, в которой первый символ будетАргумент Описание Только один аргумент Используется первый ключ из des-key-file
Номер ключа Используется заданный ключ (0-9) из des-key-file
Строка Для шифрования string_to_encrypt
может использоваться ключ, заданный вkey_string
CHAR(128 | key_number)
. Число128
добавлено для упрощения распознавания зашифрованного ключа. При использовании строкового ключаkey_number
будет равен127
. При ошибке эта функция возвращаетNULL
. Длина строки в результате будет равнаnew_length=org_length + (8-(org_length % 8))+1
. Выражениеdes-key-file
имеет следующий форматt:key_number des_key_string key_number des_key_string
Каждый элементkey_number
должен быть числом от 0 до 9. Строки в данном файле могут располагаться в произвольном порядке. Выражениеdes_key_string
представляет собой строку, которая будет использована при шифровании сообщения. Между числом и ключом должен быть по крайней мере один пробел. Первый ключ используется по умолчанию, если не задан какой-либо аргумент ключа в функцииDES_ENCRYPT()
. Существует возможность послать MySQL запрос на чтение новых значений ключей из файла ключей при помощи командыFLUSH DES_KEY_FILE
. Эта операция требует наличия привилегииReload_priv
. Одно из преимуществ наличия набора ключей по умолчанию состоит в том, что приложения могут проверять существование зашифрованных величин в столбцах без предоставления конечному пользователю права расшифровки этих величин.mysql> SELECT customer_address FROM customer_table WHERE crypted_credit_card = DES_ENCRYPT("credit_card_number");
DES_DECRYPT(string_to_decrypt [, key_string])
-
Дешифрует строку, зашифрованную с помощью функции
DES_ENCRYPT()
. Следует учитывать, что эта функция работает только тогда, когда конфигурация MySQL поддерживает SSL. See section 4.3.9 Использование безопасных соединений. Если аргументkey_string
не задан, то функцияDES_DECRYPT()
проверяет первый байт зашифрованной строки для определения номера ключа алгоритма DES, использованного для шифрования исходной строки, Затем читает ключ изdes-key-file
для расшифровки сообщения. Чтобы выполнить это, пользователь должен обладать привилегиейSUPER
. При указании значения аргумента вkey_string
эта строка используется как ключ для дешифровки сообщения. Если строкаstring_to_decrypt
не выглядит как зашифрованная, то MySQL вернет заданную строкуstring_to_decrypt
. При ошибке эта функция возвращаетNULL
. LAST_INSERT_ID([expr])
-
Возвращает последнюю автоматически сгенерированную величину, которая была
внесена в столбец
AUTO_INCREMENT
. See section 8.4.3.31mysql_insert_id()
.mysql> SELECT LAST_INSERT_ID(); -> 195
Значение последнего сгенерированногоID
сохраняется на сервере для данного конкретного соединения и не будет изменено другим клиентом. Оно не будет изменено даже при обновлении другого столбцаAUTO_INCREMENT
конкретной величиной (то есть, которая не равнаNULL
и не равна0
). При внесении большого количества строк с помощью одной командыINSERT
функцияLAST_INSERT_ID()
возвращает значение для первой внесенной строки. Причина этого заключается в том, что можно легко воспроизвести точно такую же командуINSERT
на другом сервере. Если задано значение аргументаexpr
в функцииLAST_INSERT_ID()
, то величина аргумента возвращается функцией и устанавливается в качестве следующего значения, которое будет возвращено функциейLAST_INSERT_ID()
. Это можно использовать для моделирования последовательностей: Вначале создается таблица:mysql> CREATE TABLE sequence (id INT NOT NULL); mysql> INSERT INTO sequence VALUES (0);
Затем данную таблицу можно использовать для генерации чисел последовательности как показано ниже:mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
Можно генерировать последовательности без вызоваLAST_INSERT_ID()
: полезность применения данной функции состоит в том, что данное значениеID
поддерживается на сервере как последняя автоматически сгенерированная величина (защищенная от других пользователей), и вы можете извлекать новыйID
так же, как и любое другое нормальное значениеAUTO_INCREMENT
в MySQL. Например, функцияLAST_INSERT_ID()
(без аргумента) возвратит новое значениеID
. Функцию C APImysql_insert_id()
также можно использовать для получения этой величины. Следует учитывать, что, поскольку функцияmysql_insert_id()
обновляется только после командINSERT
иUPDATE
, то нельзя использовать эту функцию C API для извлечения значенияID
дляLAST_INSERT_ID(expr)
после выполнения других команд SQL, таких какSELECT
илиSET
. FORMAT(X,D)
-
Форматирует число
X
в формат вида'#,###,###.##'
с округлением доD
десятичных знаков. ЕслиD
равно0
, результат будет представлен без десятичной точки или дробной части:mysql> SELECT FORMAT(12332.123456, 4); -> '12,332.1235' mysql> SELECT FORMAT(12332.1,4); -> '12,332.1000' mysql> SELECT FORMAT(12332.2,0); -> '12,332'
VERSION()
-
Возвращает строку с номером версии сервера MySQL:
mysql> SELECT VERSION(); -> '3.23.13-log'
Следует учитывать, что если данная версия заканчивается с-log
, то это означает, что включено ведение журналов. CONNECTION_ID()
-
Возвращает идентификатор (
thread_id
) для данного соединения. Каждое соединение имеет свой собственный уникальный идентификатор:mysql> SELECT CONNECTION_ID(); -> 1
GET_LOCK(str,timeout)
-
Пытается осуществить блокировку по имени, которое заданно в строке
str
, с временем ожидания в секундах, указанном в аргументеtimeout
. Возвращает1
, если блокировка осуществлена успешно,0
- если закончилось время ожидания для данной попытки, илиNULL
, если возникла ошибка (такая как отсутствие свободной памяти или уничтожение потока командойmysqladmin kill
). Блокировка снимается при выполнении командыRELEASE_LOCK()
, запуске новой командыGET_LOCK()
или при завершении данного потока. Эту функцию можно использовать для осуществления блокировок уровня приложения или для моделирования блокировки записи. Функция блокирует запросы других клиентов на блокировку с тем же именем; клиенты, которые используют согласованные имена блокировок, могут применять эту функцию для выполнения совместного упредительного блокирования:mysql> SELECT GET_LOCK("lock1",10); -> 1 mysql> SELECT IS_FREE_LOCK("lock2"); -> 1 mysql> SELECT GET_LOCK("lock2",10); -> 1 mysql> SELECT RELEASE_LOCK("lock2"); -> 1 mysql> SELECT RELEASE_LOCK("lock1"); -> NULL
Обратите внимание: повторный вызов функцииRELEASE_LOCK()
возвращаетNULL
, поскольку блокировкаlock1
была автоматически выполнена вторым вызовом функцииGET_LOCK()
. RELEASE_LOCK(str)
-
Снимает блокировку, указанную в строке
str
, полученной от функцииGET_LOCK()
. Возвращает1
если блокировка была снята,0
- если такая блокировка уже поставлена в другом соединении (в этом случае блокировка не снимается) иNULL
, если блокировки с указанным именем не существует. Последнее может произойти в случае, когда вызов функцииGET_LOCK()
не привел к успешному результату или данная блокировка уже снята. ФункциюRELEASE_LOCK()
удобно использовать совместно с командойDO
. See section 6.4.10 Синтаксис оператораDO
. IS_FREE_LOCK(str)
-
Проверяет, свободна ли блокировка по имени
str
(т.е. не установлена). Возвращает1
если блокировка свободна (никто не поставил таковую). Возвращает0
если блокировка установлена иNULL
в случае ошибки (например, при неправильных аргументах). BENCHMARK(count,expr)
-
Функция
BENCHMARK()
повторяет выполнение выраженияexpr
заданное количество раз, указанное в аргументеcount
. Она может использоваться для определения того, насколько быстро MySQL обрабатывает данное выражение. Значение результата всегда равно0
. Функция предназначена для использования в клиентеmysql
, который сообщает о времени выполнения запроса:mysql> SELECT BENCHMARK(1000000,ENCODE("hello","goodbye")); +----------------------------------------------+ | BENCHMARK(1000000,ENCODE("hello","goodbye")) | +----------------------------------------------+ | 0 | +----------------------------------------------+ 1 row in set (4.74 sec)
Указанное в отчете время представляет собой время, подсчитанное на стороне клиента, а не время, затраченное центральным процессором (CPU time) на сервере. Может оказаться целесообразным выполнитьBENCHMARK()
несколько раз, чтобы выяснить, насколько интенсивно загружен серверный компьютер. INET_NTOA(expr)
-
По заданному числовому адресу сети (4 или 8 байтов) возвращает
представление указанного адреса в виде разделенных точками четырех октетов
в виде строки:
mysql> SELECT INET_NTOA(3520061480); -> "209.207.224.40"
INET_ATON(expr)
-
По заданному представлению сетевого адреса в виде строки, содержащей
разделенные точками четыре октета, функция возвращает целое число,
представляющее собой числовое значение данного адреса. Адреса могут быть
длиной 4 или 8 байтов:
mysql> SELECT INET_ATON("209.207.224.40"); -> 3520061480
Результирующее число всегда генерируется в соответствии с порядком расположения октетов в сетевом адресе, например вышеприведенное число вычисляется как209*256^3 + 207*256^2 + 224*256 +40
. MASTER_POS_WAIT(log_name, log_pos)
-
Блокируется, пока подчиненный сервер не достигнет определенной точки положения
в журнале репликации головного сервера (т.е. не прочитает и не выполнит все
операции до указанной позиции).
Если информация головного сервера не инициализирована, или аргументы
неправильны, то функция возвращает
NULL
. Если подчиненный сервер не работает, то функция блокируется и ожидает, пока сервер запустится и дойдет до указанной позиции или пройдет через нее. Если подчиненный сервер уже прошел указанную точку, то функция немедленно возвращает результат. Если timeout (новшество в 4.0.10) указан, то ожидание прекратится по прошествии timeout секунд. Таймаут должен быть больше 0. 0 или негативный таймаут означает тоже самое что и отсутствие таймаута. Возвращаемая величина представляет собой число событий в журнале, которые функция должна была ``переждать'', пока сервер дойдет до указанной точки,NULL
в случае ошибки или-1
в случае, если истек таймаут. FOUND_ROWS()
-
Возвращает количество строк, которые возвратила бы последняя команда
SELECT SQL_CALC_FOUND_ROWS ...
при отсутствии ограничения операторомLIMIT
.mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10; mysql> SELECT FOUND_ROWS();
Второй вызов командыSELECT
возвратит количество строк, которые возвратила бы первая команда SELECT, если бы она была написана без выраженияLIMIT
. Отметим, что, хотя при использовании командыSELECT SQL_CALC_FOUND_ROWS ...
, MySQL должен пересчитать все строки в наборе результатов, этот способ все равно быстрее, чем безLIMIT
, так как не требуется посылать результат клиенту. ФункцияSQL_CALC_FOUND_ROWS
появилась в MySQL 4.0.0.
6.3.7 Функции, используемые в операторах GROUP BY
Вызов групповых функций для SQL-команд, не содержащих GROUP BY
,
эквивалентен выполнению этих функций над всем набором возвращаемых данных.
COUNT(expr)
-
Возвращает количество величин со значением, не равным
NULL
, в строках, полученных при помощи командыSELECT
:mysql> SELECT student.student_name,COUNT(*) FROM student,course WHERE student.student_id=course.student_id GROUP BY student_name;
ФункцияCOUNT(*)
несколько отличается от описанной выше: она возвращает количество извлеченных строк, содержащих величины со значениемNULL
.COUNT(*)
оптимизирована для очень быстрого возврата результата при условии, что командаSELECT
извлекает данные из одной таблицы, никакие другие столбцы не обрабатываются и функция не содержит выраженияWHERE
. Например:mysql> SELECT COUNT(*) FROM student;
COUNT(DISTINCT expr,[expr...])
-
Возвращает количество различающихся величин со значением, не равным
NULL
:mysql> SELECT COUNT(DISTINCT results) FROM student;
В MySQL для того, чтобы получить количество различающихся комбинаций выражений, не содержащихNULL
, нужно просто задать список этих выражений. В ANSI SQL необходимо провести конкатенацию всех выражений внутриCOUNT(DISTINCT ...)
. AVG(expr)
-
Возвращает среднее значение аргумента expr:
mysql> SELECT student_name, AVG(test_score) FROM student GROUP BY student_name;
MIN(expr)
MAX(expr)
-
Возвращает минимальную или максимальную величину аргумента
expr
. ФункцииMIN()
иMAX()
могут принимать строковый аргумент; в таких случаях они возвращают минимальную или максимальную строковую величину. See section 5.4.3 Использование индексов в MySQL.mysql> SELECT student_name, MIN(test_score), MAX(test_score) FROM student GROUP BY student_name;
ВMIN()
,MAX()
и других групповых фунциях MySQL сейчас сравниваетENUM
иSET
-столбцы по ихнему строковому представлению а не по относительной позиции строки в множестве. Это будет исправлено. SUM(expr)
-
Возвращает сумму величин в аргументе
expr
. Обратите внимание: если возвращаемый набор данных не содержит ни одной строки, то функция возвращаетNULL
! VARIANCE(expr)
-
Возвращает вариант стандарта, которому соответствует
expr
. Это - расширение по сравнению с ANSI SQL, доступное только в 4.1 или более поздних версиях. STD(expr)
STDDEV(expr)
-
Возвращает среднеквадратичное отклонение значения в аргументе
expr
. Эта функция является расширением ANSI SQL. ФормаSTDDEV()
обеспечивает совместимость с Oracle. BIT_OR(expr)
-
Возвращает побитовое ИЛИ для всех битов в
expr
. Вычисление производится с 64-битовой (BIGINT
) точностью. BIT_AND(expr)
-
Возвращает побитовое И для всех битов в
expr
. Вычисление производится с 64-битовой (BIGINT
) точностью.
В MySQL расширены возможности использования оператора GROUP BY
. Теперь в
выражениях SELECT
можно использовать столбцы или вычисления, которые не
присутствуют в части GROUP BY
. Это справедливо для любой возможной
величины для этой группы. Данная возможность позволяет повысить
производительность за счет исключения сортировки и группирования ненужных
величин. Например, в следующем запросе нет необходимости в группировке
customer.name
:
mysql> SELECT order.custid,customer.name,MAX(payments) FROM order,customer WHERE order.custid = customer.custid GROUP BY order.custid;
В ANSI SQL к предложению GROUP BY
необходимо добавлять customer.name
. В
MySQL, если работа происходит не в режиме ANSI, это имя избыточно.
Не используйте данное свойство, если столбцы, пропущенные в части GROUP
BY
, не являются уникальными в данной группе! Возможны непредсказуемые
результаты.
В некоторых случаях можно применять функции MIN()
и MAX()
для получения
указанной величины столбца, даже если он не является уникальным. В
следующем примере выдается значение столбца column
из строки, содержащей
наименьшую величину в столбце sort
:
SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7)
See section 3.5.4 Строка, содержащая максимальное значение некоторого столбца.
Следует отметить, что в версии MySQL 3.22 (или более ранней) либо при
попытке работы в рамках ANSI SQL применение выражений в предложениях
GROUP BY
или ORDER BY
невозможно. Это ограничение можно обойти,
используя для выражения псевдоним:
mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name GROUP BY id,val ORDER BY val;
В версии MySQL 3.23 можно также выполнить следующее:
mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();
6.4 Обработка данных: SELECT, INSERT, UPDATE, DELETE
6.4.1 Синтаксис оператора SELECT
Оператор SELECT имеет следующую структуру:
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY] [DISTINCT | DISTINCTROW | ALL] select_expression,... [INTO {OUTFILE | DUMPFILE} 'file_name' export_options] [FROM table_references [WHERE where_definition] [GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...] [HAVING where_definition] [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC], ...] [LIMIT [offset,] rows | rows OFFSET offset] [PROCEDURE procedure_name(argument_list)] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
применяется для извлечения строк, выбранных из одной или нескольких
таблиц. Выражение select_expression
задает столбцы, в которых необходимо
проводить выборку. Кроме того, оператор SELECT
можно использовать для
извлечения строк, вычисленных без ссылки на какую-либо таблицу. Например:
mysql> SELECT 1 + 1; -> 2
При указании ключевых слов следует точно соблюдать порядок, указанный
выше. Например, выражение HAVING
должно располагаться после всех выражений
GROUP BY
и перед всеми выражениями ORDER BY
.
-
Используя ключевое слово
AS
, выражению вSELECT
можно присвоить псевдоним. Псевдоним используется в качестве имени столбца в данном выражении и может применяться вORDER BY
илиHAVING
. Например:mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
-
Псевдонимы столбцов нельзя использовать в выражении
WHERE
, поскольку находящиеся в столбцах величины на момент выполненияWHERE
могут быть еще не определены. See section A.5.4 Проблемы сalias
. -
Выражение
FROM table_references
задает таблицы, из которых надлежит извлекать строки. Если указано имя более чем одной таблицы, следует выполнить объединение. Информацию о синтаксисе объединения можно найти в разделе section 6.4.1.1 Синтаксис оператораJOIN
. Для каждой заданной таблицы по желанию можно указать псевдоним.table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | FORCE INDEX (key_list)]]
В версии MySQL 3.23.12 можно указывать, какие именно индексы (ключи) MySQL должен применять для извлечения информации из таблицы. Это полезно, если операторEXPLAIN
(выводящий информацию о структуре и порядке выполнения запросаSELECT
), показывает, что MySQL из списка возможных индексов выбрал неправильный. Если нужно. чтобы для поиска записи в таблице применялся только один из возможных индексов, следует задать значение этого индекса вUSE INDEX
(key_list
). Альтернативное выражениеIGNORE INDEX (key_list)
запрещает использование в MySQL данного конкретного индекса. В MySQL 4.0.9 можно также указыватьFORCE INDEX
. Это работает также, как иUSE INDEX (key_list)
но в дополнение дает понять серверу что полное сканирование таблицы будет ОЧЕНЬ дорогостоящей операцией. Другими словами, в этом случае сканирование таблицы будет использовано только тогда, когда не будет найдено другого способа использовать один из данных индексов для поиска записей в таблице. ВыраженияUSE/IGNORE KEY
являются синонимами дляUSE/IGNORE INDEX
. -
Ссылки на таблицы могут даваться как
tbl_name
(в рамках текущей базы данных), или какdbname.tbl_name
с тем, чтобы четко указать базу данных. Ссылки на столбцы могут задаваться в видеcol_name
,tbl_name.col_name
илиdb_name.tbl_name.col_name
. В выраженияхtbl_name
илиdb_name.tbl_name
нет необходимости указывать префикс для ссылок на столбцы в командеSELECT
, если эти ссылки нельзя истолковать неоднозначно. See section 6.1.2 Имена баз данных, таблиц, столбцов, индексы псевдонимы, где приведены примеры неоднозначных случаев, для которых требуются более четкие определения ссылок на столбцы. -
Ссылку на таблицу можно заменить псевдонимом, используя
tbl_name [AS] alias_name
:mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; mysql> SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
-
В выражениях
ORDER BY
иGROUP BY
для ссылок на столбцы, выбранные для вывода информации, можно использовать либо имена столбцов, либо их псевдонимы, либо их позиции (местоположения). Нумерация позиций столбцов начинается с1
:mysql> SELECT college, region, seed FROM tournament ORDER BY region, seed; mysql> SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; mysql> SELECT college, region, seed FROM tournament ORDER BY 2, 3;
Для того чтобы сортировка производилась в обратном порядке, в утвержденииORDER BY
к имени заданного столбца, в котором производится сортировка, следует добавить ключевое словоDESC
(убывающий). По умолчанию принята сортировка в возрастающем порядке, который можно задать явно при помощи ключевого словаASC
. -
В выражении
WHERE
можно использовать любую из функций, которая поддерживается в MySQL. See section 6.3 Функции, используемые в операторахSELECT
иWHERE
. ВыражениеHAVING
может ссылаться на любой столбец или псевдоним, упомянутый в выраженииselect_expression
.HAVING
отрабатывается последним, непосредственно перед отсылкой данных клиенту, и без какой бы то ни было оптимизации. Не используйте это выражение для определения того, что должно быть определено вWHERE
. Например, нельзя задать следующий оператор:mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;
Вместо этого следует задавать:mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;
В версии MySQL 3.22.5 или более поздней можно также писать запросы, как показано ниже:mysql> SELECT user,MAX(salary) FROM users GROUP BY user HAVING MAX(salary)>10;
В более старых версиях MySQL вместо этого можно указывать:mysql> SELECT user,MAX(salary) AS sum FROM users GROUP BY user HAVING sum>10;
-
Параметры (опции)
DISTINCT
,DISTINCTROW
иALL
указывают, должны ли возвращаться дублирующиеся записи. По умолчанию установлен параметр (ALL
), т.е. возвращаются все встречающиеся строки.DISTINCT
иDISTINCTROW
являются синонимами и указывают, что дублирующиеся строки в результирующем наборе данных должны быть удалены. -
Все параметры, начинающиеся с
SQL_
,STRAIGHT_JOIN
иHIGH_PRIORITY
, представляют собой расширение MySQL для ANSI SQL. -
При указании параметра
HIGH_PRIORITY
содержащий его операторSELECT
будет иметь более высокий приоритет, чем команда обновления таблицы. Нужно только использовать этот параметр с запросами, которые должны выполняться очень быстро и сразу. Если таблица заблокирована для чтения, то запросSELECT HIGH_PRIORITY
будет выполняться даже при наличии команды обновления, ожидающей, пока таблица освободится. -
Параметр
SQL_BIG_RESULT
можно использовать сGROUP BY
илиDISTINCT
, чтобы сообщить оптимизатору, что результат будет содержать большое количество строк. Если указан этот параметр, MySQL при необходимости будет непосредственно использовать временные таблицы на диске, однако предпочтение будет отдаваться не созданию временной таблицы с ключом по элементамGROUP BY
, а сортировке данных. -
При указании параметра
SQL_BUFFER_RESULT
MySQL будет заносить результат во временную таблицу. Таким образом MySQL получает возможность раньше снять блокировку таблицы; это полезно также для случаев, когда для посылки результата клиенту требуется значительное время. -
Параметр
SQL_SMALL_RESULT
является опцией, специфической для MySQL. Данный параметр можно использовать сGROUP BY
илиDISTINCT
, чтобы сообщить оптимизатору, что результирующий набор данных будет небольшим. В этом случае MySQL для хранения результирующей таблицы вместо сортировки будет использовать быстрые временные таблицы. В версии MySQL 3.23 указывать данный параметр обычно нет необходимости. -
Параметр
SQL_CALC_FOUND_ROWS
(MySQL 4.0.0 и более новый) возвращает количество строк, которые вернул бы операторSELECT
, если бы не был указанLIMIT
. Искомое количество строк можно получить при помощиSELECT FOUND_ROWS()
. See section 6.3.6.2 Разные функции. Заметьте, что в версиях MySQL до 4.1.0 это не работает сLIMIT 0
, который оптимизирован для того, чтобы немедленно вернуть нулевой результат. See section 5.2.8 Как MySQL оптимизируетLIMIT
. -
Параметр
SQL_CACHE
предписывает MySQL сохранять результат запроса в кэше запросов при использованииQUERY_CACHE_TYPE=2
(DEMAND
). See section 6.9 Кэш запросов в MySQL. -
Параметр
SQL_NO_CACHE
запрещает MySQL хранить результат запроса в кэше запросов. See section 6.9 Кэш запросов в MySQL. -
При использовании выражения
GROUP BY
строки вывода будут сортироваться в соответствии с порядком, заданным вGROUP BY
, - так, как если бы применялось выражениеORDER BY
для всех полей, указанных вGROUP BY
. В MySQL выражениеGROUP BY
расширено таким образом, что для него можно также указывать параметрыASC
иDESC
:SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
-
Расширенный оператор
GROUP BY
в MySQL обеспечивает, в частности, возможность выбора полей, не упомянутых в выраженииGROUP BY
. Если ваш запрос не приносит ожидаемых результатов, прочтите, пожалуйста, описаниеGROUP BY
. See section 6.3.7 Функции, используемые в операторахGROUP BY
. -
При указании параметра
STRAIGHT_JOIN
оптимизатор будет объединять таблицы в том порядке, в котором они перечислены в выраженииFROM
. Применение данного параметра позволяет увеличить скорость выполнения запроса, если оптимизатор производит объединение таблиц неоптимальным образом. See section 5.2.1 Синтаксис оператораEXPLAIN
(получение информации оSELECT
). -
Выражение
LIMIT
может использоваться для ограничения количества строк, возвращенных командойSELECT
.LIMIT
принимает один или два числовых аргумента. Эти аргументы должны быть целочисленными константами. Если заданы два аргумента, то первый указывает на начало первой возвращаемой строки, а второй задает максимальное количество возвращаемых строк. При этом смещение начальной строки равно0
(не1
): Для совместимости с PostgreSQL MySQL также поддерживает синтаксисLIMIT # OFFSET #
.mysql> SELECT * FROM table LIMIT 5,10; # возвращает строки 6-15
Для того, чтобы выбрать все строки с определенного смещения и до конца результата, вы можете использовать значение-1
в качестве второго параметра:mysql> SELECT * FROM table LIMIT 95,-1; # Retrieve rows 96-last.
Если задан один аргумент, то он показывает максимальное количество возвращаемых строк:mysql> SELECT * FROM table LIMIT 5; # возвращает первых 5 строк
Другими словами,LIMIT n
эквивалентноLIMIT 0,n
. -
Оператор
SELECT
может быть представлен в формеSELECT ... INTO OUTFILE 'file_name'
. Эта разновидность команды осуществляет запись выбранных строк в файл, указанный вfile_name
. Данный файл создается на сервере и до этого не должен существовать (таким образом, помимо прочего, предотвращается разрушение таблиц и файлов, таких как `/etc/passwd'). Для использования этой формы командыSELECT
необходимы привилегииFILE
. ФормаSELECT ... INTO OUTFILE
главным образом предназначена для выполнения очень быстрого дампа таблицы на серверном компьютере. КомандуSELECT ... INTO OUTFILE
нельзя применять, если необходимо создать результирующий файл на ином хосте, отличном от серверного. В таком случае для генерации нужного файла вместо этой команды следует использовать некоторую клиентскую программу наподобиеmysqldump --tab
илиmysql -e "SELECT ..." > outfile
. КомандаSELECT ... INTO OUTFILE
является дополнительной по отношению кLOAD DATA INFILE
; синтаксис части export_options этой команды содержит те же выраженияFIELDS
иLINES
, которые используются в командеLOAD DATA INFILE
. See section 6.4.9 Синтаксис оператораLOAD DATA INFILE
. Следует учитывать, что в результирующем текстовом файле операторESCAPED BY
экранирует только следующие символы:- Символ оператора
ESCAPED BY
- Первый символ оператора
FIELDS TERMINATED BY
- Первый символ оператора
LINES TERMINATED BY
0
конвертируется вESCAPED BY
, за которым следует символ `0' (ASCII 48). Это делается потому, что необходимо экранировать любые символы операторовFIELDS TERMINATED BY
,ESCAPED BY
илиLINES TERMINATED BY
, чтобы иметь надежную возможность повторить чтение этого файла. ASCII0
экранируется, чтобы облегчить просмотр файла с помощью программ вывода типа pager. Поскольку результирующий файл не должен удовлетворять синтаксису SQL, нет необходимости экранировать что-либо еще. Ниже приведен пример того, как получить файл в формате, который используется многими старыми программами.SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM test_table;
- Символ оператора
-
Если вместо
INTO OUTFILE
использоватьINTO DUMPFILE
, то MySQL запишет в файл только одну строку без символов завершения столбцов или строк и без какого бы то ни было экранирования. Это полезно для хранения данных типаBLOB
в файле. -
Следует учитывать, что любой файл, созданный с помощью
INTO OUTFILE
иINTO DUMPFILE
, будет доступен для записи всем пользователям! Причина этого заключается в следующем: сервер MySQL не может создавать файл, принадлежащий только какому-либо текущему пользователю (вы никогда не можете запуститьmysqld
от пользователяroot
), соответственно, файл должен быть доступен для записи всем пользователям. При использованииFOR UPDATE
с обработчиком таблиц, поддерживающим блокировку страниц/строк, выбранные строки будут заблокированы для записи.
6.4.1.1 Синтаксис оператора JOIN
MySQL поддерживает следующий синтаксис оператора JOIN
при использовании в
командах SELECT
:
table_reference, table_reference table_reference [CROSS] JOIN table_reference table_reference INNER JOIN table_reference join_condition table_reference STRAIGHT_JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference join_condition table_reference LEFT [OUTER] JOIN table_reference table_reference NATURAL [LEFT [OUTER]] JOIN table_reference { OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr } table_reference RIGHT [OUTER] JOIN table_reference join_condition table_reference RIGHT [OUTER] JOIN table_reference table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
где table_reference
определено, как:
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
и join_condition
определено, как:
ON conditional_expr | USING (column_list)
В большинстве случаев не следует указывать в части ON
какие бы то ни
было условия, накладывающие ограничения на строки в наборе результатов (из
этого правила есть исключения). Если необходимо указать, какие строки должны
присутствовать в результате, следует сделать это в выражении WHERE
.
Необходимо учитывать, что в версиях до 3.23.17 оператор INNER JOIN
не
принимает параметр join_condition
!
Наличие последней из приведенных выше конструкций выражения LEFT OUTER
JOIN
обусловлено только требованиями совместимости с ODBC:
-
Вместо ссылки на таблицу может использоваться псевдоним, который
присваивается при помощи выражений
tbl_name AS alias_name
илиtbl_name alias_name
:mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name;
-
Условный оператор
ON
представляет собой условие в любой форме из числа тех, которые можно использовать в выраженииWHERE
. -
Если запись для правой таблицы в частях
ON
илиUSING
вLEFT JOIN
не найдена, то для данной таблицы используется строка, в которой все столбцы установлены вNULL
. Эту возможность можно применять для нахождения результатов в таблице, не имеющей эквивалента в другой таблице:mysql> SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Этот пример находит все строки в таблицеtable1
с величинойid
, которая не присутствует в таблицеtable2
(т.е. все строки вtable1
, для которых нет соответствующих строк вtable2
). Конечно, это предполагает, чтоtable2.id
объявлен какNOT NULL
. See section 5.2.6 Как MySQL оптимизируетLEFT JOIN
иRIGHT JOIN
. -
USING (column_list)
служит для указания списка столбцов, которые должны существовать в обеих таблицах. Такое выражениеUSING
, как:A LEFT JOIN B USING (C1,C2,C3,...)
семантически идентично выражениюON
, например:A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
-
Выражение
NATURAL [LEFT] JOIN
для двух таблиц определяется так, чтобы оно являлось семантическим эквивалентомINNER JOIN
илиLEFT JOIN
с выражениемUSING
, в котором указаны все столбцы, имеющиеся в обеих таблицах. -
INNER JOIN
и,
(запятая) являются семантическими эквивалентами. Оба осуществляют полное объединение используемых таблиц. Способ связывания таблиц обычно задается в условииWHERE
. -
RIGHT JOIN
работает аналогичноLEFT JOIN
. Для сохранения переносимости кода между различными базами данных рекомендуется вместоRIGHT JOIN
использоватьLEFT JOIN
. -
STRAIGHT_JOIN
идентичноJOIN
, за исключением того, что левая таблица всегда читается раньше правой. Это выражение может использоваться для тех (немногих) случаев, когда оптимизатор объединения располагает таблицы в неправильном порядке. -
Начиная с версии MySQL 3.23.12, можно давать MySQL указания о том,
какой индекс должен использоваться при извлечении информации из
таблицы. Эта возможность полезна, если оператор
EXPLAIN
показывает, что MySQL из всех возможных индексов использует ошибочный. Задавая значение индекса вUSE INDEX (key_list)
, можно заставить MySQL применять для поиска записи только один из возможных индексов. Альтернативное выражениеIGNORE INDEX (key_list)
запрещает использование в MySQL данного конкретного индекса. ВыраженияUSE/IGNORE KEY
являются синонимами дляUSE/IGNORE INDEX
. В MySQL 4.0.9 можно также указыватьFORCE INDEX
. Это работает также, как иUSE INDEX (key_list)
но в дополнение дает понять серверу что полное сканирование таблицы будет ОЧЕНЬ дорогостоящей операцией. Другими словами, в этом случае сканирование таблицы будет использовано только тогда, когда не будет найдено другого способа использовать один из данных индексов для поиска записей в таблице.
Несколько примеров:
mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id); mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id; mysql> SELECT * FROM table1 USE INDEX (key1,key2) WHERE key1=1 AND key2=2 AND key3=3; mysql> SELECT * FROM table1 IGNORE INDEX (key3) WHERE key1=1 AND key2=2 AND key3=3;
See section 5.2.6 Как MySQL оптимизирует LEFT JOIN
и RIGHT JOIN
.
6.4.1.2 Синтаксис оператора UNION
SELECT ... UNION [ALL] SELECT ... [UNION SELECT ...]
Оператор UNION
реализован в MySQL 4.0.0.
UNION
используется для объединения результатов работы нескольких команд
SELECT
в один набор результатов.
Столбцы, перечисленные в части select_expression
должны быть одинакового типа.
Имена столбцов, указанные в первом SELECT
будут использованы как имена столбцов для
всего результата.
Эти команды SELECT
являются обычными командами выборки данных, но со
следующим ограничением:
-
Только последняя команда
SELECT
может включать операторINTO OUTFILE
.
Если не используется ключевое слово ALL
для UNION
, все возвращенные строки
будут уникальными, так как по умолчанию подразумевается DISTINCT
для всего
результирующего набора данных. Если указать ключевое слово ALL
, то
результат будет содержать все найденные строки из всех примененных команд
SELECT
.
Если для всего результата UNION
необходимо применить оператор ORDER BY
,
следует использовать круглые скобки:
(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10) ORDER BY a;
6.4.2 Синтаксис оператора HANDLER
HANDLER tbl_name OPEN [ AS alias ] HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...) [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name READ { FIRST | NEXT } [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name CLOSE
Оператор HANDLER
обеспечивает прямой доступ к интерфейсу обработчика
таблиц MyISAM
.
Первая форма оператора HANDLER
открывает таблицу, делая ее доступной для
последовательности команд HANDLER ... READ
. Этот объект недоступен другим
потокам и не будет закрыт, пока данный поток не вызовет HANDLER tbl_name
CLOSE
или сам поток не будет уничтожен.
Вторая форма выбирает одну строку (или больше - в соответствии с
установкой в выражении LIMIT
), для которой(ых) указанный индекс
соответствует заданному условию и условие в выражении WHERE
также
выполняется. Если индекс состоит из нескольких частей (охватывает
несколько столбцов), то составляющие его величины указываются в виде
разделенного запятыми списка. Обеспечиваются величины только для
нескольких первых столбцов.
Третья форма выбирает одну строку (или больше - в соответствии с
установкой в выражении LIMIT
), из таблицы; в порядке указания индексов в
соответствии с условием WHERE
.
Четвертая форма (без указания индексов) выбирает одну строку (или больше -
в соответствии с установкой в выражении LIMIT
), из таблицы, используя
естественный порядок строк (как они хранятся в файле данных), в
соответствии с условием WHERE
. Эта форма работает быстрее, чем HANDLER
tbl_name READ index_name
, в тех случаях, когда желателен просмотр всей
таблицы.
Оператор HANDLER ... CLOSE
закрывает таблицу, открытую оператором
HANDLER ... OPEN
.
Оператор HANDLER
представляет собой что-то наподобие низкоуровневой
команды. Например, он не обеспечивает целостности таблицы. Т.е. HANDLER
... OPEN
НЕ делает моментального снимка таблицы и НЕ блокирует ее. Отсюда
следует, что после вызова команды HANDLER ... OPEN
данные таблицы могут
быть модифицированы (этим или любым другим потоком), а сами модификации в
просмотрах таблицы при помощи HANDLER ... NEXT
или HANDLER ... PREV
могут
появляться только частично.
Вот причины, по которым вы можете предпочесть HANDLER вместо обычного SQL:
-
Он быстрее чем
SELECT
, потому что:-
Выделенный код обработчика таблиц создается в потоке по вызову
HANDLER open
. - Меньше синтаксического анализа.
- Нет нагрузки на оптимизацию и проверку.
- Таблицу не нужно блокировать между запросами.
- Этот интерфейс не обязан предоставлять целостный вид данных (скажем, грязное чтение допускается), что позволяет обработчику таблиц делать оптимизации которые SQL обычно не допускает.
-
Выделенный код обработчика таблиц создается в потоке по вызову
- Гораздо легче переносить на MySQL приложения, которые используют интерфейс, подобный ISAM.
- Такой интерфейс позволяет просматривать базу данных способом, который не так легко (или в некоторых случаях и вовсе невозможно) реализовать с помощью SQL. Интерфейс HANDLER является более естественным способом получить данные, когда приходится иметь дело с интерактивными пользовательскими приложениями.
6.4.3 Синтаксис оператора INSERT
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES (expression,...),(...),... [ ON DUPLICATE KEY UPDATE col_name=expression, ... ] или INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ... или INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name SET col_name=(expression | DEFAULT), ... [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]
Оператор INSERT
вставляет новые строки в существующую таблицу. Форма
данной команды INSERT ... VALUES
вставляет строки в соответствии с точно
указанными в команде значениями. Форма INSERT ... SELECT
вставляет строки,
выбранные из другой таблицы или таблиц. Форма INSERT ... VALUES
со списком
из нескольких значений поддерживается в версии MySQL 3.22.5 и более
поздних. Синтаксис выражения col_name=expression
поддерживается в версии
MySQL 3.22.10 и более поздних.
tbl_name
задает таблицу, в которую должны быть внесены строки. Столбцы,
для которых заданы величины в команде, указываются в списке имен столбцов
или в части SET
:
-
Если не указан список столбцов для
INSERT ... VALUES
илиINSERT ... SELECT
, то величины для всех столбцов должны быть определены в спискеVALUES()
или в результате работыSELECT
. Если порядок столбцов в таблице неизвестен, для его получения можно использоватьDESCRIBE tbl_name
. -
Любой столбец, для которого явно не указано значение, будет установлен
в свое значение по умолчанию. Например, если в заданном списке
столбцов не указаны все столбцы в данной таблице, то не упомянутые
столбцы устанавливаются в свои значения по умолчанию. Установка
значений по умолчанию описывается в разделе section 6.5.3 Синтаксис оператора
CREATE TABLE
. Вы также можете использовать ключевое словоDEFAULT
для того, чтобы установить столбец в его значение по умолчанию (новшество в MySQL 4.0.3). Это облегчает написаниеINSERT
, присвающим значения всем, за исключением одного-двух, столбцам, т.к. такой ситнаксис позволяет вам обойтись без указания списка столбцов, которые операторINSERT
должен обновить. В MySQL всегда предусмотрено значение по умолчанию для каждого поля. Это требование ``навязано'' MySQL, чтобы обеспечить возможность работы как с таблицами, поддерживающими транзакции, так и с таблицами, не поддерживающими их. Наша точка зрения (разработчиков) состоит в том, что проверка содержимого полей должна производиться приложением, а не сервером баз данных. -
Выражение
expression
может относится к любому столбцу, который ранее был внесен в список значений. Например, можно указать следующее:mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
Но нельзя указать:mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
-
Если указывается ключевое слово
LOW_PRIORITY
, то выполнение данной командыINSERT
будет задержано до тех пор, пока другие клиенты не завершат чтение этой таблицы. В этом случае данный клиент должен ожидать, пока данная команда вставки не будет завершена, что в случае интенсивного использования таблицы может потребовать значительного времени. В противоположность этому командаINSERT DELAYED
позволяет данному клиенту продолжать операцию сразу же. See section 6.4.4 Синтаксис оператораINSERT DELAYED
. Следует отметить, что указательLOW_PRIORITY
обычно не используется с таблицамиMyISAM
, поскольку при его указании становятся невозможными параллельные вставки. See section 7.1 ТаблицыMyISAM
. -
Если в команде
INSERT
со строками, имеющими много значений, указывается ключевое словоIGNORE
, то все строки, имеющие дублирующиеся ключиPRIMARY
илиUNIQUE
в этой таблице, будут проигнорированы и не будут внесены. Если не указыватьIGNORE
, то данная операция вставки прекращается при обнаружении строки, имеющей дублирующееся значение существующего ключа. Количество строк, внесенных в данную таблицу, можно определить при помощи функции C APImysql_info()
. -
Если вы указываете
ON DUPLICATE KEY UPDATE
(новшество в MySQL 4.1.0), и производится вставка строки, которая вызывает ошибку дублирующегося первичного (PRIMARY
) или уникального (UNIQUE
) ключа, то вполняетсяUPDATE
старой строки. Например:mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) --> ON DUPLICATE KEY UPDATE c=c+1;
Еслиa
определяется какUNIQUE
и уже содержит1
, то тогда вышеуказанная команда будет аналогична следующей:mysql> UPDATE table SET c=c+1 WHERE a=1;
Внимание: если столбецb
также является уникальным ключем, тоUPDATE
переписывается как:mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
и если несколько записей соответствуютa=1 OR b=2
только одна запись будет обновлена! В общем случае, следует избегать использованияON DUPLICATE KEY
на таблицах со множеством уникальных (UNIQUE
) ключей. Когда используетсяON DUPLICATE KEY UPDATE
, опцияDELAYED
будет проигнорирована. -
Если MySQL был сконфигурирован с использованием опции
DONT_USE_DEFAULT_FIELDS
, то командаINSERT
будет генерировать ошибку, если явно не указать величины для всех столбцов, которые требуют значений не-NULL
. See section 2.3.3 Типичные опцииconfigure
. -
С помощью функции
mysql_insert_id
можно найти величину, использованную для столбцаAUTO_INCREMENT
. See section 8.4.3.31mysql_insert_id()
.
Если задается команда INSERT ... SELECT
или INSERT ... VALUES
со списками
из нескольких значений, то для получения информации о данном запросе можно
использовать функцию C API mysql_info()
. Формат этой информационной строки
приведен ниже:
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
показывает число строк, которые не могли быть внесены,
поскольку они дублировали бы значения некоторых существующих уникальных
индексов. Указатель Warnings
показывает число попыток внести величину в
столбец, который по какой-либо причине оказался проблематичным.
Предупреждения возникают при выполнении любого из следующих условий:
-
Внесение
NULL
в столбец, который был объявлен, какNOT NULL
. Данный столбец устанавливается в значение, заданное по умолчанию. - Установка числового столбца в значение, лежащее за пределами его допустимого диапазона. Данная величина усекается до соответствующей конечной точки этого диапазона.
-
Занесение в числовой столбец такой величины, как
'10.34 a'
. Конечные данные удаляются и вносится только оставшаяся числовая часть. Если величина вовсе не имеет смысла как число, то столбец устанавливается в0
. -
Внесение в столбцы типа
CHAR
,VARCHAR
,TEXT
илиBLOB
строки, превосходящей максимальную длину столбца. Данная величина усекается до максимальной длины столбца. - Внесение в столбец даты или времени строки, недопустимой для данного типа столбца. Этот столбец устанавливается в нулевую величину, соответствующую данному типу.
6.4.3.1 Синтаксис оператора INSERT ... SELECT
INSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ...
Команда INSERT ... SELECT
обеспечивает возможность быстрого внесения
большого количества строк в таблицу из одной или более таблиц.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
Для команды INSERT ... SELECT
необходимо соблюдение следующих условий:
-
Целевая таблица команды
INSERT
не должна появляться в утвержденииFROM
частиSELECT
данного запроса, поскольку в ANSI SQL запрещено производить выборку из той же таблицы, в которую производится вставка. (Проблема заключается в том, что операцияSELECT
, возможно, найдет записи, которые были внесены ранее в течение того же самого прогона команды. При использовании команд, внутри которых содержатся многоступенчатые выборки, можно легко попасть в очень запутанную ситуацию!) -
Столбцы
AUTO_INCREMENT
работают, как обычно. -
Для получения информации о данном запросе можно использовать функцию C
API
mysql_info()
. See section 6.4.3 Синтаксис оператораINSERT
. -
Чтобы гарантировать возможность использования журнала
обновлений/двоичного журнала для восстановления исходного состояния
таблиц, в MySQL во время выполнения команды
INSERT ... SELECT
параллельные вставки не разрешаются.
Разумеется, для перезаписи старых строк можно вместо INSERT
использовать
REPLACE
.
6.4.4 Синтаксис оператора INSERT DELAYED
INSERT DELAYED ...
Опция DELAYED
для команды INSERT
является специфической для MySQL
возможностью, которая очень полезна, если клиент не может ждать завершения
команды INSERT
. Такая проблема встречается часто - она возникает, когда
MySQL используется для ведения журналов (проще говоря, для логгинга) и при
этом периодически запускаются команды SELECT
и UPDATE
, для выполнения
которых требуется много времени. Оператор DELAYED
был введен в версию
MySQL 3.22.15. Он является расширением MySQL к ANSI SQL92.
INSERT DELAYED
работает только с таблицами типа ISAM
и MyISAM
. Следует
учитывать, что таблицы MyISAM
поддерживают одновременное выполнение SELECT
и INSERT
, поэтому если нет свободных блоков в середине файла данных, то
необходимость в применении INSERT DELAYED
возникает очень редко.
See section 7.1 Таблицы MyISAM
.
При использовании оператора INSERT DELAYED
клиент сразу же получает
успешный ответ от сервера, а запись будет добавлена в таблицу сразу же
после того, как эту таблицу перестанет использовать другой поток.
Еще одно существенное преимущество применения оператора INSERT DELAYED
заключается в том, что данные от многих клиентов собираются вместе и
записываются одним блоком. Это намного быстрее, чем несколько отдельных
операций вставки.
Обратите внимание: в настоящее время все записи, поставленные в очередь на
добавление, хранятся только в памяти до тех пор, пока они не будут
записаны на диск. Отсюда следует, что если выполнение mysqld
будет
завершено принудительно (kill -9
) или программа умрет, то все находящиеся
в очереди данные, которые не записаны на диск, будут потеряны!.
Ниже детально описано, что происходит при использовании опции DELAYED
в
командах INSERT
или REPLACE
. В этом описании ``поток'' понимается как
поток, принимающий команду INSERT DELAYED
, а ``обработчик'' - это поток,
который обрабатывает все команды INSERT DELAYED
в конкретной таблице.
-
При выполнении потоком команды
DELAYED
для таблицы создается поток-обработчик для обработки всех командDELAYED
в данной таблице, если подобный обработчик уже не существует. -
Данный поток проверяет, выполнил ли уже обработчик блокировку
DELAYED
; если нет, то он предписывает обработчику сделать это. БлокировкаDELAYED
может быть осуществлена даже в случае, если блокировкиREAD
илиWRITE
на данной таблице уже выполнены другими потоками. Однако обработчик будет ожидать всех блокировокALTER TABLE
и завершения всех командFLUSH TABLES
, чтобы убедиться в том, что структура таблицы соответствует последнему обновлению. -
Поток выполняет команду
INSERT
, но вместо записи строки в таблицу он ставит финальную копию этой строки в очередь, управляемую потоком-обработчиком. Поток отмечает все синтаксические ошибки и сообщает о них клиентской программе. -
Клиент не может уведомить о количестве дубликатов или значении
AUTO_INCREMENT
для данной результирующей строки; он также не может получить эти данные с сервера, поскольку командаINSERT
возвращает результат до полного завершения операции вставки. По той же причине ничего существенного не даст и использование функции C APImysql_info()
. - Обновление журнала обновлений производится потоком-обработчиком после вставки строки в таблицу. В случае многострочной вставки обновление журнала обновлений производится при записи первой строки.
-
После записи каждых
delayed_insert_limit
строк, обработчик проверяет, не находятся ли в ожидании выполнения какие-либо командыSELECT
. Если да, то обработчик перед продолжением своей работы ``пропускает их вперед'' на выполнение. -
Если очередь обработчика больше не содержит строк, то с данной таблицы
будет снята блокировка. Если в течение
delayed_insert_timeout
секунд не поступят никакие новые командыINSERT DELAYED
, то обработчик завершит свою работу. -
Если более, чем
delayed_queue_size
строк уже ожидают в очереди обработчика, то поток, запрашивающийINSERT DELAYED
, будет ждать, пока не освободится место в очереди. Таким образом можно иметь уверенность в том, чтоmysqld
не займет всю память сервера для хранения запросов данной очереди. -
Поток-обработчик будет наблюдаться в списке процессов MySQL со
значением
delayed_insert
в столбцеCommand
. Поток-обработчик можно уничтожить запуском командыFLUSH TABLES
или командойKILL номер_потока
. Однако перед своим завершением он вначале сохранит в таблице все поставленные в очередь строки. В процессе сохранения он не будет принимать никаких новых командINSERT
от иного потока. При выполнении после этого командыINSERT DELAYED
будет создан новый поток-обработчик. Обратите внимание: отсюда следует, что командыINSERT DELAYED
имеют более высокий приоритет, чем обычные командыINSERT
, если уже существует запущенный обработчикINSERT DELAYED
! Другие команды обновления должны ожидать, пока не опустеет очередьINSERT DELAYED
или же пока кто-либо не прекратит выполнение потока-обработчика (с помощьюKILL номер_потока
) или не выполнитFLUSH TABLES
. -
Представленные в таблице переменные обеспечивают информацию об
INSERT DELAYED
:Переменная Значение Delayed_insert_threads
Количество потоков-обработчиков Delayed_writes
Количество строк, записанных INSERT DELAYED
Not_flushed_delayed_rows
Количество строк, ожидающих записи -
Чтобы увидеть эти переменные, следует вызвать команду
SHOW STATUS
или выполнить командуmysqladmin extended-status
.
Обратите внимание: если данная таблица не используется, то команда INSERT
DELAYED
работает медленнее, чем обычная команда INSERT
. Кроме того,
возникает дополнительная нагрузка на сервер, поскольку требуется управлять
отдельным потоком для каждой таблицы, для которой используется INSERT
DELAYED
. Это означает, что команду INSERT DELAYED
следует применять
только тогда, когда в ней есть реальная необходимость!
6.4.5 Синтаксис оператора UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition] [ORDER BY ...] [LIMIT rows] или UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [, tbl_name ...] SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition]
Оператор UPDATE
обновляет столбцы в соответствии с их новыми значениями в
строках существующей таблицы. В выражении SET
указывается, какие именно
столбцы следует модифицировать и какие величины должны быть в них
установлены. В выражении WHERE
, если оно присутствует, задается, какие
строки подлежат обновлению. В остальных случаях обновляются все строки.
Если задано выражение ORDER BY
, то строки будут обновляться в указанном в
нем порядке.
Если указывается ключевое слово LOW_PRIORITY
, то выполнение данной команды
UPDATE
задерживается до тех пор, пока другие клиенты не завершат чтение
этой таблицы.
Если указывается ключевое слово IGNORE
, то команда обновления не будет
прервана, даже если при обновлении возникнет ошибка дублирования ключей.
Строки, из-за которых возникают конфликтные ситуации, обновлены не будут.
Если доступ к столбцу из указанного выражения осуществляется по аргументу
tbl_name
, то команда UPDATE
использует для этого столбца его текущее
значение. Например, следующая команда устанавливает столбец age
в
значение, на единицу большее его текущей величины:
mysql> UPDATE persondata SET age=age+1;
Значения команда UPDATE
присваивает слева направо. Например, следующая
команда удваивает столбец age
, затем инкрементирует его:
mysql> UPDATE persondata SET age=age*2, age=age+1;
Если столбец устанавливается в его текущее значение, то MySQL замечает это и не обновляет его.
Команда UPDATE
возвращает количество фактически измененных строк. В
версии MySQL 3.22 и более поздних функция C API mysql_info()
возвращает
количество строк, которые были найдены и обновлены, и количество
предупреждений, имевших место при выполнении UPDATE
.
В версии MySQL 3.23 можно использовать LIMIT #
, чтобы убедиться, что было
изменено только заданное количество строк.
Начиная с версии MySQL 4.0.4 вы также можете выполнять UPDATE
, охватывающий множество таблиц:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
Обратите внимание: вы не можете использовать ORDER BY
или LIMIT
для многотабличных обновлений.
6.4.6 Синтаксис оператора DELETE
DELETE [LOW_PRIORITY] [QUICK] FROM table_name [WHERE where_definition] [ORDER BY ...] [LIMIT rows]
или
DELETE [LOW_PRIORITY] [QUICK] table_name[.*] [, table_name[.*] ...] FROM table-references [WHERE where_definition]
или
DELETE [LOW_PRIORITY] [QUICK] FROM table_name[.*] [, table_name[.*] ...] USING table-references [WHERE where_definition]
Оператор DELETE
удаляет из таблицы table_name
строки, удовлетворяющие
заданным в where_definition
условиям, и возвращает число удаленных
записей.
Если оператор DELETE
запускается без определения WHERE
, то удаляются все
строки. При работе в режиме AUTOCOMMIT
это будет аналогично использованию
оператора TRUNCATE
. See section 6.4.7 Синтаксис оператора TRUNCATE
. В MySQL 3.23 оператор
DELETE
без определения WHERE
возвратит ноль как число удаленных записей.
Если действительно необходимо знать число удаленных записей при удалении
всех строк, и если допустимы потери в скорости, то можно использовать
команду DELETE
в следующей форме:
mysql> DELETE FROM table_name WHERE 1>0;
Следует учитывать, что эта форма работает намного медленнее, чем DELETE
FROM table_name
без выражения WHERE
, поскольку строки удаляются
поочередно по одной.
Если указано ключевое слово LOW_PRIORITY
, выполнение данной команды DELETE
будет задержано до тех пор, пока другие клиенты не завершат чтение этой
таблицы.
Если задан параметр QUICK
, то обработчик таблицы при выполнении удаления
не будет объединять индексы - в некоторых случаях это может ускорить
данную операцию.
В таблицах MyISAM
удаленные записи сохраняются в связанном списке, а
последующие операции INSERT
повторно используют места, где располагались
удаленные записи. Чтобы возвратить неиспользуемое пространство и уменьшить
размер файлов, можно применить команду OPTIMIZE TABLE
или утилиту
myisamchk
для реорганизации таблиц. Команда OPTIMIZE TABLE
проще, но
утилита myisamchk
работает быстрее. See section 4.5.1 Синтаксис команды OPTIMIZE TABLE
. See section 4.4.6.10 Оптимизация таблиц.
Первый из числа приведенных в начале данного раздела многотабличный формат
команды DELETE
поддерживается, начиная с MySQL 4.0.0. Второй
многотабличный формат поддерживается, начиная с MySQL 4.0.2.
Идея заключается в том, что удаляются только совпадающие строки из таблиц,
перечисленных перед выражениями FROM
или USING
. Это позволяет удалять
единовременно строки из нескольких таблиц, а также использовать для поиска
дополнительные таблицы.
Символы .*
после имен таблиц требуются только для совместимости с Access:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
или
DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
В предыдущем случае просто удалены совпадающие строки из таблиц t1
и t2
.
Если применяется выражение ORDER BY
(доступно с версии MySQL 4.0), то
строки будут удалены в указанном порядке. В действительности это выражение
полезно только в сочетании с LIMIT
. Например:
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp LIMIT 1
Данный оператор удалит самую старую запись (по timestamp
), в которой
строка соответствует указанной в выражении WHERE
.
Специфическая для MySQL опция LIMIT
для команды DELETE
указывает
серверу максимальное количество строк, которые следует удалить до возврата
управления клиенту. Эта опция может использоваться для гарантии того, что
данная команда DELETE
не потребует слишком много времени для выполнения.
Можно просто повторять команду DELETE
до тех пор, пока количество
удаленных строк меньше, чем величина LIMIT
.
С MySQL 4.0 вы можете указать множество таблиц в DELETE
чтобы удалить записи из одной таблицы, основываясь на
условии по множеству таблиц. Однако, с такой формой оператора DELETE
нельзя использовать ORDER BY
или LIMIT
.
6.4.7 Синтаксис оператора TRUNCATE
TRUNCATE TABLE table_name
В версии 3.23 TRUNCATE TABLE
выполняет последовательность "COMMIT ; DELETE
FROM table_name"
. See section 6.4.6 Синтаксис оператора DELETE
.
TRUNCATE TABLE
имеет следующие отличия от DELETE FROM ...
:
- Эта операция удаляет и воссоздает таблицу, что намного быстрее, чем поочередное удаление строк.
- Операция является нетранзакционной; если одновременно выполняется транзакция или активная блокировка таблицы, то можно получить ошибку.
- Не возвращает количество удаленных строк.
- Пока существует корректный файл `table_name.frm', таблицу можно воссоздать с его с помощью, даже если файлы данных или индексов повреждены.
TRUNCATE
является расширением Oracle SQL.
6.4.8 Синтаксис оператора REPLACE
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES (expression,...),(...),... или REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT ... или REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name=expression, col_name=expression,...
Оператор REPLACE
работает точно так же, как INSERT
, за исключением того,
что если старая запись в данной таблице имеет то же значение индекса
UNIQUE
или PRIMARY KEY
, что и новая, то старая запись перед занесением
новой будет удалена. See section 6.4.3 Синтаксис оператора INSERT
.
Другими словами, команда REPLACE
не предоставляет доступа к замещаемой
записи. В некоторых старых версиях MySQL такой доступ иногда оказывался
возможным, но это был дефект, который уже исправлен.
Для использования REPLACE
у вас должны быть привилегии INSERT
и DELETE
для таблицы.
При использовании команды REPLACE
функция mysql_affected_rows()
вернет
значение, равное 2
, если старая строка была заменена новой. Объясняется
это тем, что в таблицу вставляется строка после того, как удаляется дубликат.
Это позволяет легко определять, какое действие произвела команда REPLACE
-
добавление или замещение строки. Достаточно просто проверить, какое число
вернула функция mysql_affected_rows()
- 1
(строка добавлена) или 2
(замещена).
Следует учитывать, что, если не используются индексы UNIQUE
или PRIMARY
KEY
, то применение команды REPLACE
не имеет смысла, так как она работает
просто как INSERT
.
6.4.9 Синтаксис оператора LOAD DATA INFILE
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE tbl_name [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES TERMINATED BY '\n'] [IGNORE number LINES] [(col_name,...)]
Команда LOAD DATA INFILE
читает строки из текстового файла и вставляет
их в таблицу с очень высокой скоростью. Если задано ключевое слово LOCAL
,
то файл читается с клиентского хоста. Если же LOCAL
не указывается, то
файл должен находиться на сервере. (Опция LOCAL
доступна в версии MySQL
3.22.6 и более поздних.)
Если текстовые файлы, которые нужно прочитать, находятся на сервере, то из
соображений безопасности эти файлы должны либо размещаться в директории
базы данных, либо быть доступными для чтения всем пользователям. Кроме
того, для применения команды LOAD DATA INFILE
к серверным файлам
необходимо обладать привилегиями FILE
для серверного хоста.
See section 4.2.7 Привилегии, предоставляемые MySQL.
В версиях MySQL 3.23.49 и MySQL 4.0.2 команда LOCAL
не будет работать в
случаях, если демон mysqld
запущен с параметром --local-infile=0
или если
для клиента не включена возможность поддержки LOCAL
. See section 4.2.4 Вопросы безопасности, относящиеся к команде LOAD DATA LOCAL.
Если указывается ключевое слово LOW_PRIORITY
, то выполнение данной команды
LOAD DATA
будет задержано до тех пор, пока другие клиенты не завершат
чтение этой таблицы.
Если указывается ключевое слово CONCURRENT
при работе с таблицами MyISAM
,
то другие потоки могут извлекать данные из таблицы во время выполнения
команды LOAD DATA
. Использование этой возможности, конечно, будет немного
влиять на производительность выполнения LOAD DATA
, даже если никакой
другой поток не использует данную таблицу в это же время.
При применении опции LOCAL
выполнение может происходить несколько
медленнее в сравнении с предоставлением серверу доступа к файлам напрямую,
поскольку содержимое файла должно переместиться с клиентского хоста на
сервер. С другой стороны, в этом случае нет необходимости в привилегиях
FILE
для загрузки локальных файлов.
При использовании версий MySQL до 3.23.24 при помощи команды LOAD DATA
INFILE
нельзя выполнять чтение из FIFO
. Если необходимо читать из FIFO
(например, стандартный вывод gunzip
), следует использовать LOAD DATA
LOCAL INFILE
.
Можно также загружать файлы данных, используя утилиту mysqlimport
. Эта
утилита выполняет загрузку файлов путем посылки на сервер команд LOAD
DATA INFILE
. Опция --local
заставляет mysqlimport
читать файлы данных с
клиентского хоста. Можно указать параметр --compress
, чтобы получить
лучшую производительность при работе через медленные сети, если и клиент,
и сервер поддерживают протокол сжатия данных.
В случаях, когда файлы находятся на сервере, последний действует по следующим правилам:
- Если задан абсолютный (полный) путь к файлу, то сервер использует этот путь без изменений.
-
Если задан относительный путь к файлу с указанием одного или более
начальных каталогов, то поиск файла будет осуществляться относительно
указанных каталогов в каталоге данных сервера (
datadir
). - Если дается путь к файлу без указания начальных каталогов, то сервер ищет этот файл в директории используемой базы данных.
Отсюда следует, что файл, заданный как `./myfile.txt', читается из
серверного каталога данных, в то время как файл, заданный как `myfile.txt',
читается из каталога используемой базы данных. Например, следующая команда
LOAD DATA
читает файл data.txt
в каталоге базы данных для db1
, поскольку
db1
является текущей базой данных, даже если эта команда явно содержит
указание загрузить файл в таблицу базы данных db2
:
mysql> USE db1; mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;
Ключевые слова REPLACE
и IGNORE
управляют обработкой входных записей,
которые дублируют существующие записи с теми же величинами уникальных
ключей. Если указать REPLACE
, то новые строки заменят существующие с таким
же уникальным ключом. Если указать IGNORE
, то входные строки, имеющие тот
же уникальный ключ, что и существующие, будут пропускаться. Если не указан
ни один из параметров, то при обнаружении дублирующегося значения ключа
возникает ошибка и оставшаяся часть текстового файла игнорируется.
Если данные загружаются из локального файла с использованием ключевого
слова LOCAL
, то сервер не сможет прервать передачу данных посреди этой
операции, поэтому по умолчанию выполнение команды происходит так же, как и
в случае, когда указывается IGNORE
.
При использовании LOAD DATA INFILE
на пустых таблицах MyISAM
все
неуникальные индексы создаются в отдельном пакете (как в REPAIR
). Обычно
это значительно ускоряет работу LOAD DATA INFILE
в случае большого
количества индексов.
Команда LOAD DATA INFILE
является дополнительной к SELECT ... INTO
OUTFILE
. See section 6.4.1 Синтаксис оператора SELECT
. Чтобы записать данные из базы данных в
файл, используется SELECT ... INTO OUTFILE
. Чтобы прочитать данные
обратно в базу данных, используется LOAD DATA INFILE
. Синтаксис FIELDS
и
LINES
одинаков в обеих командах. Обе части являются необязательными, но
если указаны оба, то FIELDS
должно предшествовать LINES
.
Если указывается FIELDS
, то каждое из его подвыражений (TERMINATED BY
,
[OPTIONALLY] ENCLOSED BY
, и ESCAPED BY
) также является
необязательным, однако необходимо указать по меньшей мере одно из них.
Если утверждение FIELDS
не определено, то по умолчанию его параметры будут
принимать следующие значения:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Если утверждение LINES
не определено, то по умолчанию оно имеет следующую
структуру:
LINES TERMINATED BY '\n'
Иными словами, при установках по умолчанию команда LOAD DATA INFILE
при
чтении входных данных будет работать следующим образом:
- Искать концы строк в виде символов `\n'
- Разбивать строки на поля по символам табуляции.
- Не ожидать, что поля могут быть заключены в символы цитирования.
- Интерпретировать встречающиеся символы табуляции, новой строки или `\', предваренные `\', как литералы, являющиеся частью значения поля.
И, наоборот, если действуют установки по умолчанию при записи выходных
данных, команда SELECT ... INTO OUTFILE
будет работать следующим образом:
- Вставлять символы табуляции между полями.
- Не заключать поля в символы цитирования. Использовать символы `\' для экранирования экземпляров символов табуляции, новой строки или `\', которые появляются среди величин поля.
- Вставлять символы новой строки в конце каждой записи.
Следует учитывать, что в записи FIELDS ESCAPED BY `\'
необходимо
указывать два обратных слеша для величины, которая должна читаться как
один обратный слеш.
Опцию IGNORE number LINES
можно применять для игнорирования заголовка
имен столбцов в начале файла:
mysql> LOAD DATA INFILE "/tmp/file_name" INTO TABLE test IGNORE 1 LINES;
При использовании SELECT ... INTO OUTFILE
совместно с LOAD DATA INFILE
для того, чтобы данные из базы данных прочитать в файл, а затем - обратно
из файла в базу данных, опции, обрабатывающие поля и строки, для обеих
команд должны совпадать. В противном случае LOAD DATA INFILE
не сможет
интерпретировать содержимое данного файла правильно. Предположим, что
команда SELECT ... INTO OUTFILE
используется для записи в файл с полями,
разделенными запятыми:
mysql> SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM ...;
Чтобы прочитать этот разделенный запятыми файл обратно в базу данных, корректная команда должна иметь вид:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';
Если вместо этого попытаться прочитать этот файл с помощью команды,
представленной ниже, то она не будет работать, поскольку предписывает
команде LOAD DATA INFILE
искать символы табуляции между полями:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';
Похожий результат получился бы, если бы каждая входная строка интерпретировалась как отдельное поле.
Команду LOAD DATA INFILE
можно также использовать для чтения файлов,
полученных из внешних источников. Например, поля в файле формата базе
данных dBASE будут разделены запятыми и заключены в двойные кавычки. Если
строки в данном файле заканчиваются символами новой строки, то для записи
файла можно использовать приведенную ниже команду, в которой
проиллюстрировано задание опций, обрабатывающих поля и строки:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
Любая из опций, обрабатывающих поля и строки, может задавать пустую строку
(''). Если строка не пустая, то величины опций FIELDS [OPTIONALLY]
ENCLOSED BY
и FIELDS ESCAPED BY
должны содержать один символ. Величины
опций FIELDS TERMINATED BY
и LINES TERMINATED BY
могут содержать более
чем один символ. Например, чтобы записать строки, заканчивающиеся парами
``возврат каретки - перевод строки'' (как в текстовых файлах MS DOS или
Windows), необходимо задать следующее выражение:
LINES TERMINATED BY '\r\n'
.
Например, чтобы прочитать файл `jokes', в котором строки разделены
символами %%
, в таблицу SQL, необходимо сделать следующее:
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
служит для управления полями,
заключенными в заданные символы. Если параметр OPTIONALLY
опущен, то в
выводе (SELECT ... INTO OUTFILE)
все поля будут заключены в символы,
заданные в 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
и VARCHAR
:
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
не сможет правильно прочитать. Например, если символ экранирования
является пустой строкой, то вывод, представленный выше, окажется таким,
как показано ниже. Обратите внимание: второе поле в четвертой строке
содержит запятую, следующую за кавычкой, которая (ошибочно) появляется,
чтобы ограничить данное поле:
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
, встречающиеся внутри поля,
интерпретируются как одиночные символы 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
не пустой, он
используется в качестве префикса для следующих символов в выводе:
-
Символ
FIELDS ESCAPED BY
-
Символ
FIELDS [OPTIONALLY] ENCLOSED BY
-
Первый символ величин
FIELDS TERMINATED BY и LINES TERMINATED BY
-
Символ ASCII
0
(в действительности после экранирующего символа пишется ASCII `0', а не байт с нулевой величиной)
Если символ FIELDS ESCAPED BY
пустой, то никакие символы не
экранируются. На самом деле указывать пустой экранирующий символ нет
смысла, особенно если величины полей в обрабатываемых данных содержат
какие-либо из символов, указанных в приведенном выше списке.
Если символ FIELDS ESCAPED BY
не пуст, то в случае входных данных
вхождения такого символа удаляются и следующий за таким вхождением символ
принимается буквально как часть величины поля. Исключениями являются
экранированные `0' или `N' (например, \0
или \N
, если экранирующим
символом является `\'). Эти последовательности интерпретируются как ASCII
0
(байт с нулевой величиной) и NULL
. См. ниже правила обработки величины
NULL
.
Чтобы получить более полную информацию о синтаксисе экранирующего символа `\' см. раздел section 6.1.1 Литералы: представление строк и чисел.
В ряде случаев опции обработки полей и строк взаимодействуют:
-
Если
LINES TERMINATED BY
является пустой строкой иFIELDS TERMINATED BY
является не пустой строкой, то строки также заканчиваются символамиFIELDS TERMINATED BY
. -
Если обе величины
FIELDS TERMINATED BY
иFIELDS ENCLOSED BY
являются пустыми (''), то применяется формат с фиксированной строкой (без разделителей). В формате с фиксированной строкой не предусмотрены никакие разделители между полями. Вместо этого при чтении и записи величин столбцов используется ширина ``вывода'' столбцов. Например, если столбец объявлен какINT(7)
, значения для этого столбца записываются с использованием полей шириной7
символов. Входные значения для этого столбца получаются чтением7
символов. Формат с фиксированной строкой влияет также на обработку величин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
и пустая строка в данной таблице будут неразличимы при записи в файл, поскольку они обе записываются как пустые строки. Если необходимо, чтобы эти величины были различными при обратном чтении файла, то не следует использовать формат с фиксированной строкой.
Некоторые случаи, не поддерживаемые оператором 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
:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Список полей не указывается, следовательно, команда LOAD DATA INFILE
ожидает входные строки для заполнения каждого столбца таблицы. При этом
используются значения FIELDS
и LINES
по умолчанию.
Если требуется загрузить только некоторые из столбцов таблицы, необходимо задать список столбцов:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);
Список полей необходимо задавать и в случаях, если порядок следования полей во входном файле отличается от порядка столбцов в данной таблице. В противном случае MySQL не сможет установить соответствие вводимых полей и столбцов таблицы.
Если строка имеет слишком мало полей, то столбцы, для которых отсутствуют
поля во входном файле, устанавливаются в свои значения по умолчанию.
Назначение величин по умолчанию описывается в разделе section 6.5.3 Синтаксис оператора CREATE TABLE
.
Значение пустого поля интерпретируется иначе, чем отсутствие значения:
- Для строковых типов столбец устанавливается в пустую строку.
-
Для числовых типов столбец устанавливается в
0
. - Для типов даты и времени столбец устанавливается в соответствующее этому типу значение ``ноль''. See section 6.2.2 Типы данных даты и времени.
Отметим, что это те же самые величины, которые окажутся в столбце в
результате явного назначения пустой строки столбцам строкового, числового
типов, либо типов даты или времени в команде INSERT
или UPDATE
.
Столбцы типа TIMESTAMP
устанавливаются только в текущую дату или время в
случаях, если для столбца назначено значение NULL
или (только для первого
столбца TIMESTAMP
) если столбец TIMESTAMP
находится вне списка полей, если
такой список задан.
Если входная строка имеет слишком много полей, то лишние поля игнорируются и количество предупреждений увеличится.
Команда LOAD DATA INFILE
интерпретирует все входные данные как строки,
поэтому нельзя указывать числовые величины для столбцов ENUM
или SET
так
же, как для команд INSERT
. Все величины ENUM
и SET
должны быть заданы как
строки!
При использовании C API можно получить информацию о запросе, вызвав
функцию API mysql_info()
по окончании запроса LOAD DATA INFILE
. Ниже
показан формат строки информации для этого случая:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Предостережения выдаются при тех же обстоятельствах, что и при записи
величин командой INSERT
(see section 6.4.3 Синтаксис оператора INSERT
), за исключением того,
что команда LOAD DATA INFILE
дополнительно генерирует предупреждения,
когда во входной строке слишком мало или слишком много полей.
Предостережения нигде не хранятся; количество предупреждений может
использоваться только для того, чтобы проверить, нормально ли выполнились
указанные действия. Если необходимо точно знать причины предупреждений, то
следует выполнить команду SELECT ... INTO OUTFILE
в другой файл и
сравнить результат с первоначальным входным файлом - это единственный
способ получить такую информацию.
Если необходимо выполнить LOAD DATA
для чтения из канала, можно применить
следующий трюк:
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
При использовании версии MySQL старше, чем 3.23.25, вышеприведенное можно
сделать только с LOAD DATA LOCAL INFILE
.
Чтобы получить более подробную информацию об эффективности INSERT
в
сравнении с LOAD DATA INFILE
и увеличении скорости LOAD DATA INFILE
,
см. раздел section 5.2.9 Скорость выполнения запросов INSERT
.
6.4.10 Синтаксис оператора DO
DO expression, [expression, ...]
Выполняет данное выражение, но не возвращает какой-либо результат.
Является сокращенной формой оператора SELECT expression, expression
, но
преимущество его заключается в том, что он работает немного быстрее, если
нет необходимости в возвращении результата.
Оператор главным образом полезен при использовании с функциями, имеющими
побочные эффекты, такими как RELEASE_LOCK
.
6.5 Определение данных: CREATE
, DROP
, ALTER
6.5.1 Синтаксис оператора CREATE DATABASE
CREATE DATABASE [IF NOT EXISTS] db_name
Оператор CREATE DATABASE
создает базу данных с указанным именем. Правила
для допустимых имен базы данных приведены в разделе section 6.1.2 Имена баз данных, таблиц, столбцов, индексы псевдонимы. Если база данных уже существует и не
указан ключевой параметр IF NOT EXISTS
, то возникает ошибка выполнения
команды.
Базы данных в MySQL реализуются как директории, содержащие файлы, которые
соответствуют таблицам в базе данных. Поскольку при первоначальном
создании база данных не содержит таблиц, то команда CREATE DATABASE
создает только соответствующую поддиректорию в директории данных MySQL.
Базы данных можно также создавать с помощью утилиты mysqladmin
.
See section 4.8 Клиентские сценарии и утилиты MySQL.
6.5.2 Синтаксис оператора DROP DATABASE
DROP DATABASE [IF EXISTS] db_name
Оператор DROP DATABASE
удаляет все таблицы в указанной базе данных и саму
базу. Если вы выполняете DROP DATABASE
на базе данных, символически
связанной с другой, то удаляется как ссылка, так и оригинальная база
данных. Будьте ОЧЕНЬ внимательны при работе с этой командой!
Оператор DROP DATABASE
возвращает количество файлов, которые были удалены
из директории базы данных. Как правило, это число равно количеству таблиц,
умноженному на три, поскольку обычно каждая таблица представлена тремя
файлами - `.MYD'-файлом, `MYI'-файлом и `.frm'-файлом.
Команда DROP DATABASE
удаляет из директории указанной базы данных все
файлы со следующими расширениями:
Расширение | Расширение | Расширение | Расширение |
.BAK | .DAT | .HSH | .ISD |
.ISM | .ISM | .MRG | .MYD |
.MYI | .db | .frm |
Все поддиректории, имена которых состоят из двух цифр (RAID
-директории),
также удаляются.
В версии MySQL 3.22 и более поздних можно использовать ключевые слова IF
EXISTS
для предупреждения ошибки, если указанная база данных не
существует.
Можно также удалять базы данных с помощью утилиты mysqladmin
.
See section 4.8 Клиентские сценарии и утилиты MySQL.
6.5.3 Синтаксис оператора CREATE TABLE
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options] [select_statement] или CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name LIKE old_table_name; create_definition: col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [PRIMARY KEY] [reference_definition] или PRIMARY KEY (index_col_name,...) или KEY [index_name] (index_col_name,...) или INDEX [index_name] (index_col_name,...) или UNIQUE [INDEX] [index_name] (index_col_name,...) или FULLTEXT [INDEX] [index_name] (index_col_name,...) или [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] или CHECK (expr) type: 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] или CHAR(length) [BINARY] или VARCHAR(length) [BINARY] или DATE или TIME или TIMESTAMP или DATETIME или TINYBLOB или BLOB или MEDIUMBLOB или LONGBLOB или TINYTEXT или TEXT или MEDIUMTEXT или LONGTEXT или ENUM(value1,value2,value3,...) или SET(value1,value2,value3,...) index_col_name: col_name [(length)] reference_definition: REFERENCES tbl_name [(index_col_name,...)] [MATCH FULL | MATCH PARTIAL] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT table_options: TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM } или AUTO_INCREMENT = # или AVG_ROW_LENGTH = # или CHECKSUM = {0 | 1} или COMMENT = "string" или MAX_ROWS = # или MIN_ROWS = # или PACK_KEYS = {0 | 1 | DEFAULT} или PASSWORD = "string" или DELAY_KEY_WRITE = {0 | 1} или ROW_FORMAT= { default | dynamic | fixed | compressed } или RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=# RAID_CHUNKSIZE=# или UNION = (table_name,[table_name...]) или INSERT_METHOD= {NO | FIRST | LAST } или DATA DIRECTORY="абсолютный путь к каталогу" или INDEX DIRECTORY="абсолютный путь к каталогу" select_statement: [IGNORE | REPLACE] SELECT ... (любое корректное выражение SELECT)
Оператор CREATE TABLE
создает таблицу с заданным именем в текущей базе
данных. Правила для допустимых имен таблицы приведены в разделе section 6.1.2 Имена баз данных, таблиц, столбцов, индексы псевдонимы. Если нет активной текущей базы
данных или указанная таблица уже существует, то возникает ошибка
выполнения команды.
В версии MySQL 3.22 и более поздних имя таблицы может быть указано как
db_name.tbl_name
. Эта форма записи работает независимо от того, является
ли указанная база данных текущей.
Начиная с MySQL 3.23 при создании таблицы можно использовать ключевое слово
TEMPORARY
. Временная таблица автоматически удаляется по завершении
соединения, а ее имя действительно только в течение данного соединения.
Это означает, что в двух разных соединениях могут использоваться временные
таблицы с одинаковыми именами без конфликта друг с другом или с
существующей таблицей с тем же именем (существующая таблица скрыта, пока
не удалена временная таблица). С версии MySQL 4.0.2 для создания временных
таблиц необходимо иметь привилегии CREATE TEMPORARY TABLES
.
В версии MySQL 3.23 и более поздних можно использовать ключевые слова IF
NOT EXISTS
для того, чтобы не возникала ошибка, если указанная таблица
уже существует. Следует учитывать, что при этом не проверяется
идентичность структур этих таблиц.
В MySQL 4.1 вы можете указать LIKE
чтобы создавать таблицу, основываясь на
определении другой, уже существующей, таблицы. В MySQL 4.1 также можете
определять тип автоматически создаваемого столбца:
CREATE TABLE foo (a tinyint not null) SELECT b+1 AS 'a' FROM bar;
Каждая таблица tbl_name
представлена определенными файлами в директории
базы данных. В случае таблиц типа MyISAM
это следующие файлы:
Файл | Назначение |
tbl_name.frm | Файл определения таблицы |
tbl_name.MYD | Файл данных |
tbl_name.MYI | Файл индексов |
Чтобы получить более полную информацию о свойствах различных типов столбцов, section 6.2 Типы данных столбцов:
-
Если не указывается ни
NULL
, ниNOT NULL
, то столбец интерпретируется так, как будто указаноNULL
. -
Целочисленный столбец может иметь дополнительный атрибут
AUTO_INCREMENT
. При записи величиныNULL
(рекомендуется) или0
в столбецAUTO_INCREMENT
данный столбец устанавливается в значениеvalue+1
, гдеvalue
представляет собой наибольшее для этого столбца значение в таблице на момент записи. ПоследовательностьAUTO_INCREMENT
начинается с1
. See section 8.4.3.31mysql_insert_id()
. Если удалить строку, содержащую максимальную величину для столбцаAUTO_INCREMENT
, то в таблицах типаISAM
илиBDB
эта величина будет восстановлена, а в таблицах типаMyISAM
илиInnoDB
- нет. Если удалить все строки в таблице командойDELETE FROM table_name
(без выраженияWHERE
) в режимеAUTOCOMMIT
, то для таблиц всех типов последовательность начнется заново. Примечание: в таблице может быть только один столбецAUTO_INCREMENT
, и он должен быть индексирован. Кроме того, версия MySQL 3.23 будет правильно работать только с положительными величинами столбцаAUTO_INCREMENT
. В случае внесения отрицательного числа оно интерпретируется как очень большое положительное число. Это делается, чтобы избежать проблем с точностью, когда числа ``заворачиваются'' от положительного к отрицательному и, кроме того, для гарантии, что по ошибке не будет получен столбецAUTO_INCREMENT
со значением0
. В таблицахMyISAM
иBDB
можно указать вторичный столбецAUTO_INCREMENT
с многостолбцовым ключом. See section 3.5.9 Использование атрибута AUTO_INCREMENT. Последнюю внесенную строку можно найти с помощью следующего запроса (чтобы сделать MySQL совместимым с некоторыми ODBC-приложениями):SELECT * FROM tbl_name WHERE auto_col IS NULL
-
CREATE TABLE
автоматически принимает текущую открытую транзакцию в InnoDB если в MySQL включен двоичный журнал. -
Величины
NULL
для столбца типаTIMESTAMP
обрабатываются иначе, чем для столбцов других типов. В столбцеTIMESTAMP
нельзя хранить литералNULL
; при установке данного столбца вNULL
он будет установлен в текущее значение даты и времени. Поскольку столбцыTIMESTAMP
ведут себя подобным образом, то атрибутыNULL
иNOT NULL
неприменимы в обычном режиме и игнорируются при их задании. С другой стороны, чтобы облегчить клиентам MySQL использование столбцовTIMESTAMP
, сервер сообщает, что таким столбцам могут быть назначены величиныNULL
(что соответствует действительности), хотя реальноTIMESTAMP
никогда не будет содержать величиныNULL
. Это можно увидеть, применивDESCRIBE tbl_name
для получения описания данной таблицы. Следует учитывать, что установка столбцаTIMESTAMP
в0
не равнозначна установке его вNULL
, поскольку0
дляTIMESTAMP
является допустимой величиной. -
Величина
DEFAULT
должна быть константой, она не может быть функцией или выражением. Если для данного столбца не задается никакой величиныDEFAULT
, то MySQL автоматически назначает ее. Если столбец может приниматьNULL
как допустимую величину, то по умолчанию присваивается значениеNULL
. Если столбец объявлен какNOT NULL
, то значение по умолчанию зависит от типа столбца:-
Для числовых типов, за исключением объявленных с атрибутом
AUTO_INCREMENT
, значение по умолчанию равно0
. Для столбцаAUTO_INCREMENT
значением по умолчанию является следующее значение в последовательности для этого столбца. -
Для типов даты и времени, отличных от
TIMESTAMP
, значение по умолчанию равно соответствующей нулевой величине для данного типа. Для первого столбцаTIMESTAMP
в таблице значение по умолчанию представляет собой текущее значение даты и времени. See section 6.2.2 Типы данных даты и времени. Для типов даты и времени, отличных отTIMESTAMP
, значение по умолчанию равно соответствующей нулевой величине для данного типа. Для первого столбцаTIMESTAMP
в таблице значение по умолчанию представляет собой текущее значение даты и времени. See section 6.2.2 Типы данных даты и времени. -
Для строковых типов, кроме
ENUM
, значением по умолчанию является пустая строка. ДляENUM
значение по умолчанию равно первой перечисляемой величине.
NOW()
илиCURRENT_DATE
. -
Для числовых типов, за исключением объявленных с атрибутом
-
KEY
является синонимом дляINDEX
. -
В MySQL ключ
UNIQUE
может иметь только различающиеся значения. При попытке добавить новую строку с ключом, совпадающим с существующей строкой, возникает ошибка выполнения команды. -
PRIMARY KEY
представляет собой уникальный ключKEY
с дополнительным ограничением, что все столбцы с данным ключом должны быть определены какNOT NULL
. В MySQL этот ключ называетсяPRIMARY
(первичный). Таблица может иметь только один первичный ключPRIMARY KEY
. ЕслиPRIMARY KEY
отсутствует в таблицах, а некоторое приложение запрашивает его, то MySQL может превратить вPRIMARY KEY
первый ключUNIQUE
, не имеющий ни одного столбцаNULL
. -
PRIMARY KEY
может быть многостолбцовым индексом. Однако нельзя создать многостолбцовый индекс, используя в определении столбца атрибут ключаPRIMARY KEY
. Именно таким образом только один столбец будет отмечен как первичный. Необходимо использовать синтаксисPRIMARY KEY(index_col_name, ...
). -
Если ключ
PRIMARY
илиUNIQUE
состоит только из одного столбца и он принадлежит к числовому типу, то на него можно сослаться также как на_rowid
(новшество версии 3.23.11). -
Если индексу не назначено имя, то ему будет присвоено первое имя в
index_col_name
, возможно, с суффиксами (_2
,_3
,...
), делающими это имя уникальным. Имена индексов для таблицы можно увидеть, используяSHOW INDEX FROM tbl_name
.SHOW Syntax
. -
Только таблицы типов
MyISAM
,InnoDB
иBDB
поддерживают индексы столбцов, которые могут иметь величиныNULL
. В других случаях, во избежание ошибки, необходимо объявлять такие столбцы какNOT NULL
. -
С помощью выражения
col_name(length)
можно указать индекс, для которого используется только часть столбцаCHAR
илиVARCHAR
. Это поможет сделать файл индексов намного меньше. See section 5.4.4 Индексы столбцов. -
Индексацию столбцов
BLOB
иTEXT
поддерживают только таблицы с типомMyISAM
. Назначая индекс столбцу с типомBLOB
илиTEXT
, всегда НЕОБХОДИМО указывать длину этого индекса:CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
-
При использовании выражений
ORDER BY
илиGROUP BY
со столбцом типаTEXT
илиBLOB
используются только первыеmax_sort_length
байтов. See section 6.2.3.2 Типы данныхBLOB
иTEXT
. -
В версии MySQL 3.23.23 и более поздних можно создавать также
специальные индексы
FULLTEXT
. Они применяются для полнотекстового поиска. Эти индексы поддерживаются только таблицами типаMyISAM
и они могут быть созданы только из столбцовCHAR
,VARCHAR
иTEXT
. Индексирование всегда выполняется для всего столбца целиком, частичная индексация не поддерживается. Более подробно эта операция описана в разделе MySQL section 6.8 Полнотекстовый поиск в MySQL. -
Выражения
FOREIGN KEY
,CHECK
иREFERENCES
фактически ничего не делают. Они введены только из соображений совместимости, чтобы облегчить перенос кода с других SQL-серверов и запускать приложения, создающие таблицы со ссылками. See section 1.9.3 Расширения MySQL к ANSI SQL92. -
В MySQL версии 3.23.44 или более поздней, таблицы InnoDB выполняют проверку
ограничений внешнего ключа. See section 7.5 Таблицы
InnoDB
. Однако обратите внимание, что синтаксисFOREIGN KEY
в InnoDB более строгий чем приведенный выше. InnoDB не допускает указанияindex_name
. Также столбцы таблицы, на которую ссылаются, должны быть явно указаны. Начиная с 4.0.8 InnoDB поддерживает действияON DELETE
иON UPDATE
. Для уточнения синтаксиса см. документацию по InnoDB. See section 7.5 ТаблицыInnoDB
. Для остальных типов таблиц, MySQL делает синтаксической разбор указанийFOREIGN KEY
,CHECK
иREFERENCES
вCREATE TABLE
, но при этом успешно их игнорирует. See section 1.9.4.5 Внешние ключи. -
Для каждого столбца
NULL
требуется один дополнительный бит, при этом величина столбца округляется в большую сторону до ближайшего байта. -
Максимальную длину записи в байтах можно вычислить следующим образом:
длина записи = 1 + (сумма длин столбцов) + (количество столбцов с допустимым NULL + 7)/8 + (количество столбцов с динамической длинной)
-
Опции
table_options
иSELECT
реализованы только в версиях MySQL 3.23 и выше. Ниже представлены различные типы таблиц:
See section 7 Типы таблиц MySQL. Если задается тип таблицы, который не поддерживается данной версией, то MySQL выберет из возможных типов ближайший к указанному. Например, если задаетсяТип таблицы Описание BDB или BerkeleyDB Таблицы с поддержкой транзакций и блокировкой страниц. See section 7.6 Таблицы BDB
или BerkeleyDB.HEAP Данные для этой таблицы хранятся только в памяти. See section 7.4 Таблицы HEAP
.ISAM Оригинальный обработчик таблиц. See section 7.3 Таблицы ISAM
.InnoDB Таблицы с поддержкой транзакций и блокировкой строк. See section 7.5 Таблицы InnoDB
.MERGE Набор таблиц MyISAM, используемый как одна таблица. See section 7.2 Таблицы MERGE
.MRG_MyISAM Псевдоним для таблиц MERGE MyISAM Новый обработчик, обеспечивающий переносимость таблиц в бинарном виде, который заменяет ISAM. See section 7.1 Таблицы MyISAM
.TYPE=BDB
и данный дистрибутив MySQL не поддерживает таблицBDB
, то вместо этого будет создана таблицаMyISAM
. Другие табличные опции используются для оптимизации характеристик таблицы. Эти опции в большинстве случаев не требуют специальной установки. Данные опции работают с таблицами всех типов, если не указано иное:
При использовании таблицОпция Описание AUTO_INCREMENT Следующая величина AUTO_INCREMENT
, которую следует установить для данной таблицы (MyISAM
).AVG_ROW_LENGTH Приближенное значение средней длины строки для данной таблицы. Имеет смысл устанавливать только для обширных таблиц с записями переменной длины. CHECKSUM Следует установить в 1
, чтобы в MySQL поддерживалась проверка контрольной суммы для всех строк (это делает таблицы немного более медленными при обновлении, но позволяет легче находить поврежденные таблицы) (MyISAM
).COMMENT Комментарий для данной таблицы длиной 60 символов. MAX_ROWS Максимальное число строк, которые планируется хранить в данной таблице. MIN_ROWS Минимальное число строк, которые планируется хранить в данной таблице. PACK_KEYS Следует установить в 1
для получения меньшего индекса. Обычно это замедляет обновление и ускоряет чтение (MyISAM
,ISAM
). Установка в0
отключит уплотнение ключей. При установке вDEFAULT
(MySQL 4.0) обработчик таблиц будет уплотнять только длинные столбцыCHAR/VARCHAR
.PASSWORD Шифрует файл `.frm' с помощью пароля. Эта опция не функционирует в стандартной версии MySQL. DELAY_KEY_WRITE Установка в 1
задерживает операции обновления таблицы ключей, пока не закроется указанная таблица (MyISAM
).ROW_FORMAT Определяет, каким образом должны храниться строки. В настоящее время эта опция работает только с таблицами MyISAM
, которые поддерживают форматы строкDYNAMIC
иFIXED
. See section 7.1.2 Форматы таблицMyISAM
.MyISAM
MySQL вычисляет выражениеmax_rows * avg_row_length
, чтобы определить, насколько велика будет результирующая таблица. Если не задана ни одна из вышеупомянутых опций, то максимальный размер таблицы будет составлять 4Гб (или 2Гб если данная операционная система поддерживает только таблицы величиной до 2Гб). Это делается для того, чтобы, если нет реальной необходимости в больших файлах, ограничить размеры указателей, что позволит сделать индексы меньше и быстрее. Если опцияPACK_KEYS
не используется, то по умолчанию уплотняются только строки, но не числа. При использованииPACK_KEYS=1
числа тоже будут уплотняться. При уплотнении двоичных числовых ключей MySQL будет использовать сжатие префиксов. Это означает, что выгода от этого будет значительной только в случае большого количества одинаковых чисел. При сжатии префиксов для каждого ключа требуется один дополнительный байт, в котором указано, сколько байтов предыдущего ключа являются такими же, как и для следующего (следует учитывать, что указатель на строку хранится в порядке "старший-байт-в-начале" сразу после ключа - чтобы улучшить компрессию). Это означает, что при наличии нескольких одинаковых ключей в двух строках записи все последующие ``аналогичные'' ключи будут занимать только по 2 байта (включая указатель строки). Сравним: в обычном случае для хранения последующих ключей требуетсяразмер_хранения_ключа + размер_указателя (обычно 4)
байтов. С другой стороны, если все ключи абсолютно разные, каждый ключ будет занимать на 1 байт больше, если данный ключ не может иметь величинуNULL
(в этом случае уплотненный ключ будет храниться в том же байте, который используется для указания, что ключ равенNULL
). -
Если после команды
CREATE
указывается командаSELECT
, то MySQL создаст новые поля для всех элементов в данной командеSELECT
. Например:mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (a), KEY(b)) TYPE=MyISAM SELECT b,c FROM test2;
Эта команда создаст таблицуMyISAM
с тремя столбцамиa
,b
иc
. Отметим, что столбцы из команды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
, при этом в новые столбцы в таблицеbar
записываются величины, заданные по умолчанию. КомандаCREATE TABLE ... SELECT
не создает автоматически каких-либо индексов. Это сделано преднамеренно, чтобы команда была настолько гибкой, насколько возможно. Чтобы иметь индексы в созданной таблице, необходимо указать их перед данной командойSELECT
:mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Если возникает ошибка при копировании данных в таблицу, то они будут автоматически удалены. Чтобы обеспечить возможность использовать для восстановления таблиц журнал обновлений/двоичный журнал, в MySQL во время выполнения командыCREATE TABLE ... SELECT
не разрешены параллельные вставки. -
Воспользовавшись опцией
RAID_TYPE
, можно разбить файл данныхMyISAM
на участки с тем, чтобы преодолеть 2Гб/4Гб лимит файловой системы под управлением ОС, не поддерживающих большие файлы. Разбиение не касается файла индексов. Следует учесть, что для файловых систем, которые поддерживают большие файлы, эта опция не рекомендуется! Для получения более высокой скорости ввода-вывода можно разместить RAID-директории на различных физических дисках.RAID_TYPE
будет работать под любой операционной системой, если конфигурация MySQL выполнена с параметром--with-raid
. В настоящее время для опцииRAID_TYPE
возможен только параметрSTRIPED
(1
иRAID0
являются псевдонимами для него). Если указываетсяRAID_TYPE=STRIPED
для таблицыMyISAM
, тоMyISAM
создаст поддиректорииRAID_CHUNKS
с именами `00', `01', `02' в директории базы данных. В каждой из этих директорийMyISAM
создаст файл `table_name.MYD'. При записи данных в файл данных обработчик RAID установит соответствие первыхRAID_CHUNKSIZE*1024
байтов первому упомянутому файлу, следующихRAID_CHUNKSIZE*1024
байтов - следующему файлу и так далее. -
Опция
UNION
применяется, если необходимо использовать совокупность идентичных таблиц как одну таблицу. Она работает только с таблицамиMERGE
. See section 7.2 ТаблицыMERGE
. На данный момент для таблиц, сопоставляемых с таблицейMERGE
, необходимо иметь привилегииSELECT
,UPDATE
иDELETE
. Все сопоставляемые таблицы должны принадлежать той же базе данных, что и таблицаMERGE
. -
Для внесения данных в таблицу
MERGE
необходимо указать с помощьюINSERT_METHOD
, в какую таблицу данная строка должна быть внесена. See section 7.2 ТаблицыMERGE
. Эта опция была введена в MySQL 4.0.0. -
В созданной таблице ключ
PRIMARY
будет помещен первым, за ним все ключиUNIQUE
и затем простые ключи. Это помогает оптимизатору MySQL определять приоритеты используемых ключей, а также более быстро определять сдублированные ключиUNIQUE
. -
Используя опции
DATA DIRECTORY="каталог"
илиINDEX DIRECTORY="каталог"
, можно указать, где обработчик таблицы должен помещать свои табличные и индексные файлы. Следует учитывать, что указываемый параметр directory должен представлять собой полный путь к требуемому каталогу (а не относительный путь). Данные опции работают только для таблицMyISAM
в версии MySQL 4.0, если при этом не используется опция--skip-symlink
. See section 5.6.1.2 Использование символических ссылок для таблиц.
6.5.3.1 Молчаливые изменения определений столбцов
В некоторых случаях MySQL без уведомления изменяет определение столбца,
заданное командой CREATE TABLE
(Это может осуществляться также для
команды ALTER TABLE
):
-
Столбец
VARCHAR
с длиной меньше, чем четыре, преобразуется в столбецCHAR
. -
Если некоторый столбец в таблице имеет переменную длину, то и вся
строка в результате будет переменной длины. Следовательно, если
таблица содержит любые столбцы переменной длины (
VARCHAR
,TEXT
илиBLOB
), то все столбцыCHAR
с длиной, превышающей три символа, преобразуются в столбцыVARCHAR
. Это в любом случае не влияет на использование столбцов; в MySQL столбецVARCHAR
представляет собой просто иной способ хранения символов. MySQL выполняет данное преобразование, поскольку оно позволяет сэкономить память и сделать табличные операции более быстрыми. See section 7 Типы таблиц MySQL. -
Количество выводящихся символов столбца
TIMESTAMP
должно быть четным и находиться в диапазоне от2
до14
. При задании размера вывода, равного0
или превышающего14
, указанный размер приводится к14
. Нечетные величины размера вывода в пределах от1
до13
приводятся к следующему четному числу. -
В столбце
TIMESTAMP
не может храниться литералNULL
; установка данного столбца вNULL
устанавливает его в текущее значение даты и времени. Поскольку столбцыTIMESTAMP
ведут себя подобным образом, то атрибутыNULL
иNOT NULL
неприменимы в обычном режиме и игнорируются при их задании.DESCRIBE tbl_name
всегда сообщает, что столбцуTIMESTAMP
могут быть присвоены величиныNULL
. - MySQL приводит в соответствие определенные типы столбцов, используемые другими производителями баз данных SQL, к типам, принятым в MySQL. See section 6.2.5 Использование типов столбцов из других баз данных.
Если необходимо увидеть, использует ли MySQL иной тип столбца, чем был
первоначально задан, следует запустить команду DESCRIBE tbl_name
после
создания или изменения данной таблицы.
Некоторые другие изменения типов столбцов могут происходить при сжатии
таблицы с использованием утилиты myisampack
. See section 7.1.2.3 Характеристики сжатых таблиц.
6.5.4 Синтаксис оператора ALTER TABLE
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...] alter_specification: ADD [COLUMN] create_definition [FIRST | AFTER column_name ] или ADD [COLUMN] (create_definition, create_definition,...) или ADD INDEX [index_name] (index_col_name,...) или ADD PRIMARY KEY (index_col_name,...) или ADD UNIQUE [index_name] (index_col_name,...) или ADD FULLTEXT [index_name] (index_col_name,...) или ADD [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] или ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} или CHANGE [COLUMN] old_col_name create_definition [FIRST | AFTER column_name] или MODIFY [COLUMN] create_definition [FIRST | AFTER column_name] или DROP [COLUMN] col_name или DROP PRIMARY KEY или DROP INDEX index_name или DISABLE KEYS или ENABLE KEYS или RENAME [TO] new_tbl_name или ORDER BY col или table_options
Оператор ALTER TABLE
обеспечивает возможность изменять структуру
существующей таблицы. Например, можно добавлять или удалять столбцы,
создавать или уничтожать индексы или переименовывать столбцы либо саму
таблицу. Можно также изменять комментарий для таблицы и ее тип.
See section 6.5.3 Синтаксис оператора CREATE TABLE
.
Если оператор ALTER TABLE
используется для изменения определения типа
столбца, но DESCRIBE tbl_name
показывает, что столбец не изменился, то,
возможно, MySQL игнорирует данную модификацию по одной из причин,
описанных в разделе section 6.5.3.1 Молчаливые изменения определений столбцов. Например, при
попытке изменить столбец VARCHAR
на CHAR
MySQL будет продолжать
использовать VARCHAR
, если данная таблица содержит другие столбцы с
переменной длиной.
Оператор ALTER TABLE
во время работы создает временную копию исходной
таблицы. Требуемое изменение выполняется на копии, затем исходная таблица
удаляется, а новая переименовывается. Так делается для того, чтобы в новую
таблицу автоматически попадали все обновления кроме неудавшихся. Во время
выполнения ALTER TABLE
исходная таблица доступна для чтения другими
клиентами. Операции обновления и записи в этой таблице приостанавливаются,
пока не будет готова новая таблица.
Следует отметить, что при использовании любой другой опции для ALTER
TABLE
кроме RENAME
, MySQL всегда будет создавать временную таблицу, даже
если данные, строго говоря, и не нуждаются в копировании (например, при
изменении имени столбца). Мы планируем исправить это в будущем, однако,
поскольку ALTER TABLE
выполняется не так часто, мы (разработчики MySQL)
не считаем эту задачу первоочередной. Для таблиц MyISAM
можно увеличить
скорость воссоздания индексной части (что является наиболее медленной
частью в процессе восстановления таблицы) путем установки переменной
myisam_sort_buffer_size
достаточно большого значения.
-
Для использования оператора
ALTER TABLE
необходимы привилегииALTER
,INSERT
иCREATE
для данной таблицы. -
Опция
IGNORE
является расширением MySQL по отношению к ANSI SQL92. Она управляет работойALTER TABLE
при наличии дубликатов уникальных ключей в новой таблице. Если опцияIGNORE
не задана, то для данной копии процесс прерывается и происходит откат назад. ЕслиIGNORE
указывается, тогда для строк с дубликатами уникальных ключей только первая строка используется, а остальные удаляются. -
Можно запустить несколько выражений
ADD
,ALTER
,DROP
иCHANGE
в одной командеALTER TABLE
. Это является расширением MySQL по отношению к ANSI SQL92, где допускается только одно выражение из упомянутых в одной командеALTER TABLE
. -
Опции
CHANGE col_name
,DROP col_name
иDROP INDEX
также являются расширениями MySQL по отношению к ANSI SQL92. -
Опция
MODIFY
представляет собой расширение Oracle для командыALTER TABLE
. -
Необязательное слово
COLUMN
представляет собой ``белый шум'' и может быть опущено. -
При использовании
ALTER TABLE имя_таблицы RENAME TO новое_имя
без каких-либо других опций MySQL просто переименовывает файлы, соответствующие заданной таблице. В этом случае нет необходимости создавать временную таблицу. See section 6.5.5 Синтаксис оператораRENAME TABLE
. -
В выражении
create_definition
дляADD
иCHANGE
используется тот же синтаксис, что и дляCREATE TABLE
. Следует учитывать, что этот синтаксис включает имя столбца, а не просто его тип. See section 6.5.3 Синтаксис оператораCREATE TABLE
. -
Столбец можно переименовывать, используя выражение
CHANGE имя_столбца create_definition
. Чтобы сделать это, необходимо указать старое и новое имена столбца и его тип в настоящее время. Например, чтобы переименовать столбецINTEGER
изa
вb
, можно сделать следующее:mysql> ALTER TABLE t1 CHANGE a b INTEGER;
При изменении типа столбца, но не его имени синтаксис выраженияCHANGE
все равно требует указания обоих имен столбца, даже если они одинаковы. Например:mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
Однако начиная с версии MySQL 3.22.16a можно также использовать выражениеMODIFY
для изменения типа столбца без переименовывания его:mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
-
При использовании
CHANGE
илиMODIFY
для того, чтобы уменьшить длину столбца, по части которого построен индекс (например, индекс по первым 10 символам столбцаVARCHAR
), нельзя сделать столбец короче, чем число проиндексированных символов. -
При изменении типа столбца с использованием
CHANGE
илиMODIFY
MySQL пытается преобразовать данные в новый тип как можно корректнее. -
В версии MySQL 3.22 и более поздних можно использовать
FIRST
илиADD ... AFTER имя_столбца
для добавления столбца на заданную позицию внутри табличной строки. По умолчанию столбец добавляется в конце. Начиная с версии MySQL 4.0.1, можно также использовать ключевые словаFIRST
иAFTER
в опцияхCHANGE
илиMODIFY
. -
Опция
ALTER COLUMN
задает для столбца новое значение по умолчанию или удаляет старое. Если старое значение по умолчанию удаляется и данный столбец может принимать значениеNULL
, то новое значение по умолчанию будетNULL
. Если столбец не может бытьNULL
, то MySQL назначает значение по умолчанию так, как описано в разделе section 6.5.3 Синтаксис оператораCREATE TABLE
. -
Опция
DROP INDEX
удаляет индекс. Это является расширением MySQL по отношению к ANSI SQL92. See section 6.5.8 Синтаксис оператораDROP INDEX
. - Если столбцы удаляются из таблицы, то эти столбцы удаляются также и из любого индекса, в который они входят как часть. Если все столбцы, составляющие индекс, удаляются, то данный индекс также удаляется.
-
Если таблица содержит только один столбец, то этот столбец не может
быть удален. Вместо этого можно удалить данную таблицу, используя
команду
DROP TABLE
. -
Опция
DROP PRIMARY KEY
удаляет первичный индекс. Если такого индекса в данной таблице не существует, то удаляется первый индексUNIQUE
в этой таблице. (MySQL отмечает первый уникальный ключUNIQUE
как первичный ключPRIMARY KEY
, если никакой другой первичный ключPRIMARY KEY
не был явно указан). При добавленииUNIQUE INDEX
илиPRIMARY KEY
в таблицу они хранятся перед остальными неуникальными ключами, чтобы можно было определить дублирующиеся ключи как можно раньше. -
Опция
ORDER BY
позволяет создавать новую таблицу со строками, размещенными в заданном порядке. Следует учитывать, что созданная таблица не будет сохранять этот порядок строк после операций вставки и удаления. В некоторых случаях такая возможность может облегчить операцию сортировки в MySQL, если таблица имеет такое расположение столбцов, которое вы хотели бы иметь в дальнейшем. Эта опция в основном полезна, если заранее известен определенный порядок, в котором преимущественно будут запрашиваться строки. Использование данной опции после значительных преобразований таблицы дает возможность получить более высокую производительность. -
При использовании команды
ALTER TABLE
для таблицMyISAM
все неуникальные индексы создаются в отдельном пакете (подобноREPAIR
). Благодаря этому командаALTER TABLE
при наличии нескольких индексов будет работать быстрее. -
Начиная с MySQL 4.0, вышеуказанная возможность может быть
активизирована явным образом. Команда
ALTER TABLE ... DISABLE KEYS
блокирует в MySQL обновление неуникальных индексов для таблицMyISAM
. После этого можно применить командуALTER TABLE ... ENABLE KEYS
для воссоздания недостающих индексов. Так как MySQL делает это с помощью специального алгоритма, который намного быстрее в сравнении со вставкой ключей один за другим, блокировка ключей может дать существенное ускорение на больших массивах вставок. -
Применяя функцию C API
mysql_info()
, можно определить, сколько записей было скопировано, а также (при использованииIGNORE
) - сколько записей было удалено из-за дублирования значений уникальных ключей. -
Выражения
FOREIGN KEY
,CHECK
иREFERENCES
фактически ничего не делают во всех типах таблиц, кроме InnoDB. InnoDB поддерживаетADD CONSTRAINT FOREIGN KEY (...) REFERENCES ... (...)
. Заметьте, что InnoDB не допускает указанияindex_name
. See section 7.5 ТаблицыInnoDB
. Поддержка синтаксиса FOREIGH KEY введена только из соображений совместимости, чтобы облегчить перенос кода с других серверов SQL и запуск приложений, создающих таблицы со ссылками. See section 1.9.4 Отличия MySQL от ANSI SQL92.
Ниже приводятся примеры, показывающие некоторые случаи употребления
команды ALTER TABLE
. Пример начинается с таблицы t1
, которая создается
следующим образом:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
Для того чтобы переименовать таблицу из t1
в t2
:
mysql> ALTER TABLE t1 RENAME t2;
Для того чтобы изменить тип столбца с INTEGER
на TINYINT NOT NULL
(оставляя имя прежним) и изменить тип столбца b
с CHAR(10)
на CHAR(20)
с
переименованием его с b
на c
:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
Для того чтобы добавить новый столбец TIMESTAMP
с именем d
:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
Для того чтобы добавить индекс к столбцу d
и сделать столбец a первичным
ключом:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
Для того чтобы удалить столбец c
:
mysql> ALTER TABLE t2 DROP COLUMN c;
Для того чтобы добавить новый числовой столбец AUTO_INCREMENT
с именем c
:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX (c);
Заметьте, что столбец c
индексируется, так как столбцы AUTO_INCREMENT
должны быть индексированы, кроме того, столбец c
объявляется как NOT
NULL
, поскольку индексированные столбцы не могут быть NULL
.
При добавлении столбца AUTO_INCREMENT
значения этого столбца автоматически
заполняются последовательными номерами (при добавлении записей). Первый
номер последовательности можно установить путем выполнения команды SET
INSERT_ID=#
перед ALTER TABLE
или использования табличной опции
AUTO_INCREMENT = #
. See section 5.5.6 Синтаксис команды SET
.
Если столбец AUTO_INCREMENT
для таблиц MyISAM
, не изменяется, то номер
последовательности остается прежним. При удалении столбца AUTO_INCREMENT
и
последующем добавлении другого столбца AUTO_INCREMENT
номера будут
начинаться снова с 1
.
See section A.6.1 Проблемы с ALTER TABLE
.
6.5.5 Синтаксис оператора RENAME TABLE
RENAME TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2,...]
Операция переименования должна осуществляться как атомарная, т.е. при выполнении переименования никакому другому потоку не разрешается доступ к указанным таблицам. Благодаря этому возможно замещение таблицы пустой таблицей:
CREATE TABLE new_table (...); RENAME TABLE old_table TO backup_table, new_table TO old_table;
Переименование производится слева направо. Таким образом, для обмена именами между двумя таблицами необходимо выполнить следующие действия:
RENAME TABLE old_table TO backup_table, new_table TO old_table, backup_table TO new_table;
Для двух баз данных, находящихся на одном и том же диске, можно также осуществлять обмен именами:
RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
При выполнении команды RENAME
не должны иметь место заблокированные
таблицы или активные транзакции. Необходимо также иметь привилегии ALTER
и
DROP
для исходной таблицы и привилегии CREATE
и INSERT
- для новой.
Если MySQL сталкивается с какой-либо ошибкой при переименовании нескольких таблиц, то произойдет обратное переименование для всех переименованных таблиц, чтобы вернуть все в исходное состояние.
Оператор RENAME TABLE
был добавлен в MySQL 3.23.23.
6.5.6 Синтаксис оператора DROP TABLE
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name,...] [RESTRICT | CASCADE]
Оператор DROP TABLE
удаляет одну или несколько таблиц. Все табличные
данные и определения удаляются, так что будьте внимательны при работе с
этой командой!
В версии MySQL 3.22 и более поздних можно использовать ключевые слова IF
EXISTS
, чтобы предупредить ошибку, если указанные таблицы не существуют.
В 4.1 будет получено замечание (NOTE
) для всех несуществующих таблиц при
использовании IF EXISTS
. See section 4.5.6.9 SHOW WARNINGS | ERRORS
.
Опции RESTRICT
и CASCADE
позволяют упростить перенос программы. В данный
момент они не задействованы.
Примечание: DROP TABLE
автоматически принимает текущую активную
транзакцию (за исключением случаев, когда вы используетее 4.1 и указано
ключевое слово TEMPORARY
).
Опция TEMPORARY
игнорируется в 4.0. В 4.1 эта опция работает следующим образом:
- Только уничтожает временные таблицы.
- Не закрывает открытую транзакцию.
- Права доступа не проверяются.
Использование слова TEMPORARY
- это хороший способ удостовериться что вы случайно
не уничтожите настоящую таблицу.
6.5.7 Синтаксис оператора CREATE INDEX
CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tbl_name (col_name[(length)],... )
Команда CREATE INDEX
в версиях MySQL до 3.22 не выполняет никаких
действий. В версии 3.22 и более поздних CREATE INDEX
соответствует
команде ALTER TABLE
в части создания индексов. See section 6.5.4 Синтаксис оператора ALTER TABLE
.
Обычно все индексы создаются в таблице во время создания самой таблицы
командой CREATE TABLE
. See section 6.5.3 Синтаксис оператора CREATE TABLE
. CREATE INDEX
дает
возможность добавить индексы к существующим таблицам.
Список столбцов в форме (col1,col2,...)
создает индекс для нескольких
столбцов. Величины индексов формируются путем конкатенации величин
указанных столбцов.
Для столбцов типов CHAR
и VARCHAR
с помощью параметра
col_name(length)
могут создаваться индексы, для которых используется только
часть столбца (для столбцов BLOB
и TEXT
нужно указывать длину). Команда,
приведенная ниже, создает индекс, используя первые 10 символов столбца
name:
mysql> CREATE INDEX part_of_name ON customer (name(10));
Поскольку большинство имен обычно имеют отличия друг от друга в первых 10
символах, данный индекс не должен быть намного медленнее, чем созданный из
столбца name целиком. Кроме того, используя неполные столбцы для индексов,
можно сделать файл индексов намного меньше, а это позволяет сэкономить
место на диске и к тому же повысить скорость операций INSERT
!
Следует учитывать, что в версии MySQL 3.23.2 и более поздних для таблиц
типа MyISAM
можно добавлять индекс только для столбцов, которые могут
принимать величины NULL
или для столбцов BLOB/TEXT
.
Чтобы получить более подробную информацию о том, как MySQL
использует
индексы, See section 5.4.3 Использование индексов в MySQL.
С помощью опции FULLTEXT
можно индексировать только столбцы VARCHAR
и TEXT
и только в таблицах MyISAM
. Эта возможность доступна только в версии MySQL
3.23.23 и выше. See section 6.8 Полнотекстовый поиск в MySQL.
6.5.8 Синтаксис оператора DROP INDEX
DROP INDEX index_name ON tbl_name
Оператор DROP INDEX
удаляет индексы, указанные в index_name
из таблицы
tbl_name
. DROP INDEX
не выполняет никаких действий в версиях MySQL до
3.22. В версиях 3.22 и более поздних DROP INDEX
соответствует команде
ALTER TABLE
в части удаления индексов. See section 6.5.4 Синтаксис оператора ALTER TABLE
.
6.6 Основные команды пользовательских программ MySQL
6.6.1 Синтаксис команды USE
USE db_name
Команда USE db_name
предписывает MySQL использовать базу данных с именем
db_name
в последующих запросах по умолчанию. Указанная база данных
остается в этом состоянии до конца данного сеанса или пока не будет выдана
еще одна команда USE
:
mysql> USE db1; mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable mysql> USE db2; mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable
То обстоятельство, что отдельная база данных посредством команды USE
выбирается как используемая в текущий момент по умолчанию, не является
препятствием для доступа к таблицам других баз данных. Следующий пример
иллюстрирует получение доступа к таблице author
базы данных db1
и к
таблице editor
базы данных db2
:
mysql> USE db1; mysql> SELECT author_name,editor_name FROM author,db2.editor WHERE author.editor_id = db2.editor.editor_id;
Наличие команды USE
обеспечивает совместимость с Sybase.
6.6.2 Синтаксис команды DESCRIBE
(Получение информации о столбцах)
{DESCRIBE | DESC} tbl_name [col_name | wild]
Команда DESCRIBE
представляет собой сокращенный вариант команды SHOW
COLUMNS FROM
. See section 4.5.6.1 Получение информации по базам данных, таблицам, столбцам и индексам.
Команда DESCRIBE
предоставляет информацию о столбцах таблицы. Параметр
col_name
может содержать имя столбца или строки, включающей такие
групповые символы SQL, как `%' и `_' (шаблонные символы, позволяющие
получить информацию о всех подходящих столбцах). В кавычки брать строку не нужно.
Следует отметить, что типы столбцов в полученном описании могут отличаться
от ожидаемых, первоначально заданных командой CREATE TABLE
при создании
таблицы, поскольку MySQL иногда изменяет типы столбцов. See section 6.5.3.1 Молчаливые изменения определений столбцов.
Данная команда обеспечивает совместимость с Oracle.
Команда SHOW
предоставляет аналогичную информацию.
See section 4.5.6 Синтаксис команды SHOW
.
6.7 Команды управления транзакциями и блокировками в MySQL
6.7.1 Синтаксис команд BEGIN/COMMIT/ROLLBACK
По умолчанию MySQL работает в режиме autocommit
. Это означает, что при
выполнении обновления данных MySQL будет сразу записывать обновленные
данные на диск.
При использовании таблиц, поддерживающих транзакции (таких как InnoDB
,
BDB
), в MySQL можно отключить режим autocommit при помощи следующей
команды:
SET AUTOCOMMIT=0
После этого необходимо применить команду COMMIT
для записи изменений на
диск или команду ROLLBACK
, которая позволяет игнорировать изменения,
произведенные с начала данной транзакции.
Если необходимо переключиться из режима AUTOCOMMIT
только для выполнения
одной последовательности команд, то для этого можно использовать команду START TRANSACTION
или BEGIN
или BEGIN WORK
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summmary=@A WHERE type=1; COMMIT;
START TRANSACTION
была добавлена в MySQL 4.0.11. Это - рекомендованный
способ открыть транзакцию, в соответствии с синтаксисом ANSI SQL.
Отметим, что при использовании таблиц, не поддерживающих транзакции,
изменения будут записаны сразу же, независимо от статуса режима
autocommit
.
При выполнении команды ROLLBACK
после обновления таблицы, не
поддерживающей транзакции, пользователь получит ошибку
(ER_WARNING_NOT_COMPLETE_ROLLBACK
) в виде предупреждения. Все таблицы,
поддерживающие транзакции, будут перезаписаны, но ни одна таблица, не
поддерживающая транзакции, не будет изменена.
При выполнении команд START TRANSACTION
или SET AUTOCOMMIT=0
необходимо использовать
двоичный журнал MySQL для резервных копий вместо более старого
журнала записи изменений. Транзакции сохраняются в двоичном системном
журнале как одна порция данных (перед операцией COMMIT
), чтобы
гарантировать, что транзакции, по которым происходит откат, не
записываются. See section 4.9.4 Бинарный журнал обновлений.
Следующие команды автоматически завершают транзакцию (как если бы перед
выполнением данной команды была сделана операция COMMIT
):
Команда | Команда | Команда |
ALTER TABLE | BEGIN | CREATE INDEX
|
DROP DATABASE | DROP TABLE | RENAME TABLE
|
TRUNCATE |
Уровень изоляции для транзакций можно изменить с помощью команды SET
TRANSACTION ISOLATION LEVEL ...
. See section 6.7.3 Синтаксис команды SET TRANSACTION
.
6.7.2 Синтаксис команд LOCK TABLES/UNLOCK TABLES
LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...] ... UNLOCK TABLES
Команда LOCK TABLES
блокирует указанные в ней таблицы для данного потока.
Команда UNLOCK TABLES
снимает любые блокировки, удерживаемые данным
потоком. Все таблицы, заблокированные текущим потоком, автоматически
разблокируются при появлении в потоке иной команды LOCK TABLES
или при
прекращении соединения с сервером.
Чтобы использовать команду LOCK TABLES
в MySQL 4.0.2, необходимо иметь
глобальные привилегии LOCK TABLES
и SELECT
для заданных таблиц. В MySQL
3.23 для этого необходимы привилегии SELECT
, INSERT
, DELETE
и UPDATE
для
рассматриваемых таблиц.
Основные преимущества использования команды LOCK TABLES
состоят в том,
что она позволяет осуществлять эмуляцию транзакций или получить более
высокую скорость при обновлении таблиц. Ниже это разъясняется более
подробно.
Если в потоке возникает блокировка операции READ
для некоторой таблицы, то
только этот поток (и все другие потоки) могут читать из данной таблицы.
Если для некоторой таблицы в потоке существует блокировка WRITE
, тогда
только поток, содержащий блокировку, может осуществлять операции чтения (READ
) и
записи (WRITE
) на данной таблице. Остальные потоки блокируются.
Различие между READ LOCAL
и READ
состоит в том, что READ LOCAL
позволяет
выполнять неконфликтующие команды INSERT
во время существования
блокировки. Однако эту команду нельзя использовать для работы с файлами
базы данных вне сервера MySQL во время данной блокировки.
При использовании команды LOCK TABLES
необходимо блокировать все таблицы,
которые предполагается использовать в последующих запросах, употребляя при
этом те же самые псевдонимы, которые будут в запросах! Если таблица
упоминается в запросе несколько раз (с псевдонимами), необходимо
заблокировать каждый псевдоним!
Блокировка WRITE
обычно имеет более высокий приоритет, чем блокировка READ
,
чтобы гарантировать, что изменения обрабатываются так быстро, как
возможно. Это означает, что если один поток получает блокировку READ
и
затем иной поток запрашивает блокировку WRITE
, последующие запросы на
блокировку READ
будут ожидать, пока поток WRITE
не получит блокировку и не
снимет ее. Можно использовать блокировки LOW_PRIORITY WRITE
, позволяющие
другим потокам получать блокировки READ
в то время, как основной поток
находится в состоянии ожидания блокировки WRITE
. Блокировки LOW_PRIORITY
WRITE
могут быть использованы только если есть уверенность, что в конечном
итоге будет период времени, когда ни один из потоков не будет иметь
блокировки READ
.
Команда LOCK TABLES
работает следующим образом:
- Сортирует все блокируемые таблицы в порядке, который задан внутренним образом, т.е. ``зашит'' (с точки зрения пользователя этот порядок не задан).
-
Блокировка
WRITE
ставится перед блокировкойREAD
, если таблицы блокируются с блокировкамиREAD
иWRITE
. - Блокирует одну таблицу единовременно, пока поток не получит все блокировки.
Описанный порядок действий гарантирует, что блокирование таблицы не создает тупиковой ситуации. Однако есть и другие вещи, о которых необходимо отдавать себе отчет при работе по описанной схеме:
Использование для таблицы блокировки LOW_PRIORITY WRITE
всего лишь
означает, что MySQL будет выполнять данную конкретную блокировку, пока не
появится поток, запрашивающий блокировку READ
. Если поток получил
блокировку WRITE
и находится в ожидании блокировки следующей таблицы из
списка блокируемых таблиц, то все остальные потоки будут ожидать, пока
блокировка WRITE
не будет снята. Если это представляет серьезную проблему
для вашего приложения, то следует подумать о преобразовании имеющихся
таблиц в таблицы иного вида, поддерживающие транзакции.
Поток, ожидающий блокировку таблицы, можно безопасно уничтожить с помощью
команды KILL
. See section 4.5.5 Синтаксис команды KILL
.
Учтите, что нельзя блокировать любые таблицы, используемые совместно с
оператором INSERT DELAYED
, поскольку в этом случае команда INSERT
выполняется как отдельный поток.
Обычно нет необходимости блокировать таблицы, поскольку все единичные
команды UPDATE
являются неделимыми; никакой другой поток не может
взаимодействовать с какой-либо SQL-командой, выполняемой в данное время.
Однако в некоторых случаях предпочтительно тем или иным образом
осуществлять блокировку таблиц:
-
Если предполагается выполнить большое количество операций на группе
взаимосвязанных таблиц, то быстрее всего это сделать, блокировав
таблицы, которые вы собираетесь использовать. Конечно, это имеет свою
обратную сторону, поскольку никакой другой поток управления не может
обновить таблицу с блокировкой
READ
или прочитать таблицу с блокировкойWRITE
. При блокировкеLOCK TABLES
операции выполняются быстрее потому, что в этом случае MySQL не производит запись на диск содержимого кэша ключей для заблокированных таблиц, пока не будет вызвана командаUNLOCK TABLES
(обычно кэш ключей записывается на диск после каждой SQL-команды). ПрименениеLOCK TABLES
увеличивает скорость записи/обновления/удаления в таблицах типаMyISAM
. -
Если вы используете таблицы, не поддерживающие транзакций, то при использовании
программы обработки таблиц необходимо применять команду
LOCK TABLES
для гарантии, что никакой другой поток не вклинился между операциямиSELECT
иUPDATE
. Ниже показан пример, требующий использованияLOCK TABLES
для успешного выполнения операций:mysql> LOCK TABLES trans READ, customer WRITE; mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id; mysql> UPDATE customer SET total_value=sum_from_previous_statement WHERE customer_id=some_id; mysql> UNLOCK TABLES;
Без использованияLOCK TABLES
существует вероятность того, что какой-либо иной поток управления может вставить новую строку в таблицуtrans
между выполнением операцийSELECT
иUPDATE
.
Используя пошаговые обновления (UPDATE customer SET
value=value+new_value
) или функцию LAST_INSERT_ID()
, применения команды
LOCK TABLES
во многих случаях можно избежать.
Некоторые проблемы можно также решить путем применения блокирующих функций
на уровне пользователя GET_LOCK()
и RELEASE_LOCK()
. Эти блоки хранятся в
хэш-таблице на сервере и, чтобы обеспечить высокую скорость, реализованы в
виде pthread_mutex_lock()
и pthread_mutex_unlock()
.
See section 6.3.6.2 Разные функции.
Чтобы получить дополнительную информацию о механизме блокировки, обращайтесь к разделу section 5.3.1 Как MySQL блокирует таблицы.
Можно блокировать все таблицы во всех базах данных блокировкой READ
с
помощью команды FLUSH TABLES WITH READ LOCK
. See section 4.5.3 Синтаксис команды FLUSH
.
Это очень удобно для получения резервной копии файловой системы, подобной
Veritas, при работе в которой могут потребоваться заблаговременные копии
памяти.
Примечание: Команда LOCK TABLES
не сохраняет транзакции и автоматически
фиксирует все активные транзакции перед попыткой блокировать таблицы.
6.7.3 Синтаксис команды SET TRANSACTION
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Устанавливает уровень изоляции транзакций.
По умолчанию уровень изоляции устанавливается для последующей (не
начальной) транзакции. При использовании ключевого слова GLOBAL
данная
команда устанавливает уровень изоляции по умолчанию глобально для всех
новых соединений, созданных от этого момента. Однако для того чтобы
выполнить данную команду, необходима привилегия SUPER
. При использовании
ключевого слова SESSION
устанавливается уровень изоляции по умолчанию для
всех будущих транзакций, выполняемых в текущем соединении.
Установить глобальный уровень изоляции по умолчанию для утилиты mysqld
можно с помощью опции --transaction-isolation=...
. See section 4.1.1 Параметры командной строки mysqld
.
6.8 Полнотекстовый поиск в MySQL
С 3.23.23 MySQL поддерживает
полнотекстовый поиск и индексацию. Полнотекстовые индексы в MySQL обозначаются
как индексы типа FULLTEXT
. Эти индексы могут быть созданы в таблицах
MyISAM в столбцах VARCHAR
и TEXT
во время создания таблицы
командой CREATE TABLE
или добавлены позже с помощью команд ALTER
TABLE
или CREATE INDEX
. Загрузка больших массивов данных в таблицу
будет происходить намного быстрее, если таблица не содержит индекс
FULLTEXT
, который затем создается командой ALTER TABLE
(или
CREATE INDEX
). Загрузка данных в таблицу, уже имеющую индекс
FULLTEXT
, будет более медленной.
Полнотекстовый поиск выполняется с помощью функции MATCH()
.
mysql> CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) ); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO articles VALUES -> (NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'), -> (NULL,'How To Use MySQL Efficiently', 'After you went through a ...'), -> (NULL,'Optimising MySQL','In this tutorial we will show ...'), -> (NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), -> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'), -> (NULL,'MySQL Security', 'When configured properly, MySQL ...'); Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database'); +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 5 | MySQL vs. YourSQL | In the following database comparison ... | | 1 | MySQL Tutorial | DBMS stands for DataBase ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec)
Функция MATCH()
выполняет поиск в естественном языке, сравнивая строку с
содержимым текста (совокупность одного или более столбцов, включенных в
индекс FULLTEXT
). Строка поиска задается как аргумент в выражении
AGAINST()
. Поиск выполняется без учета регистра символов. Для каждой
строки столбца в заданной таблице команда MATCH()
возвращает величину
релевантности, т.е. степень сходства между строкой поиска и текстом,
содержащимся в данной строке указанного в списке оператора MATCH()
столбца.
Когда команда MATCH()
используется в выражении WHERE
(см. пример выше),
возвращенные строки столбцов автоматически сортируются, начиная с наиболее
релевантных. Величина релевантности представляет собой неотрицательное
число с плавающей точкой. Релевантность вычисляется на основе количества
слов в данной строке столбца, количества уникальных слов в этой строке,
общего количества слов в тексте и числа документов (строк), содержащих
отдельное слово.
Поиск возможен также в логическом режиме, это объясняется ниже в данном разделе.
Предыдущий пример представляет собой общую иллюстрацию использования
функции MATCH()
. Строки возвращаются в порядке уменьшения релевантности.
В следующем примере показано, как извлекать величины релевантности в явном
виде. В случае отсутствия выражений WHERE
и ORDER BY
возвращаемые строки
не упорядочиваются.
mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles; +----+-----------------------------------------+ | id | MATCH (title,body) AGAINST ('Tutorial') | +----+-----------------------------------------+ | 1 | 0.64840710366884 | | 2 | 0 | | 3 | 0.66266459031789 | | 4 | 0 | | 5 | 0 | | 6 | 0 | +----+-----------------------------------------+ 6 rows in set (0.00 sec)
Следующий пример - более сложный. Запрос возвращает значение релевантности
и, кроме того, сортирует строки в порядке убывания релевантности. Чтобы
получить такой результат, необходимо указать MATCH()
дважды. Это не
приведет к дополнительным издержкам, так как оптимизатор MySQL учтет, что
эти два вызова MATCH()
идентичны, и запустит код полнотекстового поиска
только однажды.
mysql> SELECT id, body, MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root') AS score -> FROM articles WHERE MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root'); +----+-------------------------------------+-----------------+ | id | body | score | +----+-------------------------------------+-----------------+ | 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 | | 6 | When configured properly, MySQL ... | 1.31140957288 | +----+-------------------------------------+-----------------+ 2 rows in set (0.00 sec)
Для разбивки текста на слова MySQL использует очень простой синтаксический анализатор. ``Словом'' является любая последовательность символов, состоящая из букв, чисел, знаков `'' и `_'. Любое ``слово'', присутствующее в стоп-списке (stopword) или просто слишком короткое (3 символа или меньше), игнорируется.
Каждое правильное слово в наборе проверяемых текстов и в данном запросе оценивается в соответствии с его важностью в этом запросе или наборе текстов. Таким образом, слово, присутствующее во многих документах, будет иметь меньший вес (и даже, возможно, нулевой), как имеющее более низкое смысловое значение в данном конкретном наборе текстов. С другой стороны, редко встречающееся слово получит более высокий вес. Затем полученные значения весов слов объединяются для вычисления релевантности данной строки столбца.
Описанная техника подсчета лучше всего работает для больших наборов текстов (фактически она именно для этого тщательно настраивалась). Для очень малых таблиц распределение слов не отражает адекватно их смысловое значение, и данная модель иногда может выдавать некорректные результаты.
mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL'); Empty set (0.00 sec)
Поиск по слову ``MySQL'' в предыдущем примере не приводит к каким-либо результатам, так как это слово присутствует более чем в половине строк. По существу, данное слово целесообразно трактовать как стоп-слово (т.е. слово с нулевой смысловой ценностью). Это наиболее приемлемое решение - запрос на естественном языке не должен возвращать каждую вторую строку из таблицы размером 1Гб.
Маловероятно, что слово, встречающееся в половине строк таблицы, определяет местонахождение релевантных документов. На самом деле, наиболее вероятно, что будет найдено много не относящихся к делу документов. Общеизвестно, что такое случается слишком часто при попытке найти что-либо в Интернет с помощью поисковых машин. Именно на этом основании подобным строкам должно быть назначено низкое смысловое значение в данном конкретном наборе данных.
В MySQL 4.0.1 возможен полнотекстовый поиск также и в логическом режиме с
использованием модификатора IN BOOLEAN MODE
.
mysql> SELECT * FROM articles WHERE MATCH (title,body) -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +----+------------------------------+-------------------------------------+ | id | title | body | +----+------------------------------+-------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 2 | How To Use MySQL Efficiently | After you went through a ... | | 3 | Optimising MySQL | In this tutorial we will show ... | | 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | | 6 | MySQL Security | When configured properly, MySQL ... | +----+------------------------------+-------------------------------------+
Данный запрос вывел все строки, содержащие слово ``MySQL'' (заметьте,
50-процентная пороговая величина здесь не используется), но эти строки не
содержат слова ``YourSQL''. Следует отметить, что логический режим поиска
не сортирует автоматически строки в порядке уменьшения релевантности. Это
видно по результату предыдущего запроса, где строка с наиболее высокой
релевантностью (содержащая слово ``MySQL'' дважды) помещена последней, а
не первой. Логический режим полнотекстового поиска может работать даже без
индекса FULLTEXT
, хотя и очень медленно.
В логическом режиме полнотекстового поиска поддерживаются следующие операторы:
+
- Предшествующий слову знак ``плюс'' показывает, что это слово должно присутствовать в каждой возвращенной строке.
-
- Предшествующий слову знак ``минус'' означает, что это слово не должно присутствовать в какой-либо возвращенной строке.
-
По умолчанию (если ни плюс, ни минус не указаны) данное слово является не
обязательным, но содержащие его строки будут оцениваться более высоко. Это
имитирует поведение команды
MATCH() ... AGAINST()
без модификатораIN BOOLEAN MODE
. < >
-
Эти два оператора используются для того, чтобы изменить вклад слова в
величину релевантности, которое приписывается строке. Оператор
<
уменьшает этот вклад, а оператор>
- увеличивает его. См. пример ниже. ( )
- Круглые скобки группируют слова в подвыражения.
~
- Предшествующий слову знак ``тильда'' воздействует как оператор отрицания, обуславливая негативный вклад данного слова в релевантность строки. Им отмечают нежелательные слова. Строка, содержащая такое слово, будет оценена ниже других, но не будет исключена совершенно, как в случае оператора - ``минус''.
*
- Звездочка является оператором усечения. В отличие от остальных операторов, она должна добавляться в конце слова, а не в начале.
"
- Фраза, заключенная в двойные кавычки, соответствует только строкам, содержащим эту фразу, написанную буквально.
Ниже приведен ряд примеров:
apple banana
- находит строки, содержащие по меньшей мере одно из этих слов.
+apple +juice
- ... оба слова.
+apple macintosh
- ... слово ``apple'', но ранг строки выше, если она также содержит слово ``macintosh''.
+apple -macintosh
- ... слово ``apple'', но не ``macintosh''.
+apple +(>pie <strudel)
- ... ``apple'' и ``pie'', или ``apple'' и ``strudel'' (в любом порядке), но ранг ``apple pie'' выше, чем ``apple strudel''.
apple*
- ... ``apple'', ``apples'', ``applesauce'', и ``applet''.
"some words"
- ... ``some words of wisdom'', но не ``some noise words''.
6.8.1 Ограничения для полнотекстового поиска
-
Все параметры функции
MATCH()
должны быть столбцами одной и той же таблицы, т.е. частью одного и того же индексаFULLTEXT
, за исключением работыMATCH()
в режимеIN BOOLEAN MODE
. -
Список столбцов в команде
MATCH()
должен точно соответствовать списку столбцов в определении индексаFULLTEXT
для этой таблицы, за исключением работы данной функцииMATCH()
в режимеIN BOOLEAN MODE
. -
Аргумент в выражении
AGAINST()
должен быть неизменяемой строкой.
6.8.2 Тонкая настройка полнотекстового поиска в MySQL
К сожалению, полнотекстовый поиск имеет еще мало настраиваемых пользователем параметров, хотя для последующих модификаций добавление некоторого их количества является очень важной задачей (TODO). Однако при наличии исходного дистрибутива MySQL (see section 2.3 Установка исходного дистрибутива MySQL) имеется больше возможностей управлять полнотекстовым поиском.
Следует отметить, что полнотекстовый поиск был тщательно настроен так, чтобы обеспечить наилучшую эффективность выполнения данной операции. Если изменить установленный по умолчанию режим работы, то в большинстве случаев результаты поиска станут только хуже. Поэтому не вносите какие-либо правки в код MySQL, если не знаете наверняка, что вы делаете!
-
Минимальная длина подлежащих индексации слов определяется в MySQL
переменной
-
Список стоп-слов может быть загружен с файла, указанного в переменной
ft_stopword_file
. See section 4.5.6.4SHOW VARIABLES
. После модификации стоп-листа перестройте ваши полнотекствые индексы. (Эта переменная введена в MySQL 4.0.10) -
50-процентный порог определяется выбранной конкретной схемой
присваивания весовых коэффициентов. Чтобы отменить ее, измените
следующую строку в `myisam/ftdefs.h':
#define GWS_IN_USE GWS_PROB
на:#define GWS_IN_USE GWS_FREQ
Затем перекомпилируйте MySQL. Создавать заново индексы в этом случае нет необходимости. Примечание: таким образом вы существенно ухудшите способность MySQL продуцировать адекватные величины релевантности для функцииMATCH()
. Если действительно необходим поиск для таких общеупотребительных слов, то было бы лучше использовать вместо этого поиск в режимеIN BOOLEAN MODE
, при котором не предусмотрен 50-процентный порог. -
Иногда отладчик поисковой машины желает изменить операторы,
используемые для логического поиска по полному тексту. Эти операторы
определяются переменной
ft_boolean_syntax
. See section 4.5.6.4SHOW VARIABLES
. Однако эта переменная доступна только для чтения, ее значение устанавливается в `myisam/ft_static.c'.
ft_min_word_len
(see section 4.5.6.4 SHOW VARIABLES
). Установите
желаемую величину этой переменной и создайте заново индексы FULLTEXT
(эта переменная доступна только в версии MySQL 4.0).
Наиболее простым способом перестроить полнотекстовый индекс в тех случаях, когда это нужно - это вот такая команда:
mysql> REPAIR TABLE tbl_name QUICK;
6.8.3 Предстоящие доработки по полнотекстовому поиску
-
Сделать все операции с индексом
FULLTEXT
более быстрыми. - Операторы схожести
- Поддержка для слов, тождественных индексам, - чтобы словами могли быть любые строки, которые пользователь пожелает трактовать как слова, например "C++", "AS/400", "TCP/IP" и т.д.
-
Поддержка полнотекстового поиска в таблицах типа
MERGE
. - Поддержка многобайтовых наборов символов.
- Сделать список стоп-слов (``stopword'') зависящим от языка данных.
- Стемминг (в зависимости от языка данных, конечно).
- Обобщенный синтаксический пре-анализатор с определяемым пользователем функциониями (UDF).
-
Сделать данную модель поиска более гибкой (путем добавления ряда
регулируемых параметров к
FULLTEXT
вCREATE/ALTER TABLE
).
6.9 Кэш запросов в MySQL
Начиная с версии 4.0.1 сервер MySQL снабжен кэшем запросов. В процессе
работы кэш запросов хранит текст запроса SELECT
вместе с соответствующим
результатом, который посылался клиенту. При получении другого идентичного
запроса сервер извлечет результаты из кэша запросов, а не
анализировать и выполнять снова тот же самый запрос.
Кэш запросов особенно полезен в средах, где (некоторые) таблицы не обновляются слишком часто и присутствует много идентичных запросов. Эта ситуация типична для многих веб-серверов с обширным активным информационным наполнением.
Ниже приведены некоторые данные функционирования для кэша запросов (они получены во время работы тестового комплекта MySQL под Linux Alpha 2x500 МГц с 2Гб ОЗУ и 64-мегабайтным кэшем запросов):
- Если все производимые запросы являются простыми (такими как выбор строки из таблицы с одной строкой), но различаются настолько, что не могут быть кэшированы, непроизводительные затраты при активном состоянии кэша запросов составляют 13%. Это можно было бы рассматривать как сценарий наиболее неблагоприятного варианта. Однако в реальной жизни запросы более сложны, чем приведенный простой пример, так что непроизводительные затраты обычно значительно ниже.
- Поиск строки в таблице с одной строкой происходит на 238% быстрее. Можно рассматривать эту величину, как близкую к минимальному увеличению быстродействия, ожидаемого при кэшировании запроса.
-
Если вы хотите запретить кеш запросов, установите переменную
query_cache_size
в0
. Запрещение кеша запросов не создает лишних перегрузок для сервера. Вы можете целиком исключить код кеша запросов из сервера путем указания при компиляции опции--without-query-cache
вconfigure
.
6.9.1 Как работает кэширование запросов
Перед синтаксическим анализом запросы сравниваются, поэтому запросы
SELECT * FROM tbl_name
и
Select * from tbl_name
для кэша запросов рассматриваются как различные, поскольку они должны быть абсолютно одинаковыми (байт в байт), чтобы рассматриваться как идентичные. Помимо этого, запрос может трактоваться как отличающийся, если, например, какой-либо клиент использует протокол соединения нового формата или иной набор символов, чем другой клиент.
Запросы, использующие различные базы данных, различные версии протоколов или различные наборы символов по умолчанию, рассматриваются как различные и кэшируются раздельно.
Рассматриваемый кэш надежно работает для запросов вида SELECT CALC_ROWS
...
и SELECT FOUND_ROWS() ...
, так как число найденных строк всегда
хранится в кэше.
Если результат запроса вернулся из кеша запросов, тогда статусная переменная
Com_select
не будет увеличена, но вместо нее будет увеличена Qcache_hits
.
See section 6.9.4 Статус и поддержка кэша запросов.
При изменениях таблицы (INSERT
, UPDATE
, DELETE
,
TRUNCATE
, ALTER
или DROP TABLE|DATABASE
), все кэшированные
запросы, использовавшие данную таблицу (возможно, через таблицу
MRG_MyISAM
!), становятся недействительными и удаляются из кэша.
Если изменения были произведены в поддерживающих транзакции таблицах вида
InnoDB
, то все кэшированные запросы становятся недействительными при
выполнении команды COMMIT
.
Запрос не будет кэширован, если содержит одну из приведенных ниже функций:
Функция | Функция | Функция |
Определяемые пользователем функции (UDF)
| CONNECTION_ID
| FOUND_ROWS
|
GET_LOCK
| RELEASE_LOCK
| LOAD_FILE
|
MASTER_POS_WAIT
| NOW
| SYSDATE
|
CURRENT_TIMESTAMP
| CURDATE
| CURRENT_DATE
|
CURTIME
| CURRENT_TIME
| DATABASE
|
ENCRYPT (с одним параметром)
| LAST_INSERT_ID
| RAND
|
UNIX_TIMESTAMP (без параметров)
| USER
| BENCHMARK
|
Запрос также не будет кэширован, если он содержит переменные пользователя,
работает с системными таблицами mysql
,
или выражен в форме SELECT ... IN SHARE MODE
,
SELECT ... INTO OUTFILE ...
,
SELECT ... INTO DUMPFILE ...
или в форме SELECT * FROM
AUTOINCREMENT_FIELD IS NULL
(для получения последнего ID - это для ODBC).
Однако FOUND ROWS()
возвратит правильную величину, даже если из кэша был
выбран предыдущий запрос.
В случае если запрос не использует таблиц, или использует временные таблицы, или если пользователь обладает привилегиями уровня столбца на какую-либо из задействованных таблиц, запрос не будет кеширован.
Перед выборкой запроса из кэша запросов MySQL проверит, обладает ли
пользователь привилегией SELECT
для всех включенных баз данных и таблиц.
Если это не так, то результат кэширования не используется.
6.9.2 Конфигурация кэша запросов
Для кэша запросов в MySQL добавляется несколько системных переменных для
mysqld
, которые могут быть установлены в конфигурационном файле или из
командной строки при запуске mysqld
.
query_cache_limit
Не кэшировать результаты, большие, чем указано (по умолчанию 1Мб).query_cache_size
Память, выделенная для хранения результатов старых запросов. Если равно0
, то кэширование запроса блокируется (по умолчанию). Указывается в байтах.query_cache_type
Можно установить следующие (только числовые) значения:Опция Описание 0 OFF
(``ВЫКЛЮЧЕНО''), результаты не кэшировать и не извлекать1 ON
(``ВКЛЮЧЕНО''), кэшировать все результаты, за исключением запросовSELECT SQL_NO_CACHE ...
2 DEMAND
(``ПО ТРЕБОВАНИЮ''), кэшировать только запросыSELECT SQL_CACHE ...
Внутри потока (соединения) можно изменить функционирование кэша запросов по сравнению с установленным по умолчанию. Синтаксис следующий:
QUERY_CACHE_TYPE = OFF | ON | DEMAND QUERY_CACHE_TYPE = 0 | 1 | 2
Опция | Описание |
0 или OFF | Результаты не кэшировать и не извлекать. |
1 или ON | Кэшировать все результаты за исключением запросов SELECT SQL_NO_CACHE ...
|
2 или DEMAND | Кэшировать только запросы SELECT SQL_CACHE ...
|
6.9.3 Параметры кэша запросов в запросе SELECT
В запросе SELECT
можно указывать две опции для кэша запросов:
Опция | Описание |
SQL_CACHE | Если QUERY_CACHE_TYPE имеет опцию DEMAND , позволяет запросу
кэшироваться. Если QUERY_CACHE_TYPE имеет опцию ON , является
состоянием по умолчанию. Если QUERY_CACHE_TYPE имеет опцию
OFF , ничего не делать.
|
SQL_NO_CACHE | Делает данный запрос некэшируемым, не разрешает хранить в кэше данный запрос. |
6.9.4 Статус и поддержка кэша запросов
С помощью команды FLUSH QUERY CACHE
можно дефрагментировать кэш запросов
с целью лучшего использования его памяти. Эта команда не удалит ни одного
запроса из кэша. Команда FLUSH TABLES
также записывает на диск содержимое
кэша запросов.
Команда RESET QUERY CACHE
удаляет все результаты запросов из кэша
запросов.
Можно контролировать функционирование кэша запросов в SHOW STATUS
:
Переменная | Описание |
Qcache_queries_in_cache | Количество запросов, зарегистрированных в кэше. |
Qcache_inserts | Количество запросов, добавленных в кэш. |
Qcache_hits | Количество результативных обращений в кэш. |
Qcache_lowmem_prunes | Количество запросов, удаленных из кеша по причине недостаточного количества памяти. |
Qcache_not_cached | Количество не кэшированных запросов (не подлежащих кэшированию или из-за установок QUERY_CACHE_TYPE). |
Qcache_free_memory | Величина свободной памяти для кэша запросов. |
Qcache_total_blocks | Общее количество блоков в кэше запросов. |
Qcache_free_blocks | Количество свободных блоков памяти в кэше запросов. |
Общее количество запросов = Qcache_inserts + Qcache_hits +
Qcache_not_cached
.
Кэш запросов использует блоки переменной длины, так что параметры
Qcache_total_blocks
и Qcache_free_blocks
могут показывать фрагментацию
памяти кэша запросов. После команды FLUSH QUERY CACHE
остается только
один (большой) свободный блок.
Примечание: каждый запрос нуждается как минимум в двух блоках (один для текста данного запроса и один или больше - для результатов запроса). Для каждой используемой в запросе таблицы также требуется один блок, но если два или более запросов используют одну и ту же таблицу, требуется выделение только одного блока.
Вы можете использовать переменную Qcache_lowmem_prunes
для настройки
размера кеша запросов. В ней подсчитывается количество запросов, которые были
удалены из кеша для освобождения памяти под новые результаты запросов. Кеш
запросов использует стратегию используется реже всего
(least
recently used, LRU
) для принятия решений о о том, какие запросы удалить из
кеша.
Go to the first, previous, next, last section, table of contents.