Эта глава обеспечивает учебное введение в MySQL, показывая, как использовать mysql , чтобы создать и использовать простую базу данных. mysql (иногда называемый terminal monitor или monitor) является интерактивной программой, которая позволяет Вам соединиться с сервером MySQL, выполнить запросы и рассмотреть результаты. mysql может также использоваться в пакетном режиме: Вы помещаете свои запросы в файл заранее, затем говорите mysql, чтобы выполнять содержание файла. Оба способа использовать mysql покрыты здесь подробно.
Чтобы видеть список возможностей, предоставленных
mysql,
вызовите это с опцией --help
:
shell> mysql --helpЭта глава предполагает, что mysql установлен на Вашей машине и что сервер MySQL доступен, с которым Вы можете соединиться. Если это не так, свяжитесь со своим администратором MySQL. Если Вы и есть администратор, Вы должны консультироваться с соответствующими частями этого руководства, такими как глава 6.
Эта глава описывает весь процесс установки и использования базы данных. Если Вы интересуетесь только доступом к существующей базе данных, Вы можете хотеть перескочить через разделы, которые описывают, как создать базу данных и таблицы, которые это содержит.
Поскольку эта глава обучающая, много деталей опущены. Консультируйтесь с соответствующими разделами руководства для получения дополнительной информации о темах, затронутых здесь.
Чтобы соединиться с сервером, Вы должны будете обычно обеспечивать имя пользователя MySQL, когда Вы вызовете mysql и, наиболее вероятно, пароль. Если сервер будет работать не на той машине, где Вы входите в систему, то Вы должны будете также определить имя хоста. Свяжитесь со своим администратором, чтобы узнать, какие параметры соединения Вы должны использовать, чтобы соединиться (то есть, узел, имя пользователя и пароль, чтобы использовать). Как только Вы знаете надлежащие параметры, Вы должны быть в состоянии соединиться:
shell> mysql -hhost
-uuser
-p Enter password: ********
host
и user
представляют имя
хоста, где Ваш сервер MySQL работает и имя пользователя Вашей учетной записи
MySQL. Замените на соответствующие значения для Вашей установки.
********
представляет Ваш пароль, введите его, когда
mysql
отобразит запрос Enter password:
.
Если это работает, Вы должны видеть некоторую вводную информацию,
сопровождаемую приглашением mysql>
:
shell> mysql -hПриглашениеhost
-uuser
-p Enter password: ******** Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 25338 to server version: 8.0.1-standard Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
mysql>
говорит Вам, что
mysql
готов к работе с запросами.
Если Вы входите в систему на той же самой машине, где работает MySQL, Вы можете опустить узел и просто использовать следующее:
shell> mysql -u user
-p
Если, когда Вы пытаетесь войти в систему, Вы получаете сообщение об ошибке,
например, ERROR 2002 (HY000): Can't connect to local
MySQL server through socket '/tmp/mysql.sock' (2), это означает, что
демон сервера MySQL (Unix) или служба (Windows) не работает. Консультируйтесь
с администратором или см. раздел главы 2, который
является соответствующим Вашей операционной системе.
Для помощт с другими проблемами, с которыми часто сталкиваются, пытаясь войти в систему, см. раздел B.5.2.
Некоторые установки MySQL разрешают пользователям соединяться как анонимный (неназванный) пользователь с сервером, работающим на местном узле. Если это верно на Вашей машине, Вы должны быть в состоянии соединиться с тем сервером, вызывая mysql без любых опций:
shell> mysqlПосле того, как Вы соединились успешно, Вы можете разъединиться в любое время, вводя
QUIT
(или \q
) в ответ
на подсказку mysql>
:
mysql> QUIT Bye
В Unix Вы можете также разъединиться, нажимая Control+D.
Большинство примеров в следующих разделах предполагает, что Вы соединены с
сервером. Они указывают на это подсказкой mysql>
.
Удостоверьтесь, что Вы соединены с сервером, как обсуждено в предыдущем разделе. Выполнение этого само по себе не выбирает базу данных, чтобы работать с ней. В этом пункте более важно узнать немного о том, как делать запросы. Этот раздел описывает основные принципы ввода запросов, используя несколько запросов, которые Вы можете испытать, чтобы ознакомиться с тем, как работает mysql.
Вот простой запрос, который просит, чтобы сервер сказал Вам свой номер
версии и текущую дату. Напечатайте это как показано здесь после подсказки
mysql>
и нажмите Enter:
mysql> SELECT VERSION(), CURRENT_DATE; +-----------+--------------+ | VERSION() | CURRENT_DATE | +-----------+--------------+ | 5.8.0-m17 | 2015-12-21 | +-----------+--------------+ 1 row in set (0.02 sec) mysql>Этот запрос иллюстрирует несколько вещей о mysql:
Запрос обычно состоит из запроса SQL, сопровождаемого точкой с
запятой. Есть некоторые исключения, где точка с запятой может быть опущена.
QUIT
, упомянутый ранее, одно из них.
Мы доберемся до других позже.
mysql>
, чтобы
указать, что это готово к другому запросу.Ключевые слова могут быть введены в любом регистре. Следующие запросы эквивалентны:
mysql> SELECT VERSION(), CURRENT_DATE; mysql> select version(), current_date; mysql> SeLeCt vErSiOn(), current_DATE;Вот другой запрос. Это демонстрирует, что Вы можете использовать mysql в качестве простого калькулятора:
mysql> SELECT SIN(PI()/4), (4+1)*5; +------------------+---------+ | SIN(PI()/4) | (4+1)*5 | +------------------+---------+ | 0.70710678118655 | 25 | +------------------+---------+ 1 row in set (0.02 sec)Запросы, показанные к настоящему времени, были относительно короткими однострочными запросами. Вы можете даже ввести много запросов в одной строке. Только закончите каждый точкой с запятой:
mysql> SELECT VERSION(); SELECT NOW(); +-----------+ | VERSION() | +-----------+ | 5.8.0-m17 | +-----------+ 1 row in set (0.00 sec) +---------------------+ | NOW() | +---------------------+ | 2015-12-21 14:06:10 | +---------------------+ 1 row in set (0.00 sec)Запросы нельзя дать все на одной строке, так что длинные запросы, которые требуют несколько строк, не проблема. mysql определяет, где Ваш запрос заканчивается, ища заканчивающую точку с запятой, а не конец входной строки. Другими словами, mysql принимает ввод свободного формата: это собирает входные строки, но не выполняет их, пока не увидит точку с запятой.
Вот простой многострочный запрос:
mysql> SELECT -> USER() -> , -> CURRENT_DATE; +---------------+--------------+ | USER() | CURRENT_DATE | +---------------+--------------+ | jon@localhost | 2015-12-21 | +---------------+--------------+В этом примере, заметьте, как подсказка изменяется от
mysql>
на ->
после того, как Вы вводите
первую строку многострочного запроса. Это то, как
mysql
указывает, что еще не видел полный запрос. Подсказка Ваш друг, потому что она
обеспечивает ценную обратную связь. Если Вы используете эту обратную связь,
Вы можете всегда знать о том, чего ждет
mysql.
Если Вы решаете, что не хотите выполнять запрос, когда находитесь в
процессе ввода, отмените это, вводя \c
:
mysql> SELECT -> USER() -> \c mysql>Здесь, также, заметьте подсказку. Это переключается назад на
mysql>
после ввода \c
,
для обеспечения обратной связи, чтобы указать, что
mysql
готов к новому запросу.
Следующая таблица показывает каждую из подсказок, которые Вы можете видеть и суммирует то, что они означают о статусе mysql.
Подсказка | Смысл |
---|---|
mysql> |
Готов к новому запросу. |
-> | Ожидание следующей строки многострочного запроса. |
'> | Ожидание следующей строки,
ожидая завершения строки, которая началась с одинарной кавычки
(' ). |
"> |
Ожидание следующей строки, ожидая завершения строки, которая
началась с двойной кавычки (" ). |
`> |
Ожидание следующей строки, ожидая завершения идентификатора, который
начался с обратной кавычки (` ). |
/*> |
Ожидание следующей строки, ожидая завершения комментария, который начался с
/* . |
Многострочные запросы обычно происходят случайно, когда Вы намереваетесь выпустить запрос на одной строке, но забыли заканчивающую точку с запятой. В этом случае mysql ждет больше ввода:
mysql> SELECT USER() ->Если это происходит с Вами (Вы думаете, что ввели запрос, но единственный ответ
->
), наиболее вероятно, что
mysql
ждет точку с запятой. Если Вы не замечаете то, что подсказка говорит Вам, Вы
могли бы сидеть так некоторое время прежде, чем понять, что Вы должны
сделать. Введите точку с запятой, чтобы завершить запрос, и
mysql
его сразу выполнит:
mysql> SELECT USER() -> ; +---------------+ | USER() | +---------------+ | jon@localhost | +---------------+
'>
и ">
происходят во время строкового набора
(другой способ сказать, что MySQL ждет завершения строки). В MySQL Вы можете
написать строки, окруженные также '
или
"
(например, 'hello'
или "goodbye"
), и
mysql
позволяет Вам вводить строки, которые охватывают многократные строки. Когда
Вы видите подсказку '>
или ">
,
это означает, что Вы ввели строку, содержащую строку, которая начинается с
'
или "
, но еще не ввели соответствующую кавычку,
которая заканчивает строку. Это часто указывает, что Вы неосторожно не учли
символ кавычки. Например:
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30; '>Если Вы вводите этот
SELECT
,
затем нажмете Enter
и ждете результата, ничего не происходит. Вместо того, чтобы задаться
вопросом, почему этот запрос занимает много времени, заметьте представление,
данное подсказкой '>
. Это говорит Вам, что
mysql
ожидает увидеть остальную часть незаконченной строки. Вы видите ошибку в
запросе? Строка 'Smith
пропускает вторую одинарную кавычку.
В этом пункте, что Вы делаете? Самая простая вещь состоит в том, чтобы
отменить запрос. Однако, Вы не можете просто ввести \c
в этом случае, потому что mysql
интерпретирует это как часть строки, которую это
собирает. Вместо этого введите заключительный символ кавычки (таким образом
mysql
узнает, что Вы закончили строку), затем введите \c
:
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30; '> '\c mysql>Подсказка изменяется назад на
mysql>
, указывая, что
mysql
готов к новому запросу.
Подсказка `>
подобна '>
и
">
, но указывает, что Вы начали, но
не завершили заключенный в кавычки идентификатор.
Важно знать, что подсказки '>
,
">
и `>
имеют значение, потому что, если Вы
по ошибке вводите незаконченную строку, дальнейшие строки, Вы вводите,
кажется, проигнорированы mysql
, включая строку, содержащую QUIT
.
Это может быть довольно запутывающим, особенно если Вы не знаете, что должны
поставлять заканчивающую кавычку прежде, чем Вы сможете
отменить текущий запрос.
Как только Вы знаете, как ввести запросы SQL, Вы готовы получить доступ к базе данных.
Предположите, что у Вас есть несколько домашних животных (Ваш зверинец), и Вы хотели бы отследить различные типы информации о них. Вы можете сделать так, составляя таблицы, чтобы держать Ваши данные и загружая их желаемой информацией. Тогда Вы можете ответить на различные виды вопросов о Ваших животных, получая данные от таблиц. Этот раздел показывает Вам, как выполнить следующие операции:
Создайте базу данных.
База данных зверинца проста (сознательно), но не трудно думать о ситуациях реального мира, в которых мог бы использоваться подобный тип базы данных. Например, такая база данных могла использоваться фермером, чтобы отследить домашний скот, или ветеринаром, чтобы отследить пациентов. Распределение зверинца, содержащее некоторые из запросов и типовых данных, используемых в следующих разделах, может быть получено с Веб-сайта MySQL. Это доступно в сжатом файле tar и Zip на http://dev.mysql.com/doc/.
Используйте команду SHOW
, чтобы
узнать, какие базы данных в настоящее время существуют на сервере:
mysql> SHOW DATABASES; +----------+ | Database | +----------+ | mysql | | test | | tmp | +----------+База данных
mysql
описывает пользовательские привилегии доступа.
test
часто доступна как рабочее пространство пользователям,
чтобы испытать запросы.
Список баз данных, выведенных на экран запросом, может отличаться на Вашей
машине, SHOW DATABASES
не показывает базы данных, на которые у Вас нет никаких привилегий, если Вы
не имеете привилегии SHOW DATABASES
. См. раздел 14.7.5.14.
Если есть база test
, попробуйте ее:
mysql> USE test Database changed
USE
, аналогично QUIT
,
не требует точки с запятой. Вы можете закончить такие запросы точкой с
запятой, если Вам нравится, это не причиняет вреда.
USE
является особенным в другом
отношении: это должно быть дано на одной строке.
Вы можете использовать базу данных test
(если у Вас есть доступ к этому) для примеров, но что-либо, что Вы создаете в
этой базе данных, может быть удалено кем-либо еще с доступом к ней.
Поэтому Вы должны, вероятно, попросить у своего администратора MySQL
разрешение использовать собственную базу данных. Предположите, что Вы хотите
назвать ее menagerie
.
Администратор должен выполнить запрос:
mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';здесь
your_mysql_name
это имя пользователя MySQL, назначенное
Вам, а your_client_host
это узел, от которого
Вы соединяетесь с сервером.
Если администратор создает Вашу базу данных для Вас, настраивая Ваши разрешения, Вы можете начать использовать ее. Иначе Вы должны создать это непосредственно:
mysql> CREATE DATABASE menagerie;В Unix имена баз данных являются чувствительными к регистру (в отличие от ключевых слов SQL), таким образом, Вы должны всегда обращаться к своей базе данных как к
menagerie
, но не Menagerie
,
MENAGERIE
или еще как-то. Это также истина для имен таблиц. Под
Windows не применяется это ограничение, хотя Вы должны обратиться к базам
данных и таблицам, используя тот же самый регистр символов всюду по данному
запросу. Однако, по множеству причин, рекомендуемая передовая практика это
всегда использовать тот же самый регистр, который использовался, когда
база данных создавалась.
Если Вы получаете такую ошибку, как ERROR 1044 (42000): Access denied for user 'micah'@'localhost' to database 'menagerie' , пытаясь создать базу данных, это означает, что у Вашей учетной записи пользователя нет необходимых привилегий. Обсудите это с администратором или см. раздел 7.2.
Создание базы данных не выбирает ее для использования, Вы должны сделать
это явно. Чтобы сделать menagerie
текущей базой данных, используйте этот запрос:
mysql> USE menagerie Database changedВаша база данных должна быть создана только однажды, но Вы должны выбрать ее для использования каждый раз, когда Вы начинаете сессию mysql. Вы можете сделать это, выполняя
USE
.
Альтернативно, Вы можете выбрать базу данных в командной строке, когда Вы
вызываете mysql
. Только определите имя после любых параметров соединения, которые Вы,
возможно, должны были бы обеспечить. Например:
shell> mysql -hhost
-uuser
-p menagerie Enter password: ********
menagerie
в этой команде
не Ваш пароль. Если Вы хотите поставлять свой
пароль в командной строке после -p
, Вы должны сделать так без
пробела (например, как -pmypassword
, а не -p
mypassword
). Однако, помещение Вашего пароля в командной строке не
рекомендуется, потому что выполнение это выставляет его на всеобщее обозрение
другими пользователями на Вашей машине.
Вы можете видеть в любое время, какая база данных в настоящее время
выбирается, используя SELECT
DATABASE()
.
Создание базы данных является легкой частью, но в этом пункте ее пока нет,
как показывает SHOW TABLES
:
mysql> SHOW TABLES; Empty set (0.00 sec)Сложней решить, какова структура Вашей базы данных должна быть: какие таблицы нужны, каких типов столбцы в них должны быть и т.д.
Вы хотите таблицу, которая содержит запись для каждого из Ваших
домашних животных. Это можно назвать pet
,
и это должно содержать, как минимум, имя каждого животного.
Поскольку имя отдельно не очень интересно, таблица должна содержать другую
информацию. Например, если больше, чем один человек в Вашей семье имеет
домашних животных, Вы могли бы хотеть перечислить владельца каждого
животного. Вы могли бы также хотеть сделать запись некоторой основной
описательной информации, такой как разновидности и пол.
Каков возраст? Это могло бы представлять интерес, но не хорошая идея сохранить возраст в базе данных. Изменения возраста все время происходят, так что Вы должны были бы часто обновлять свои записи. Вместо этого лучше сохранить фиксированное значение, такое как дата рождения. Тогда всякий раз, когда Вы нуждаетесь в возрасте, Вы можете вычислить его как различие между текущей датой и датой рождения. MySQL обеспечивает функции для того, чтобы они сделали арифметику даты, таким образом, это не является трудным. У хранения даты рождения, а не возраста есть также другие преимущества:
Вы можете использовать базу данных для таких задач, как производство напоминаний на наступающие дни рождения. Если Вы думаете, что этот тип запроса несколько глуп, отметьте, что это тот же самый вопрос, который Вы могли бы создать в контексте деловой базы данных, чтобы идентифицировать клиентов, которым Вы должны отослать поздравления с днем рождения на текущей неделе или в этом месяце, для индивидуального подхода.
Вы можете, вероятно, думать о других типах информации, которая была бы
полезна в таблице pet
, но этого пока достаточно: имя, владелец,
разновидности, пол и рождение.
Используйте CREATE TABLE
,
чтобы определить структуру Вашей таблицы:
mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20), -> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
VARCHAR
хороший выбор для
столбцов name
, owner
и species
,
потому что значения столбцов изменяются по длине. Длины в тех определениях
столбца не должны быть теми же самыми и не должны быть 20
.
Вы можете обычно выбирать любую длину от 1
до
65535
, независимо от того, что кажется самым разумным Вам. Если
Вы делаете короткий столбец и оказывается позже, что Вы нуждаетесь в более
длинной области, MySQL обеспечивает запрос
ALTER TABLE
.
Несколько типов значений могут быть выбраны, чтобы представить пол
в записях животных, например, 'm'
и 'f'
или
'male'
и 'female'
.
Является самым простым использовать единственные символы
'm'
и 'f'
.
Использование типа данных DATE
для birth
и death
довольно очевидный выбор.
Как только Вы составили таблицу, SHOW
TABLES
должен произвести некоторый вывод:
mysql> SHOW TABLES; +---------------------+ | Tables in menagerie | +---------------------+ | pet | +---------------------+Чтобы проверить, что Ваша таблица была составлена так, как Вы ожидали, используйте
DESCRIBE
:
mysql> DESCRIBE pet; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | name | varchar(20) | YES | | NULL | | | owner | varchar(20) | YES | | NULL | | | species | varchar(20) | YES | | NULL | | | sex | char(1) | YES | | NULL | | | birth | date | YES | | NULL | | | death | date | YES | | NULL | | +---------+-------------+------+-----+---------+-------+Вы можете использовать
DESCRIBE
в любое время, например, если Вы забываете названия столбцов в Вашей таблице
или типы, которые они имеют.
После составления Вашей таблицы Вы должны заполнить ее.
LOAD DATA
и
INSERT
полезны для этого.
Предположите, что Ваши любимые записи могут быть описаны как показано
здесь. Заметьте, что MySQL ожидает даты в формате 'YYYY-MM-DD'
,
это может отличаться от того, к чему Вы привыкли.
name | owner | species | sex | birth | death |
---|---|---|---|---|---|
Fluffy | Harold | cat | f | 1993-02-04 | |
Claws | Gwen | cat | m | 1994-03-17 | |
Buffy | Harold | dog | f | 1989-05-13 | |
Fang | Benny | dog | m | 1990-08-27 | |
Bowser | Diane | dog | m | 1979-08-31 | 1995-07-29 |
Chirpy | Gwen | bird | f | 1998-09-11 | |
Whistler | Gwen | bird | 1997-12-09 | ||
Slim | Benny | snake | m | 1996-04-29 |
Поскольку Вы начинаете с пустой таблицы, легкий способ заполнить это состоит в том, чтобы создать текстовый файл, содержащий строку для каждого из Ваших животных, затем загрузить содержание файла в таблицу единственным запросом.
Вы можете создать текстовый файл pet.txt
,
содержащий один запись на строку со значениями, отделенными табуляцией,
в том порядке, в котором столбцы были перечислены в
CREATE TABLE
.
Для того, чтобы пропустить значения (такие как неизвестный пол или дату
смерти для животных, которые все еще живут), Вы можете использовать
NULL
. Чтобы представить их в Вашем текстовом файле, надо
использовать \N
(backslash, capital-N).
Например, запись для птицы Whistler была бы похожа на это
(где пробел между значениями это единственный символ табуляции):
Whistler Gwen bird \N 1997-12-09 \NЗагрузить текстовый файл
pet.txt
в таблицу
pet
можно так:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;Если Вы создали файл в Windows редактором, который использует
\r\n
как разделитель строк, Вы должны использовать этот запрос:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet -> LINES TERMINATED BY '\r\n';На Apple под OS X, Вы, вероятно, хотели бы использовать
LINES TERMINATED BY '\r'
.
Вы можете определить разделитель значения столбца и конец маркера строки
явно в LOAD DATA
, если Вы
желаете, но значения по умолчанию являются табуляцией и переводом строки.
Они достаточны для запроса, чтобы считать файл pet.txt
.
Если запрос терпит неудачу, вероятно, что Вашей установке MySQL не включили местное чтение файла по умолчанию. См. раздел 7.1.6.
Когда Вы хотите добавить новые записи по одной, используйте запрос
INSERT
. В его самой простой форме
Вы поставляете значения для каждого столбца, в том порядке, в котором столбцы
были перечислены в CREATE TABLE
. Предположите, что Диана получает нового хомяка, названного
Puffball. Вы могли добавить новую
запись, используя INSERT
:
mysql> INSERT INTO pet -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);Строки и значения даты определены как заключенные определены как заключенные в кавычки строки. Также с
INSERT
Вы можете вставить
NULL
непосредственно, чтобы представлять недостающее значение.
Вы не используете \N
как Вы делаете с
LOAD DATA
.
Из этого примера Вы должны быть в состоянии видеть, что было бы намного
больше ввода, чтобы загрузить Ваши записи первоначально, используя несколько
INSERT
вместо
LOAD DATA
.
SELECT
используется, чтобы
вытянуть информацию из таблицы. Общая форма запроса:
SELECTwhat_to_select
FROMwhich_table
WHEREconditions_to_satisfy
;
what_to_select
указывает на то, что Вы хотите видеть.
Это может быть списком столбцов или *
, чтобы указать
все столбцы. which_table
указывает на таблицу, от которой Вы хотите получить данные.
WHERE
является дополнительным. Если это присутствует,
conditions_to_satisfy
определяет одно или более
условий, которым строки должны удовлетворить, чтобы иметь
право на извлечение.
Самая простая форма SELECT
получает все от таблицы:
mysql> SELECT * FROM pet; +----------+--------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +----------+--------+---------+------+------------+------------+ | Fluffy | Harold | cat | f | 1993-02-04 | NULL | | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | | Fang | Benny | dog | m | 1990-08-27 | NULL | | Bowser | Diane | dog | m | 1979-08-31 | 1995-07-29 | | Chirpy | Gwen | bird | f | 1998-09-11 | NULL | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | | Slim | Benny | snake | m | 1996-04-29 | NULL | | Puffball | Diane | hamster | f | 1999-03-30 | NULL | +----------+--------+---------+------+------------+------------+Эта форма
SELECT
полезна, если
Вы хотите рассмотреть всю таблицу, например, после того, как Вы только что
загрузили ее своей группой исходных данных. Например, Вы думаете, что дата
рождения Bowser не кажется правильной. Консультируясь с Вашей оригинальной
родословной животного, Вы находите, что правильный год рождения
должен быть 1989, а не 1979.
Есть по крайней мере два способа исправить это:
Отредактируйте файл pet.txt
, чтобы
исправить ошибку, освободите таблицу и перезагрузите ее с использованием
DELETE
и
LOAD DATA
:
mysql> DELETE FROM pet; mysql> LOAD DATA LOCAL INFILE 'pet.txt' INTO TABLE pet;Однако, если Вы делаете это, Вы должны также повторно ввести запись для Puffball.
UPDATE
:
mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
UPDATE
изменяет только
рассматриваемую запись и не требует, чтобы Вы перезагрузили таблицу.
Как показано в предыдущем разделе, легко получить всю таблицу.
Только опустите WHERE
в SELECT
. Но, как правило, Вы не хотите видеть всю таблицу, особенно когда
это становится большим. Вместо этого Вы обычно больше интересуетесь ответом
на особый вопрос, когда Вы определяете некоторые ограничения на информацию,
которую Вы хотите. Давайте смотреть на некоторые запросы выбора с точки
зрения вопросов о Ваших домашних животных, на которые они отвечают.
Вы можете выбрать только особые строки из своей таблицы. Например, если Вы хотите проверить изменение, которое Вы производили в дате рождения Bowser, выберите запись Bowser:
mysql> SELECT * FROM pet WHERE name = 'Bowser'; +--------+-------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +--------+-------+---------+------+------------+------------+ | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | +--------+-------+---------+------+------------+------------+Вывод подтверждает, что год правильно зарегистрирован как 1989, а не 1979.
Строковые сравнения обычно являются нечувствительными к регистру,
таким образом, Вы можете определить имя как 'bowser'
,
'BOWSER'
и т.д. Результат запроса тот же самый.
Вы можете определить условия на любом столбце, а не только на
name
. Например, если Вы хотите знать, какие животные родились
во время или после 1998, проверьте столбец birth
:
mysql> SELECT * FROM pet WHERE birth >= '1998-1-1'; +----------+-------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+-------+ | Chirpy | Gwen | bird | f | 1998-09-11 | NULL | | Puffball | Diane | hamster | f | 1999-03-30 | NULL | +----------+-------+---------+------+------------+-------+Вы можете объединить условия, например, определить сук:
mysql> SELECT * FROM pet WHERE species = 'dog' AND sex = 'f'; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+------+------------+-------+ | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+Предыдущий запрос использует логический оператор
AND
.
Есть также OR
:
mysql> SELECT * FROM pet WHERE species = 'snake' OR species = 'bird'; +----------+-------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+-------+ | Chirpy | Gwen | bird | f | 1998-09-11 | NULL | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | | Slim | Benny | snake | m | 1996-04-29 | NULL | +----------+-------+---------+------+------------+-------+
AND
и
OR
могут быть смешаны, хотя
AND
имеет более высокий
приоритет, чем OR
.
Если Вы используете оба оператора, хорошая идея использовать круглые скобки,
чтобы указать явно, как должны быть сгруппированы условия:
mysql> SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm') OR -> (species = 'dog' AND sex = 'f'); +-------+--------+---------+-----+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+-----+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+-----+------------+-------+
Если Вы не хотите видеть все строки от своей таблицы,
только называйте столбцы, которыми Вы интересуетесь, отделенные запятыми.
Например, если Вы хотите знать, когда Ваши животные родились, выберите
столбцы name
и birth
:
mysql> SELECT name, birth FROM pet; +----------+------------+ | name | birth | +----------+------------+ | Fluffy | 1993-02-04 | | Claws | 1994-03-17 | | Buffy | 1989-05-13 | | Fang | 1990-08-27 | | Bowser | 1989-08-31 | | Chirpy | 1998-09-11 | | Whistler | 1997-12-09 | | Slim | 1996-04-29 | | Puffball | 1999-03-30 | +----------+------------+Чтобы узнать, кому принадлежат домашние животные, используйте этот запрос:
mysql> SELECT owner FROM pet; +--------+ | owner | +--------+ | Harold | | Gwen | | Harold | | Benny | | Diane | | Gwen | | Gwen | | Benny | | Diane | +--------+
Заметьте, что запрос просто получает столбец owner
от каждой записи, и некоторые из них появляются не раз. Чтобы минимизировать
вывод, получите каждую уникальную запись только однажды,
добавляя ключевое слово DISTINCT
:
mysql> SELECT DISTINCT owner FROM pet; +--------+ | owner | +--------+ | Benny | | Diane | | Gwen | | Harold | +--------+Вы можете использовать
WHERE
, чтобы объединить выбор строки с
выбором столбца. Например, чтобы получить даты рождения только собак и кошек,
используйте этот запрос:
mysql> SELECT name, species, birth FROM pet -> WHERE species = 'dog' OR species = 'cat'; +--------+---------+------------+ | name | species | birth | +--------+---------+------------+ | Fluffy | cat | 1993-02-04 | | Claws | cat | 1994-03-17 | | Buffy | dog | 1989-05-13 | | Fang | dog | 1990-08-27 | | Bowser | dog | 1989-08-31 | +--------+---------+------------+
Вы, возможно, заметили в предыдущих примерах, что строки результата
выведены на экран без определенного порядка. Часто легче исследовать
вывод запроса, когда строки сортированы некоторым значащим способом.
Чтобы сортировать результат, используйте ORDER BY
.
Вот дни рождения животных, отсортированные по времени:
mysql> SELECT name, birth FROM pet ORDER BY birth; +----------+------------+ | name | birth | +----------+------------+ | Buffy | 1989-05-13 | | Bowser | 1989-08-31 | | Fang | 1990-08-27 | | Fluffy | 1993-02-04 | | Claws | 1994-03-17 | | Slim | 1996-04-29 | | Whistler | 1997-12-09 | | Chirpy | 1998-09-11 | | Puffball | 1999-03-30 | +----------+------------+На символьных столбцах тип сортировки, как все другие операции сравнения, обычно выполняется нечувствительным к регистру. Это означает, что порядок неопределен для столбцов, которые идентичны за исключением их регистра. Вы можете вызвать чувствительный к регистру вид сортировки для столбца при использовании
BINARY
:
ORDER BY BINARY col_name
.
Порядок сортировки по умолчанию поднимается, с самыми маленькими
значениями сначала. Для сортировки в обратном (убывающем) порядке, добавьте
ключевое слово DESC
к названию столбца, который Вы сортируете:
mysql> SELECT name, birth FROM pet ORDER BY birth DESC; +----------+------------+ | name | birth | +----------+------------+ | Puffball | 1999-03-30 | | Chirpy | 1998-09-11 | | Whistler | 1997-12-09 | | Slim | 1996-04-29 | | Claws | 1994-03-17 | | Fluffy | 1993-02-04 | | Fang | 1990-08-27 | | Bowser | 1989-08-31 | | Buffy | 1989-05-13 | +----------+------------+Вы можете сортировать на многократных столбцах, и Вы можете сортировать различные столбцы в различных направлениях. Например, сортировка по типу животного в порядке возрастания, затем по дате рождения в пределах типа животных в порядке убывания (самые молодые животные сначала) использует следующий запрос:
mysql> SELECT name, species, birth FROM pet -> ORDER BY species, birth DESC; +----------+---------+------------+ | name | species | birth | +----------+---------+------------+ | Chirpy | bird | 1998-09-11 | | Whistler | bird | 1997-12-09 | | Claws | cat | 1994-03-17 | | Fluffy | cat | 1993-02-04 | | Fang | dog | 1990-08-27 | | Bowser | dog | 1989-08-31 | | Buffy | dog | 1989-05-13 | | Puffball | hamster | 1999-03-30 | | Slim | snake | 1996-04-29 | +----------+---------+------------+
DESC
применяется только к имени столбца, немедленно
предшествующему этому (birth
), это не затрагивает
порядок сортировки столбца species
.
MySQL обеспечивает несколько функций, которые Вы можете использовать, чтобы выполнить вычисления с датами, например, вычислить возрасты или части извлечения дат.
Чтобы определить, сколько лет каждому из Ваших домашних животных,
используйте TIMESTAMPDIFF()
. Параметры это единицы, в которых Вы хотите выразить результат,
и две даты, для которых нужно взять различие.
Следующий запрос показывает для каждого домашнего животного дату рождения,
текущую дату и возраст в годах. Псевдоним
(age
) используется, чтобы сделать метку столбца окончательного
результата более значащей.
mysql> SELECT name, birth, CURDATE(), -> TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age -> FROM pet; +----------+------------+------------+-----+ | name | birth | CURDATE() | age | +----------+------------+------------+-----+ | Fluffy | 1993-02-04 | 2003-08-19 | 10 | | Claws | 1994-03-17 | 2003-08-19 | 9 | | Buffy | 1989-05-13 | 2003-08-19 | 14 | | Fang | 1990-08-27 | 2003-08-19 | 12 | | Bowser | 1989-08-31 | 2003-08-19 | 13 | | Chirpy | 1998-09-11 | 2003-08-19 | 4 | | Whistler | 1997-12-09 | 2003-08-19 | 5 | | Slim | 1996-04-29 | 2003-08-19 | 7 | | Puffball | 1999-03-30 | 2003-08-19 | 4 | +----------+------------+------------+-----+Запрос работает, но результат могли быть просмотрены более легко, если бы строки были представлены в некотором порядке. Это может быть сделано, добавляя
ORDER BY name
, чтобы сортировать вывод по имени:
mysql> SELECT name, birth, CURDATE(), -> TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age -> FROM pet ORDER BY name; +----------+------------+------------+-----+ | name | birth | CURDATE() | age | +----------+------------+------------+-----+ | Bowser | 1989-08-31 | 2003-08-19 | 13 | | Buffy | 1989-05-13 | 2003-08-19 | 14 | | Chirpy | 1998-09-11 | 2003-08-19 | 4 | | Claws | 1994-03-17 | 2003-08-19 | 9 | | Fang | 1990-08-27 | 2003-08-19 | 12 | | Fluffy | 1993-02-04 | 2003-08-19 | 10 | | Puffball | 1999-03-30 | 2003-08-19 | 4 | | Slim | 1996-04-29 | 2003-08-19 | 7 | | Whistler | 1997-12-09 | 2003-08-19 | 5 | +----------+------------+------------+-----+Чтобы отсортировать вывод по
age
вместо
name
, используйте различный ORDER BY
:
mysql> SELECT name, birth, CURDATE(), -> TIMESTAMPDIFF(YEAR, birth, CURDATE()) AS age -> FROM pet ORDER BY age; +----------+------------+------------+-----+ | name | birth | CURDATE() | age | +----------+------------+------------+-----+ | Chirpy | 1998-09-11 | 2003-08-19 | 4 | | Puffball | 1999-03-30 | 2003-08-19 | 4 | | Whistler | 1997-12-09 | 2003-08-19 | 5 | | Slim | 1996-04-29 | 2003-08-19 | 7 | | Claws | 1994-03-17 | 2003-08-19 | 9 | | Fluffy | 1993-02-04 | 2003-08-19 | 10 | | Fang | 1990-08-27 | 2003-08-19 | 12 | | Bowser | 1989-08-31 | 2003-08-19 | 13 | | Buffy | 1989-05-13 | 2003-08-19 | 14 | +----------+------------+------------+-----+Подобный запрос может использоваться, чтобы определить возраст для животных, которые умерли. Вы определяете, какие это животные, проверяя, что
death
это NULL
. Тогда, для животных со
значениями не-NULL
вычислите различие
между death
и birth
:
mysql> SELECT name, birth, death, -> TIMESTAMPDIFF(YEAR,birth,death) AS age -> FROM pet WHERE death IS NOT NULL ORDER BY age; +--------+------------+------------+------+ | name | birth | death | age | +--------+------------+------------+------+ | Bowser | 1989-08-31 | 1995-07-29 | 5 | +--------+------------+------------+------+Запрос применяет
death IS NOT NULL
вместо
death <> NULL
так как NULL
это
специальное значение, которое не может быть сравнено, используя обычные
операторы сравнения. Это обсуждено позже. См.
раздел 4.3.4.6.
Что, если Вы хотите знать, у каких животных есть дни рождения в следующем
месяце? Для этого типа вычисления год и день не важны: Вы просто хотите
извлечь часть месяца столбца birth
. MySQL обеспечивает несколько
функций для того, чтобы они извлекли части дат, например,
YEAR()
,
MONTH()
и
DAYOFMONTH()
.
MONTH()
как раз
соответствующая функция здесь. Чтобы видеть, как это работает, выполните
простой запрос, который выводит на экран значение birth
и
MONTH(birth)
:
mysql> SELECT name, birth, MONTH(birth) FROM pet; +----------+------------+--------------+ | name | birth | MONTH(birth) | +----------+------------+--------------+ | Fluffy | 1993-02-04 | 2 | | Claws | 1994-03-17 | 3 | | Buffy | 1989-05-13 | 5 | | Fang | 1990-08-27 | 8 | | Bowser | 1989-08-31 | 8 | | Chirpy | 1998-09-11 | 9 | | Whistler | 1997-12-09 | 12 | | Slim | 1996-04-29 | 4 | | Puffball | 1999-03-30 | 3 | +----------+------------+--------------+Обнаружение животных с днями рождения в наступающем месяце также просто. Предположите, что текущий месяц апрель. Тогда значение месяца
4
и Вы можете искать животных, родившихся в мае (месяц 5
):
mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5; +-------+------------+ | name | birth | +-------+------------+ | Buffy | 1989-05-13 | +-------+------------+Есть маленькое осложнение, если текущий месяц декабрь. Вы не можете просто добавить единицу к числу месяца (
12
)
и получить животных, родившихся в месяце 13
,
потому что нет такого месяца. Вместо этого Вы ищете животных,
родившихся в январе (месяц 1
).
Вы можете написать запрос так, чтобы он работал независимо от того,
каков текущий месяц, так, чтобы Вы не использовали число, чтобы указать
месяц. DATE_ADD()
позволяет Вам добавить временной интервал к данной дате. Если Вы добавляете
месяц к значению CURDATE()
, тогда извлеките часть месяца с
MONTH()
, результат производит месяц, в котором можно
искать дни рождения:
mysql> SELECT name, birth FROM pet -> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));Другой способ выполнить ту же самую задачу состоит в том, чтобы добавить
1
, чтобы получить следующий месяц после текущего
после использования функции модуля (MOD
), чтобы сделать
значение месяца 0
, если это в настоящее время 12
:
mysql> SELECT name, birth FROM pet -> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;
MONTH()
возвращает число между 1
и 12
. И
MOD(something,12)
возвращает число между 0
и 11
.
Таким образом, дополнение должно быть после
MOD()
,
иначе мы пошли бы с ноября (11
) в январь (1
).
NULL
может быть удивительным, пока Вы не привыкаете к нему.
Концептуально, NULL
значит
недостающее неизвестное значение
и это обработано несколько по-другому.
Чтобы проверить на NULL
, примените операторы
IS NULL
и
IS NOT NULL
:
mysql> SELECT 1 IS NULL, 1 IS NOT NULL; +-----------+---------------+ | 1 IS NULL | 1 IS NOT NULL | +-----------+---------------+ | 0 | 1 | +-----------+---------------+Вы не можете использовать арифметические операторы сравнения, например,
=
,
<
или
<>
, чтобы
проверить на NULL
.
Чтобы продемонстрировать это для вас непосредственно,
попробуйте следующий запрос:
mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL; +----------+-----------+----------+----------+ | 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL | +----------+-----------+----------+----------+ | NULL | NULL | NULL | NULL | +----------+-----------+----------+----------+Поскольку результат любого арифметического сравнения с
NULL
тоже NULL
,
Вы не можете получить значащие следствия таких сравнений.
В MySQL 0
или NULL
означает ложный, а что-либо еще означает истину. Значение true по умолчанию
от логической операции 1
.
Специальный режим NULL
объясняет, почему
в предыдущем разделе было необходимо определить, какие животные больше не
живы, с использованием death IS NOT NULL
вместо death <> NULL
.
Два значения NULL
расценены как
равные в GROUP BY
.
Делая ORDER BY
, значения NULL
представлены сначала, если Вы делаете ORDER BY ... ASC
и
последними для ORDER BY ... DESC
.
Распространенная ошибка, работая с NULL
, это
предположить, что невозможно вставить ноль или пустую строку в столбец,
определенный как NOT NULL
, но дело обстоит не так.
Они фактически значения, тогда как NULL
значит
нет значения вообще. Вы можете проверить это
достаточно легко при использовании IS [NOT] NULL
:
mysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL; +-----------+---------------+------------+----------------+ | 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL | +-----------+---------------+------------+----------------+ | 0 | 1 | 0 | 1 | +-----------+---------------+------------+----------------+Таким образом полностью возможно вставить нулевое значение или пустую строку в столбец
NOT NULL
, так как они фактически и есть
NOT NULL
. См. раздел
B.5.4.3.
MySQL обеспечивает стандартное соответствие образца SQL так же как форму образца, соответствующего основанному на расширенных регулярных выражениях, подобных используемым утилитами Unix, такими как vi, grep и sed.
Образец SQL позволяет Вам использовать _
, чтобы
соответствовать любому единственному символу и %
, чтобы
соответствовать произвольному числу символов (включая нуль символов). В MySQL
образцы SQL являются нечувствительными к регистру по умолчанию. Некоторые
примеры показывают здесь. Вы не используете =
или
<>
с SQL-шаблонами, воспользуйтесь операторами
LIKE
или
NOT LIKE
вместо этого.
Найти имена, начинающиеся с b
:
mysql> SELECT * FROM pet WHERE name LIKE 'b%'; +--------+--------+---------+-----+------------+------------+ | name | owner | species | sex | birth | death | +--------+--------+---------+-----+------------+------------+ | Buffy | Harold | dog | f | 1989-05-13 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | +--------+--------+---------+-----+------------+------------+Найти имена, заканчивающиеся на
fy
:
mysql> SELECT * FROM pet WHERE name LIKE '%fy'; +--------+--------+---------+-----+------------+-------+ | name | owner | species | sex | birth | death | +--------+--------+---------+-----+------------+-------+ | Fluffy | Harold | cat | f | 1993-02-04 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +--------+--------+---------+-----+------------+-------+Найти имена, содержащие
w
:
mysql> SELECT * FROM pet WHERE name LIKE '%w%'; +----------+-------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+------------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | +----------+-------+---------+------+------------+------------+Чтобы найти имена, содержащие точно пять символов, используйте пять экземпляров символа шаблона
_
:
mysql> SELECT * FROM pet WHERE name LIKE '_____'; +-------+--------+---------+-----+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+-----+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+-----+------------+-------+Другой тип образца, обеспеченный MySQL использует регулярные выражения. Когда Вы проверяете на соответствующие этому типу образцы, используйте
REGEXP
и
NOT REGEXP
(или синонимы RLIKE
и
NOT RLIKE
).
Следующий список описывает некоторые характеристики расширенных регулярных выражений:
.
соответствует любому единственному символу.
[...]
соответствует
любому символу в пределах скобок. Например, [abc]
соответствует
a
, b
или c
.
Чтобы назвать диапазон символов, используйте тире. [a-z]
соответствует любой латинской букве, [0-9]
любой цифре.*
соответствует нулю или больше экземпляров объекта,
предшествующего этому. Например, x*
соответствует любому числу
символов x
(возможно, 0), [0-9]*
соответствует
любому числу цифр, а .*
соответствует любому
количеству чего угодно.REGEXP
преуспевает, если образец соответствует где-нибудь в проверяемом
значении. Это отличается от LIKE
, которое преуспевает, только если образец
соответствует всему значению.^
для начала или $
в конце образца.Чтобы продемонстрировать, как расширенные регулярные выражения работают,
запросы LIKE
, показанные
ранее, переписаны здесь, чтобы использовать
REGEXP
.
Чтобы найти имена, начинающиеся с b
, примените
^
, чтобы соответствовать началу имени:
mysql> SELECT * FROM pet WHERE name REGEXP '^b'; +--------+--------+---------+-----+------------+------------+ | name | owner | species | sex | birth | death | +--------+--------+---------+-----+------------+------------+ | Buffy | Harold | dog | f | 1989-05-13 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | +--------+--------+---------+-----+------------+------------+Если Вы действительно хотите, чтобы сравнение
REGEXP
было
чувствительным к регистру, используйте
BINARY
, чтобы сделать одну из строк двоичной строкой. Этот
запрос соответствует только нижнему регистру b
в начале имени:
mysql> SELECT * FROM pet WHERE name REGEXP BINARY '^b';Чтобы найти имена, заканчивающиеся на
fy
, примените
$
, чтобы соответствовать концу имени:
mysql> SELECT * FROM pet WHERE name REGEXP 'fy$'; +--------+--------+---------+-----+------------+-------+ | name | owner | species | sex | birth | death | +--------+--------+---------+-----+------------+-------+ | Fluffy | Harold | cat | f | 1993-02-04 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +--------+--------+---------+-----+------------+-------+Чтобы найти имена, содержащие
w
в любом месте,
используйте этот запрос:
mysql> SELECT * FROM pet WHERE name REGEXP 'w'; +----------+-------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+------------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | +----------+-------+---------+------+------------+------------+Поскольку регулярный характер выражений соответствует, если он происходит где-нибудь в значении, не надо в предыдущем запросе помещать подстановочный знак по обе стороны от образца, чтобы соответствовать всему значению, как это было бы, если бы Вы использовали образец SQL.
Чтобы найти имена, содержащие точно пять символов, надо использовать
^
и $
, чтобы соответствовать началу и концу имени,
и точно пять копий .
между ними:
mysql> SELECT * FROM pet WHERE name REGEXP '^.....$'; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth| death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m| 1994-03-17 | NULL | | Buffy | Harold | dog | f| 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+Вы могли также написать предыдущий запрос, используя оператор
{n
}
(повторить n
раз):
mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$'; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth| death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m| 1994-03-17 | NULL | | Buffy | Harold | dog | f| 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+См. раздел 13.5.2.
Базы данных часто используются, чтобы ответить на вопрос Как часто определенный тип данных встречается в таблице? . Например, Вы могли бы хотеть знать, сколько домашних животных Вы имеете, сколько домашних животных каждый владелец имеет или Вы могли бы хотеть выполнить различные виды операций переписи на Ваших животных.
Подсчет общего количества животных, которых Вы имеете, является тем же
самым вопросом как Сколько строк находится в таблице
pet
?, потому что есть одна запись на домашнее
животное. COUNT(*)
считает число строк, таким образом, запрос, чтобы посчитать Ваших животных
похож на это:
mysql> SELECT COUNT(*) FROM pet; +----------+ | COUNT(*) | +----------+ | 9 | +----------+Ранее Вы получали имена людей, которым принадлежали домашние животные. Вы можете использовать
COUNT()
, если Вы хотите узнать, сколько домашних животных каждый владелец имеет:
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner; +--------+----------+ | owner | COUNT(*) | +--------+----------+ | Benny | 2 | | Diane | 2 | | Gwen | 3 | | Harold | 2 | +--------+----------+Предыдущее использование запроса
GROUP BY
позволяет
сгруппировать все записи для каждого owner
. Использование
COUNT()
в соединении с
GROUP BY
полезно для характеристики Ваших данных при различных
группировках. Следующие примеры показывают различные способы выполнить
операции переписи животных.
Число животных по разновидностям:
mysql> SELECT species, COUNT(*) FROM pet GROUP BY species; +---------+----------+ | species | COUNT(*) | +---------+----------+ | bird | 2 | | cat | 2 | | dog | 3 | | hamster | 1 | | snake | 1 | +---------+----------+Число животных на пол:
mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex; +------+----------+ | sex | COUNT(*) | +------+----------+ | NULL | 1 | | f | 4 | | m | 4 | +------+----------+В этом выводе
NULL
указывает, что пол неизвестен.
Число животных на комбинацию разновидности и пола:
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex; +---------+-----+----------+ | species | sex | COUNT(*) | +---------+-----+----------+ | bird | NULL| 1 | | bird | f | 1 | | cat | f | 1 | | cat | m | 1 | | dog | f | 1 | | dog | m | 2 | | hamster | f | 1 | | snake | m | 1 | +---------+-----+----------+Вы не должны получить всю таблицу, когда Вы используете
COUNT()
.
Например, предыдущий запрос, когда выполнен только на собаках и кошках,
похож на это:
mysql> SELECT species, sex, COUNT(*) FROM pet -> WHERE species = 'dog' OR species = 'cat' -> GROUP BY species, sex; +---------+-----+----------+ | species | sex | COUNT(*) | +---------+-----+----------+ | cat | f | 1 | | cat | m | 1 | | dog | f | 1 | | dog | m | 2 | +---------+-----+----------+Или если Вы хотели число животных на пол только для животных, пол которых известен:
mysql> SELECT species, sex, COUNT(*) FROM pet -> WHERE sex IS NOT NULL -> GROUP BY species, sex; +---------+-----+----------+ | species | sex | COUNT(*) | +---------+-----+----------+ | bird | f | 1 | | cat | f | 1 | | cat | m | 1 | | dog | f | 1 | | dog | m | 2 | | hamster | f | 1 | | snake | m | 1 | +---------+-----+----------+Если Вы называете столбцы, чтобы выбрать в дополнение к
COUNT()
,
GROUP BY
должен присутствовать, который называет
те же самые столбцы. Иначе, следующее происходит:
Если включен режим SQL
ONLY_FULL_GROUP_BY
, то будет ошибка:
mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT owner, COUNT(*) FROM pet; ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'menagerie.pet.owner'; this is incompatible with sql_mode=only_full_group_by
Если режим
ONLY_FULL_GROUP_BY
выключен, запрос обработан, обрабатывая все
строки как единственную группу, но значение, выбранное для каждого названного
столбца, неопределенно. Сервер свободен выбрать значение из любой строки:
mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> SELECT owner, COUNT(*) FROM pet; +--------+----------+ | owner | COUNT(*) | +--------+----------+ | Harold | 8 | +--------+----------+ 1 row in set (0.00 sec)
См. раздел 13.19.3.
Таблица pet
отслеживает, которых домашних животных Вы имеете.
Если Вы хотите сделать запись другой информации о них, такой как события в их
жизни, как посещения ветеринара или когда родилось потомство, Вы нуждаетесь в
другой таблице. На что должна быть похожей эта таблица?
Это должно содержать следующую информацию:
Уменьшительное имя так, чтобы Вы знали, которому животному принадлежит каждое событие.
Запрос CREATE
TABLE
для таблицы event
:
mysql> CREATE TABLE event (name VARCHAR(20), date DATE, -> type VARCHAR(15), remark VARCHAR(255));Как с таблицей
pet
, является самым легким загрузить начальные
записи, создавая разграниченный табуляциями текстовый файл,
содержащий следующую информацию.
name | date | type | remark |
---|---|---|---|
Fluffy | 1995-05-15 | litter | 4 kittens, 3 female, 1 male |
Buffy | 1993-06-23 | litter | 5 puppies, 2 female, 3 male |
Buffy | 1994-06-19 | litter | 3 puppies, 3 female |
Chirpy | 1999-03-21 | vet | needed beak straightened |
Slim | 1997-08-03 | vet | broken rib |
Bowser | 1991-10-12 | kennel | |
Fang | 1991-10-12 | kennel | |
Fang | 1998-08-28 | birthday | Gave him a new chew toy |
Claws | 1998-03-17 | birthday | Gave him a new flea collar |
Whistler | 1998-12-09 | birthday | First birthday |
Загрузите записи так:
mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;Основываясь на том, что Вы узнали из запросов из таблицы
pet
,
Вы должны быть в состоянии выполнить извлечения на записях в
event
, принципы те же самые.
Предположите, что Вы хотите узнать возрасты, в которых у каждого домашнего
животного был детеныш. Мы видели ранее, как вычислить возрасты с двух дат.
Дата появления детеныша находится в таблице event
, но надо
вычислить возраст матери на ту дату, Вы нуждаетесь в ее дате рождения,
которая сохранена в таблице pet
.
Это означает, что запрос требует обеих таблиц:
mysql> SELECT pet.name, -> TIMESTAMPDIFF(YEAR,birth,date) AS age, -> remark FROM pet INNER JOIN event -> ON pet.name = event.name -> WHERE event.type = 'litter'; +--------+-----+-----------------------------+ | name | age | remark | +--------+-----+-----------------------------+ | Fluffy | 2 | 4 kittens, 3 female, 1 male | | Buffy | 4 | 5 puppies, 2 female, 3 male | | Buffy | 5 | 3 puppies, 3 female | +--------+-----+-----------------------------+Есть несколько вещей, которые надо отметить об этом запросе:
FROM
присоединяется к двум таблицам, потому что
запрос должен вытянуть информацию от них обоих.
name
. Запрос использует ON
, чтобы связать записи в
этих двух таблицах, основываясь на значениях name
.
Запрос использует INNER JOIN
, чтобы объединить таблицы.
INNER JOIN
разрешает строкам от любой таблицы появиться в
результате, если и только если обе таблицы удовлетворяют условиям,
определенным в ON
. В этом примере ON
определяет,
что столбец name
в таблице pet
должен
соответствовать столбцу name
в таблице event
.
Если имя появится в одной таблице, но не в другой, то строка не будет
появляться в результате потому, что условие в ON
не выполнено.
name
в обеих таблицах,
Вы должны быть определенными, которую таблицу имеете в виду, обращаясь к
столбцу. Это сделано, добавляя имя таблицы к имени столбца.У Вас не должно быть двух различных таблиц, чтобы выполнить соединение.
Иногда полезно соединить таблицу с собой, если Вы хотите сравнить записи в
таблице с другими записями в той же самой таблице. Например, чтобы найти
родительские пары среди Ваших домашних животных, Вы можете присоединить
таблицу pet
с собой, чтобы произвести
пары подобных разновидностей:
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species -> FROM pet AS p1 INNER JOIN pet AS p2 -> ON p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm'; +--------+-----+--------+-----+---------+ | name | sex | name | sex | species | +--------+-----+--------+-----+---------+ | Fluffy | f | Claws | m | cat | | Buffy | f | Fang | m | dog | | Buffy | f | Bowser | m | dog | +--------+-----+--------+-----+---------+В этом запросе мы определяем псевдонимы для имени таблицы, чтобы обратиться к столбцам и сохранить прямо, с каким случаем таблицы каждая ссылка столбца связана.
Что, если Вы забываете название базы данных или таблицы или структуру данной таблицы (например, имена столбцов)? MySQL рассматривает эту проблему через несколько запросов, которые предоставляют информацию о базах данных и таблицах, которые это поддерживает.
Вы ранее видели SHOW DATABASES
, который перечисляет базы данных, которыми управляет сервер.
Чтобы узнать, какая база данных в настоящее время выбрана, используйте
DATABASE()
:
mysql> SELECT DATABASE(); +------------+ | DATABASE() | +------------+ | menagerie | +------------+Если Вы еще не выбрали базу данных, результат
NULL
.
Чтобы знать, что какие таблицы включает база данных по умолчанию (например, когда Вы не уверены в названии таблицы), используйте этот запрос:
mysql> SHOW TABLES; +---------------------+ | Tables_in_menagerie | +---------------------+ | event | | pet | +---------------------+Название столбца в выводе, произведенном этим запросом, всегда
Tables_in_db_name
, где
db_name
это название базы данных. См.
раздел 14.7.5.37.
Если Вы хотите узнать о структуре таблицы, используйте
DESCRIBE
,
это выводит на экран информацию о каждом из столбцов таблицы:
mysql> DESCRIBE pet; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | name | varchar(20) | YES | | NULL | | | owner | varchar(20) | YES | | NULL | | | species | varchar(20) | YES | | NULL | | | sex | char(1) | YES | | NULL | | | birth | date | YES | | NULL | | | death | date | YES | | NULL | | +---------+-------------+------+-----+---------+-------+
Field
указывает на имя столбца,
Type
тип данных для столбца,
NULL
указывает, может ли столбец содержать значения
NULL
, Key
указывает, индексирован ли столбец и
Default
определяет значение по умолчанию столбца.
Extra
отображает специальную информацию о столбцах: если столбец
создавался с AUTO_INCREMENT
, значение будет auto_increment
.
DESC
это краткая форма
DESCRIBE
. См.
раздел 14.8.1.
Вы можете получить запрос
CREATE TABLE
, необходимый,
чтобы составить существующую таблицу, используя
SHOW CREATE TABLE
, см.
раздел 14.7.5.10.
Если Вы имеете индексы на таблице, SHOW INDEX FROM
производит информацию о них. См.
раздел 14.7.5.22.tbl_name
В предыдущих разделах Вы использовали mysql в интерактивном режиме, чтобы ввести запросы и смотреть результаты. Вы можете также выполнить mysql в пакетном режиме. Чтобы сделать это, поместите запросы, которые Вы хотите выполнить, в файл, затем скомандуйте mysql, чтобы читать свой ввод из файла:
shell> mysql < batch-file
Если Вы выполняете mysql
в Windows и имеете некоторые специальные символы в файле, которые
вызывают проблемы, Вы можете сделать это:
C:\> mysql -e "source batch-file
"
Если Вы должны определить параметры соединения в командной строке, команда
могла бы быть похожей на это:
shell> mysql -hКогда Вы используете mysql этим путем, Вы создаете файл скрипта, затем выполняя скрипт.host
-uuser
\ -p <batch-file
Enter password: ********
Если Вы хотите, чтобы скрипт продолжился, даже если некоторые из запросов
в нем производят ошибки, Вы должны использовать опцию
--force
.
Почему используется скрипт? Вот несколько причин:
Если Вы выполняете запрос неоднократно (скажем, каждый день или каждую неделю), скрипт позволяет Вам избежать перепечатывать его каждый раз, когда Вы выполняете это.
shell> mysql < batch-file
| more
Вы можете поймать вывод в файл для дальнейшей обработки:
shell> mysql < batch-file
> mysql.out
Вы можете дать свой скрипт другим людям так, чтобы они могли также выполнить запросы.
Выходной формат по умолчанию отличается (более краткий), когда Вы
выполняете mysql
в пакетном режиме от того, когда Вы используете это в интерактивном
режиме. Например, вывод SELECT DISTINCT
species FROM pet
похож на это, когда
mysql
выполнен в интерактивном режиме:
+---------+ | species | +---------+ | bird | | cat | | dog | | hamster | | snake | +---------+В пакетном режиме вывод похож на это:
species bird cat dog hamster snakeЕсли Вы хотите получить интерактивный выходной формат в пакетном режиме, используйте mysql -t . Чтобы добавить к выводу запросы, которые выполнены, используют mysql -v.
Вы можете также использовать скрипты из подсказки
mysql с
помощью команд source
или \.
:
mysql> sourceСм. раздел 5.5.1.5.filename
; mysql> \.filename
Вот примеры того, как решить некоторые типичные проблемы с MySQL.
Некоторые из примеров используют таблицу shop
, чтобы хранить
цену каждого артикула (номер изделия) для определенных торговцев (дилеры).
Если у каждого торговца есть единственная постоянная цена за артикул, тогда
(article
, dealer
) это первичный ключ для записей.
Запустите инструмент командной строки mysql и выберите базу данных:
shell> mysql your-database-name
В большинстве установок MySQL Вы можете использовать
базу данных test
.
Вы можете создать и заполнить таблицу в качестве примера с этими запросами:
CREATE TABLE shop (article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, dealer CHAR(20) DEFAULT '' NOT NULL, price DOUBLE(16,2) DEFAULT '0.00' NOT NULL, PRIMARY KEY(article, dealer)); INSERT INTO shop VALUES (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45), (3,'C',1.69),(3,'D',1.25),(4,'D',19.95);После выполнения запросов у таблицы должно быть следующее содержание:
SELECT * FROM shop; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | A | 3.45 | | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | B | 1.45 | | 0003 | C | 1.69 | | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+
Каков самый большой номер изделия?
SELECT MAX(article) AS article FROM shop; +---------+ | article | +---------+ | 4 | +---------+
Задача: Найдите число, дилера, и цену самого дорогого артикула .
Это легко сделано с подзапросом:
SELECT article, dealer, price FROM shop WHERE price=(SELECT MAX(price) FROM shop); +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0004 | D | 19.95 | +---------+--------+-------+Другие решения состоят в том, чтобы использовать
LEFT JOIN
или
отсортировать все убывание строк по цене и получить только первую строку,
используя MySQL-определенный параметр LIMIT
:
SELECT s1.article, s1.dealer, s1.price FROM shop s1 LEFT JOIN shop s2 ON s1.price < s2.price WHERE s2.article IS NULL; SELECT article, dealer, price FROM shop ORDER BY price DESC LIMIT 1;
Если было несколько самых дорогих артикулов, каждый с ценой 19.95,
LIMIT
показал бы только один из них.
Задача: Найдите самую высокую цену за артикул.
SELECT article, MAX(price) AS price FROM shop GROUP BY article; +---------+-------+ | article | price | +---------+-------+ | 0001 | 3.99 | | 0002 | 10.99 | | 0003 | 1.69 | | 0004 | 19.95 | +---------+-------+
Задача: Для каждого артикула найдите дилера или дилеров с самой высокой ценой.
Эта проблема может быть решена с подзапросом:
SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article); +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | C | 1.69 | | 0004 | D | 19.95 | +---------+--------+-------+Предыдущий пример использует коррелированый подзапрос, который может быть неэффективным (см. раздел 14.2.10.7 ). Другие возможности для того, чтобы решить проблему состоят в том, чтобы использовать некоррелированый подзапрос в
FROM
или LEFT JOIN
.
Некоррелированый подзапрос:
SELECT s1.article, dealer, s1.price FROM shop s1 JOIN (SELECT article, MAX(price) AS price FROM shop GROUP BY article) AS s2 ON s1.article = s2.article AND s1.price = s2.price;
LEFT JOIN
:
SELECT s1.article, s1.dealer, s1.price FROM shop s1 LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price WHERE s2.article IS NULL;
LEFT JOIN
работает на основе того что, когда
s1.price
в его максимальном значении, нет
s2.price
с большим значением и значения строк s2
будут NULL
. См. раздел 14.2.9.2.
Вы можете использовать пользовательские переменные MySQL, чтобы помнить результаты, не имея необходимости хранить их во временных переменных в клиенте. (См. раздел 10.4.
Например, чтобы найти артикулы с самой высокой и самой низкой ценами Вы можете сделать это:
mysql> SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop; mysql> SELECT * FROM shop WHERE price=@min_price OR price=@max_price; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+
Также возможно сохранить название объекта базы данных, такого как таблица или столбец, в пользовательской переменной и затем использовать эту переменную в запросе SQL, однако, это требует использования готового запроса. См. раздел 14.5.
В MySQL таблицы InnoDB
поддерживают ограничения внешнего
ключа. См. главу 16 и
раздел 1.8.2.3.
Ограничение внешнего ключа не требуется, чтобы
просто присоединиться к двум таблицам. Для механизмов хранения кроме
InnoDB
, возможно, определяя столбец использовать
REFERENCES
, что не имеет никакого фактического эффекта, и
служит только в качестве записки или комментария Вам, что столбец,
который Вы в настоящее время определяете, предназначен, чтобы обратиться к
столбцу в другой таблице. Чрезвычайно важно понять, используя
этот синтаксис, что:tbl_name
(col_name
)
MySQL не выполняет проверку CHECK
, чтобы
удостовериться, что col_name
фактически существует в
tbl_name
(или даже что
tbl_name
непосредственно существует).
tbl_name
,
как удаление строк в ответ на действия со строками в таблице, которую Вы
определяете, другими словами, этот синтаксис не вызывает ON
DELETE
или ON UPDATE
вообще. Хотя Вы можете написать
ON DELETE
или ON UPDATE
как часть
REFERENCES
, это также проигнорировано.Вы можете использовать столбец как столбец соединения, как показано здесь:
CREATE TABLE person (id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, name CHAR(60) NOT NULL, PRIMARY KEY (id)); CREATE TABLE shirt (id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, style ENUM('t-shirt', 'polo', 'dress') NOT NULL, color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL, owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id), PRIMARY KEY (id)); INSERT INTO person VALUES (NULL, 'Antonio Paz'); SELECT @last := LAST_INSERT_ID(); INSERT INTO shirt VALUES (NULL, 'polo', 'blue', @last), (NULL, 'dress', 'white', @last), (NULL, 't-shirt', 'blue', @last); INSERT INTO person VALUES (NULL, 'Lilliana Angelovska'); SELECT @last := LAST_INSERT_ID(); INSERT INTO shirt VALUES (NULL, 'dress', 'orange', @last), (NULL, 'polo', 'red', @last), (NULL, 'dress', 'blue', @last), (NULL, 't-shirt', 'white', @last); SELECT * FROM person; +----+---------------------+ | id | name | +----+---------------------+ | 1 | Antonio Paz | | 2 | Lilliana Angelovska | +----+---------------------+ SELECT * FROM shirt; +----+---------+--------+-------+ | id | style | color | owner | +----+---------+--------+-------+ | 1 | polo | blue | 1 | | 2 | dress | white | 1 | | 3 | t-shirt | blue | 1 | | 4 | dress | orange | 2 | | 5 | polo | red | 2 | | 6 | dress | blue | 2 | | 7 | t-shirt | white | 2 | +----+---------+--------+-------+ SELECT s.* FROM person p INNER JOIN shirt s ON s.owner = p.id WHERE p.name LIKE 'Lilliana%' AND s.color <> 'white'; +----+-------+--------+-------+ | id | style | color | owner | +----+-------+--------+-------+ | 4 | dress | orange | 2 | | 5 | polo | red | 2 | | 6 | dress | blue | 2 | +----+-------+--------+-------+Когда используется этим способом,
REFERENCES
не выведен на экран в выводе SHOW
CREATE TABLE
или DESCRIBE
:
SHOW CREATE TABLE shirt\G *************************** 1. row *************************** Table: shirt Create Table: CREATE TABLE `shirt` ( `id` smallint(5) unsigned NOT NULL auto_increment, `style` enum('t-shirt','polo','dress') NOT NULL, `color` enum('red','blue','orange','white','black') NOT NULL, `owner` smallint(5) unsigned NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1Использование
REFERENCES
таким образом как комментарий или
напоминание в определении столбца
работает с таблицами MyISAM
.
OR
с
использованием единственного ключа хорошо оптимизировано, как обработка
AND
.
Один хитрый случай это случай поиска на двух различных ключах,
объединенных с OR
:
SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1' OR field2_index = '1'Этот случай оптимизирован. См. раздел 9.2.1.4.
Вы можете также решить проблему эффективно при использовании
UNION
, это комбинирует вывод двух
отдельных SELECT
. См.
раздел 14.2.9.3.
Каждый SELECT
ищет
только один ключ, поиски могут быть оптимизированы:
SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1' UNION SELECT field1_index, field2_index FROM test_table WHERE field2_index = '1';
Следующий пример показывает, как Вы можете использовать разрядные групповые функции, чтобы вычислить сколько дней в месяц, пользователь посетил Веб-страницу.
CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL, day INT(2) UNSIGNED ZEROFILL); INSERT INTO t1 VALUES (2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2), (2000,2,23),(2000,2,23);Таблица в качестве примера содержит значения, представляющие посещения пользователями страницы. Чтобы определить, сколько различных дней в каждом месяце эти посещения происходят, используйте этот запрос:
SELECT year, month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1 GROUP BY year,month;Что в итоге возвращает:
+------+-------+------+ | year | month | days | +------+-------+------+ | 2000 | 01 | 3 | | 2000 | 02 | 2 | +------+-------+------+Запрос вычисляет, сколько различных дней появляется в таблице для каждой комбинации года/месяца, с автоматическим удалением двойных записей.
Атрибут AUTO_INCREMENT
может использоваться, чтобы произвести
уникальную идентичность для новых строк:
CREATE TABLE animals (id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (id)); INSERT INTO animals (name) VALUES ('dog'),('cat'),('penguin'), ('lax'),('whale'),('ostrich'); SELECT * FROM animals;Результат примерно такой:
+----+---------+ | id | name | +----+---------+ | 1 | dog | | 2 | cat | | 3 | penguin | | 4 | lax | | 5 | whale | | 6 | ostrich | +----+---------+Никакое значение не было определено для столбца
AUTO_INCREMENT
,
таким образом, MySQL назначал порядковые номера автоматически. Вы можете
также явно назначить 0 столбцу, чтобы производить порядковые номера, если
включен режим SQL
NO_AUTO_VALUE_ON_ZERO
. Если столбец объявлен как NOT
NULL
, также возможно назначить NULL
к столбцу, чтобы
произвести порядковые номера. Когда Вы вставляете любое другое значение в
AUTO_INCREMENT
, столбец установлен в то значение, и
последовательность сброшена так, чтобы следующее автоматически произведенное
значение следовало последовательно от самого большого значения столбца.
Вы можете получить новое, автоматически произведенное значение
AUTO_INCREMENT
с помощью функции SQL
LAST_INSERT_ID()
или функции C API
mysql_insert_id()
.
Эти функции являются определенными для соединения, таким образом, их
возвращаемые значения не затронуты другим соединением,
которое также вставляет.
Используйте самый маленький тип данных целого числа для
AUTO_INCREMENT
, который является достаточно большим, чтобы
содержать максимальное значение последовательности, в котором Вы будете
нуждаться. Когда столбец достигает верхнего предела типа данных, следующая
попытка произвести порядковый номер терпит неудачу. Используйте
атрибут UNSIGNED
, если возможно, чтобы позволить больший
диапазон. Например, если Вы используете
TINYINT
,
максимальный допустимый порядковый номер 127. Для
TINYINT UNSIGNED
максимум
255. См. раздел 12.2.1.
Для многострочных вставок
LAST_INSERT_ID()
и mysql_insert_id()
фактически возвратят AUTO_INCREMENT
от первой из вставленных строк. Это позволяет
многострочной вставке быть воспроизведенной правильно на
других серверах в репликации.
Чтобы AUTO_INCREMENT
стартовала не с 1,
установите то значение с CREATE
TABLE
или ALTER TABLE
:
mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;
Для информации о AUTO_INCREMENT
с InnoDB
см.
раздел 16.8.5.
Для таблиц MyISAM
Вы можете определить
AUTO_INCREMENT
на втором столбце в многостолбцовом индексе. В
этом случае произведенное значение для AUTO_INCREMENT
вычислено как MAX(
. Это полезно, когда Вы хотите поместить
данные в упорядоченные группы.
auto_increment_column
) + 1 WHERE prefix=given-prefix
CREATE TABLE animals (grp ENUM('fish','mammal','bird') NOT NULL, id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (grp,id)) ENGINE=MyISAM; INSERT INTO animals (grp,name) VALUES ('mammal','dog'),('mammal','cat'), ('bird','penguin'),('fish','lax'),('mammal','whale'), ('bird','ostrich'); SELECT * FROM animals ORDER BY grp,id;Это в итоге вернет:
+--------+----+---------+ | grp | id | name | +--------+----+---------+ | fish | 1 | lax | | mammal | 1 | dog | | mammal | 2 | cat | | mammal | 3 | whale | | bird | 1 | penguin | | bird | 2 | ostrich | +--------+----+---------+В этом случае (когда столбец
AUTO_INCREMENT
часть многостолбцового индекса) значения AUTO_INCREMENT
снова использованы, если Вы удаляете строку с самым большим
AUTO_INCREMENT
в любой группе. Это происходит даже для таблиц
MyISAM
, для которых AUTO_INCREMENT
обычно снова не используются.AUTO_INCREMENT
часть многих индексов, MySQL
производит значения последовательности, используя индексирование, которое
начинается со столбца AUTO_INCREMENT
, если такое есть.
Например, если таблица animals
имеет индексы
PRIMARY KEY (grp, id)
и INDEX (id)
, MySQL
проигнорировал бы PRIMARY KEY
для того, чтобы произвести значения последовательности. В результате таблица
содержала бы единственную последовательность не по grp
.
Больше информации о AUTO_INCREMENT
доступно здесь:
Как назначить столбцу AUTO_INCREMENT
: разделы
14.1.15 и
14.1.7.
AUTO_INCREMENT
ведет себя в зависимости от режима SQL
NO_AUTO_VALUE_ON_ZERO
: раздел 6.1.8
.
LAST_INSERT_ID()
, чтобы найти строку, которая содержит новое
значение AUTO_INCREMENT
:
раздел 13.14.Есть программы, которые позволяют Вам подтверждать подлинность своих пользователей от базы данных MySQL, а также писать свои файлы системного журнала в таблицу MySQL.
Вы можете изменить формат регистрации в Apache, чтобы быть легко читаемым MySQL, помещая следующее в конфигурационный файл Apache:
LogFormat \ "\"%h\",%{%Y%m%d%H%M%S}t,%>s,\"%b\",\"%{Content-Type}o\", \ \"%U\",\"%{Referer}i\",\"%{User-Agent}i\""Чтобы загрузить файл системного журнала в этом формате в MySQL, Вы можете использовать запрос вроде этого:
LOAD DATA INFILE 'Названная таблица должна быть составлена, чтобы иметь столбцы, которые соответствуют тем, которые строка/local/access_log
' INTO TABLEtbl_name
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
LogFormat
пишет в файл системного журнала.