Вставка и изменение данных. Транзакции.

Запросы на вставку

Запросы на вставку производятся с помощью запроса INSERT.

Общий синтаксис:

INSERT INTO tbl_name (col1, ...) VALUES (val1, ...), ...;

либо

INSERT INTO tbl_name SET col1 = val1, ...;

col* – названия колонок, val* – их значения. val* могут иметь специальное значение DEFAULT, которое приведет к вставке значения по умолчанию, или же NULL, если значение по умолчанию не указано.

Того же эффекта можно достичь, просто не указывая данную колонку в запросе.

Ошибки вставки можно игнорировать, добавив ключевое слово IGNORE после INSERT.

Существует синтаксис для вставки результатов выборки:

INSERT INTO tbl_name (col1, ...) SELECT scol1, ...

При этом результаты запроса SELECT будут вставлены в таблицу tbl_name, причем col1=scol1, col2=scol2 и т.д.

Например:

INSERT INTO stats (id, value) SELECT clientId, SUM(payment) FROM payments GROUP BY clientId;

вставит в таблицу stats значения id=clientId и value = SUM(payment) GROUP BY clientId.

Запросы на изменение

При помощи оператора UPDATE можно изменять данные в одной или нескольких таблицах.

UPDATE join_stmt SET col1 = val1, ... WHERE cond;

Здесь tbl_name – это название таблицы, или выражение JOIN; col* – названия колонок; val* – значения, выражения, возвращающие значения, или DEFAULT; cond – условие, которому должны удовлетворять обновляемые записи.

Надо заметить, что многотабличные обновления с внешними ключами в MySQL могут не работать ввиду нарушения ограничений внешнего ключа. Обращаться с этим следует осторожно.

Напоминаю, что условие WHERE не является, строго говоря, обязательным, однако без него будут изменены все записи. Не следует про это забывать.

Запросы на удаление

При помощи оператора DELETE можно удалить информацию из таблиц. Удаление безвозвратно, и современные тенденции таковы, что информация удаляется крайне редко.

Удаление из одной таблицы:

DELETE FROM tbl_name WHERE cond;

Удаление из нескольких таблиц:

DELETE FROM tbl_name1, ... USING join_stmt WHERE cond;

Здесь tbl_name* – называние таблицы или таблиц, join_stmt – выражение JOIN, используемое для построения условия cond, которому должны удовлетворять удаляемые записи.

В многотабличном удалении, join_stmt может содержать таблицы, не входящие в список tbl_name*.

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

Транзакции

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

Транзакции являются ключевым инструментом обеспечения адекватной работы многопользовательских БД.

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

Для обеспечения этого свойства, может использоваться одна из двух стратегий:

  • Блокирующий подход
    Для осуществления записи, необходимо получение блокировки записи, а для чтения – блокировки чтения. Если на таблице есть блокировка записи, другие блокировки не выдаются, пока текущая не будет снята. Блокировки записи так же не выдаются, если установлены блокировки чтения. Однако может быть выдано одновременно несоклько блокировок чтения.
  • Контроль версий
    Для записи по-прежнему необходимо получение блокировки записи, однако для чтения блокировки не требуются. Вместо этого, сервер гарантирует непротиворечивость читаемых данных, т.е. при чтении, в рамках текущего запроса, данные “кажутся” неизменными, даже если другой пользователь в этот момент изменяет их.

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

MySQL поддерживает оба подхода, в зависимости от механизма хранения данных.

Блокировки, в свою очередь, могут иметь различуню детализацию:

  • Блокирование таблицы
    предотвращает одновременную работу с одной таблицей
  • Блокирование страницы
    предотвращает одновременную работу с одной страницей таблицы (сегментом памяти)
  • Блокирование записей
    предотвращает одновременную работу с одной записью.

Более мелкая детализация подразумевает потребление большего количества оперативной памяти, но при этом меньшее время ожидания. Соответственно, для высоконагруженных серверов БД предпочтительна более мелкая детализация.

Транзакции так же используются для защиты от ошибок. Например, если клиент банка пытается перевести 5000 рублей с одного своего счета на другой, вероятно, он расстроится, если деньги будут сняты с одного счета, а на другой не поступят. Какой бы ни была причина сбоя, транзакции позволяют отменить всю операцию целиком.

Транзакция явно может быть запущена с помощью выражения

START TRANSACTION;

Если транзакция не запущена явно, каждое SQL-выражение выполняется немедленно. Это поведение в MySQL можно отключить выполнением команды SET AUTOCOMMIT=0;

Если автоматическая фиксация изменений отключена, то для каждого сеанса работы с БД автоматически создается транзакция.

Транзакция может быть завершена одним из двух способов:

COMMIT;
ROLLBACK;

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

Кроме того, транзакцию можно отменить не целиком, а частично. Для этого используется механизм точек сохранения.

Для определения точки сохранения используется выражение

SAVEPOINT sp_name;

где sp_name – уникальное название точки.

Откат к точке сохранения может быть произведен при помощи выражения

ROLLBACK TO SAVEPOINT sp_name;

Этот механизм напоминает механизм GOTO в процедурных языках. Однако, в данном случае, происходит переход к прошлому состоянию данных, а не к положению в исходном коде.