Когда использовать разные, никогда не отклоняемые («вставлять или обновлять») операторы MySQL? - PullRequest
3 голосов
/ 22 декабря 2011

Стандартная проблема в приложениях - вставить запись, если она не существует, или обновить, если она существует. В случаях, когда PRIMARY KEY неизвестно, это обычно решается путем выдачи SELECT и последующего запуска либо INSERT или UPDATE, если запись была найдена.

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

CREATE TABLE IF NOT EXISTS `table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `foo` int(10) unsigned NOT NULL,
  `bar` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `row` (`foo`,`bar`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

Вот три метода:

  1. INSERT IGNORE INTO table (foo, bar) VALUES (2,3);

  2. INSERT INTO table (foo, bar) VALUES (2,3) ON DUPLICATE KEY UPDATE;

  3. REPLACE INTO table (foo, bar) VALUES (2,3);

В какое время следует использовать каждый из этих методов?
Может кто-нибудь привести примеры правильных сценариев использования?

Ответы [ 2 ]

5 голосов
/ 22 декабря 2011
  • INSERT следует использовать, когда вы просто хотите вставить новую строку

    Допустим, вы храните записи журнала, вы хотите войтикаждое событие, используйте INSERT.


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

    Допустим, у вас есть таблица телефонных номеров и количество использований, вы найдетев таблице есть новый номер телефона, в котором вы не уверены, но вы хотите, чтобы он был там.

    Вы используете INSERT IGNORE, чтобы убедиться, что он есть.


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

    У вас есть еще одна таблица с телефонными номерами, на этот раз вы найдете новый номер и имя, с которым его можно связать,

    Вы используете REPLACE INTO для поиска и обновления полной записи или просто вставки новой информации.


  • INSERT INTO ... ON DUPLICATE KEY UPDATE ...

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

    Например, если вы храните количество посещений с определенного IP,и первая страница, которую посетил пользователь.

    INSERT INTO visitors (ip,visits,first_page) VALUES (<ip>,1,<current_page>) ON DUPLICATE KEY visits = visits +1;

3 голосов
/ 22 декабря 2011

В вашем вопросе у вас есть

INSERT INTO `table` (foo, bar) VALUES (2,3) ON DUPLICATE KEY UPDATE;

Это может работать только в том случае, если индекс строки был УНИКАЛЬНЫМ:

CREATE TABLE IF NOT EXISTS `table` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `foo` int(10) unsigned NOT NULL,  
  `bar` int(10) unsigned NOT NULL,  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `row` (`foo`,`bar`)  
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;  

В противном случае, почему есть только индекс?

Также предложения ON DUPLICATE KEY позволяют обновлять неиндексированные столбцы.

Что касается REPLACE, имейте в виду, что REPLACE на самом деле DELETE и INSERT под капотом.

...