<rmcreative>

RSS

MySQL, REPLACE INTO и ON DUPLICATE KEY UPDATE

23 декабря 2012

В MySQL есть два расширения, которые позволяют атомарно вставить или обновить запись. Годятся они для штук с довольно высокой нагрузкой, когда без блокировок не работает типичный сценарий:

  1. Выбрать запись.
  2. Если выбралась — обновить.
  3. Если пусто — вставить.

REPLACE

REPLACE INTO
  vote
SET
  user_id = 13,
  object_id = 42,
  value = 7

INSERT INTO ON DUPLICATE KEY UPDATE

INSERT INTO
  vote
SET
  user_id = 13,
  object_id = 42,
  value = 7
ON DUPLICATE KEY UPDATE
  value = 7

Сходства

И то и то выражение в итоге даст примерно тот же результат. При нарушении ограничения на уникальность (то есть UNIQUE KEY или PRIMARY KEY) не будет никакой ошибки. Для ключа user_id, object_id в базе будет единственная запись с значением 7.

Отличия

Кроме очевидного отличия в синтаксисе есть и очень важно отличие в том, как всё это работает. REPLACE при срабатывании ограничения удаляет запись (и вызывает ON DELETE CASCADE) и затем вставляет новую, что не так быстро, как ON DUPLICATE KEY UPDATE, который обновляет запись без удаления.

Комментарии RSS

  1. №7298
    Максим
    Максим 24.12.2012, 0:25:36

    Там еще с автоинкремент тонкость вроде была.

  2. №7299
    ostin
    ostin 24.12.2012, 0:47:47

    Немного тавтология, но такой вариант немного более универсальный:

    ON DUPLICATE KEY UPDATE
      value = VALUES(value)
  3. №7300
    sergunik
    sergunik 24.12.2012, 12:50:50

    Вже писав про такі інсерти - sergunik.name/?p=393

  4. №7302
    vasa_c
    vasa_c 24.12.2012, 13:48:35

    здесь не только в скорости разница. если есть какие-то поля (не указанные в запросе) со значениями отличными от DEFAULT, то UPDATE их не затронет. А REPLACE вставит новую запись с уже DEFAULT-значениями.

  5. №7365
    Илья
    Илья 08.01.2013, 19:10:40

    не подскажите из каких соображений отсутствуют соответствующие метод для моделей в YII?

    довольно часто они были необходимы. в итоге использовал данное решение www.askdev.ru/php/4199/Yii-Расширить-CActiveRecord/

  6. №7372
    Sam
    Sam 09.01.2013, 19:11:33

    Отсутствует потому как это специфичная для MySQL штука, а в Yii всё более-менее универсальное: работает для MySQL, SQLite, PostgreSQL, MSSQL и Oracle.

  7. №7447
    Александр
    Александр 26.01.2013, 14:30:05

    Если не ошибаюсь – INSERT INTO ON DUPLICATE KEY UPDATE увеличивает AUTO_INCREMENT.

  8. №7700
    zedget
    zedget 18.03.2013, 15:54:43

    vasa_c метко подметил - ON DUPLICATE KEY UPDATE в большинстве случаев - более верное решение.

  9. №8337
    Duss
    Duss 09.09.2013, 13:02:00

    "Если не ошибаюсь – INSERT INTO ON DUPLICATE KEY UPDATE увеличивает AUTO_INCREMENT." Как раз наоборот т.к.

    "REPLACE при срабатывании ограничения удаляет запись (и вызывает ON DELETE CASCADE) и затем вставляет новую"

  10. №8348
    Lacmus
    Lacmus 11.09.2013, 12:07:43

    "Если не ошибаюсь – INSERT INTO ON DUPLICATE KEY UPDATE увеличивает AUTO_INCREMENT." - только для InnoDB таблиц

  11. №10246
    masha777
    masha777 02.02.2016, 21:55:05

    привет всем. а какой метод самый быстрый?

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.