Начиная с MySQL 4.1 была введена конструкция позволяющая сформировать запрос на обновление либо добавление данных в зависимости от условия, однако, многие по прежнему не пользуются ей.
Предположим, вы пишете веб-сайт, который обращается к базе данных. И чем больше трафика, тем дольше обрабатывается отправленая информация. При этом стоит помним, что это нужно умножить на количество пользователей, которые посещают сайт. Это особенно актуально, когда базы данных находятся не не том же сервере, что и сам сайт. Это особенно актуально для людей, которые арендуют хостинг у кого-либо. Хостеры разносят сервера по их назначению. Например Server1 отвечает за хранение самих сайтов и их работу, а Server_2 отвечает за хранение баз данных и их работу. Эти сервера соединены по сети. Поэтому очень актуально уменьшить время, которое отводится на обработку запроса к базе.
Пример:
CREATE TABLE ipstat(ip int UNSIGNED NOT NULL PRIMARY KEY,
hits int UNSIGNED NOT NULL,
last_hit timestamp);
INSERT INTO ipstat
VALUES(inet_aton(’192.168.0.1?),1,now())
ON duplicate KEY UPDATE hits=hits+1;
Обратите внимание на функцию inet_aton, которая использована в примере. Она преобразовывает IP-адрес из строковой переменной в порядковое числительное(integer). А это в свою очередь позволяет сохранить IP-адрес в 4 байтах вместь 15.
Зачем используем типа timestamp для поля last_hit. Это позволит не определять метку времени при вставке/обновлении записей. Как только вы вставите новую запись, либо обновите старую, поле автоматически обновится и получит метку времени равную моменту вставки/обновления. Обратите внимание. что в примере значение поля last_int указывается явным образом. Это не ошибка. Дело в том, что в случае, если мы опустим значение поля last_int, в запросе будут передаваться данные только для двух полей(из трёх). В этом случае нам нужно модифицировать запрос и указать явным образом названия полей, для которых передаются значения.
Что сделает запрос?
Если не найдено ни одной записи с передаваемым IP-адресом в качестве значения поля ip, в таблицу будет занесена новая запись. В противном случае, найденая запись будет обновлена. Значение поля с меткой времени изменится. Поле ip является PRIMARY KEY.
Какова выгода от использования данной конструкции по сравнению с INSERT+UPDATE?!
Зависит от количества записей в базе. В среднем уменьшение времени выполнения запросов на 30%. Ещё одним важным моментом является более лёгкое отслеживание ошибок. Простота восприятия.