MySQL REPLACE в строке с автоматическим увеличением

Допустим, у меня есть таблица MySQL, которая содержит три столбца: id, a и b, а столбец с именем id является полем AUTO INCREMENT. Если я передам MySQL следующий запрос, он будет работать нормально:

REPLACE INTO `table` (`id`, `a`, `b`) VALUES (1, 'A', 'B')

Но если я пропущу поле id, оно больше не будет работать, что и ожидается.

Я хочу знать, есть ли способ ignore некоторых полей в REPLACE запросе. Таким образом, приведенный выше запрос может быть примерно таким:

REPLACE INTO `table` (`a`, `b`) VALUES ('A', 'B')

Зачем мне это нужно?

Иногда мне нужно проверить базу данных с помощью запроса SELECT, чтобы увидеть, существует ли строка или нет. Если он существует, мне нужно UPDATE существующую строку, иначе мне нужно INSERT новую строку. Мне интересно, смогу ли я добиться аналогичного результата (но не такого же) с помощью одного запроса REPLACE.

Почему не может быть тот же результат? Просто потому, что REPLACE будет DELETE существующей строки и INSERT новой строки, которая потеряет текущую primary key и увеличит автоматически увеличивающиеся значения. Напротив, в запросе UPDATE поля primary key и AI останутся нетронутыми.

MySQL ЗАМЕНИТЬ.


person Mahdi    schedule 05.03.2013    source источник
comment
Я не могу понять ваш вопрос. Что на самом деле ты хочешь сделать?   -  person Fathah Rehman P    schedule 05.03.2013
comment
@FathahRehmanP Вы знакомы с MySQL REPLACE?   -  person Mahdi    schedule 05.03.2013
comment
@Mahdi- Пожалуйста, предоставьте данные таблицы перед запросом REPLACE и ожидаемый результат после запроса REPLACE. Я постараюсь дать вам решение   -  person Fathah Rehman P    schedule 05.03.2013
comment
@FathahRehmanP Я обновил свой вопрос :)   -  person Mahdi    schedule 05.03.2013
comment
1) поделиться правильной схемой таблицы. 2) Это не то, как вы должны использовать замену. 3) используйте замену только тогда, когда вы знаете значения primary key.   -  person SparKot    schedule 05.03.2013
comment
@ Махди - мне все еще не ясно твой вопрос. Какие бы данные ни находились в таблице, их следует заменить на ('A', 'B'), верно?   -  person Fathah Rehman P    schedule 05.03.2013
comment
@FathahRehmanP Строка, содержащая 1,A,A, должна быть заменена на 2,A,B. Я думаю, это не так уж и запутанно, не так ли?   -  person Mahdi    schedule 05.03.2013
comment
@Mahdi- Просто удалите все содержимое таблицы, а затем используйте запрос на вставку.   -  person Fathah Rehman P    schedule 05.03.2013
comment
@FathahRehmanP О, чувак, да ладно ... Почему я должен удалять все данные в таблице, чтобы вставить новую строку ???   -  person Mahdi    schedule 05.03.2013
comment
Должен ли я сказать, что those row is just a sample?   -  person Mahdi    schedule 05.03.2013
comment
@Mahdi - предположим, что ваша таблица содержит три строки перед REPLACE (1, A, A) (2, A, B) (3, A, C). Затем вы использовали REPLACE INTO table (a,b) VALUES ('A',' Б') запрос. каков ваш ожидаемый результат?   -  person Fathah Rehman P    schedule 05.03.2013
comment
См. ответ на stackoverflow.com/questions/4901769/   -  person fatal_error    schedule 04.02.2015


Ответы (2)


  • Это не то, как вы должны использовать замену.
  • используйте замену только тогда, когда вы знаете значения primary key.

Руководство по эксплуатации:

Обратите внимание, что если таблица не имеет индекса PRIMARY KEY или UNIQUE, использование оператора REPLACE не имеет смысла. Он становится эквивалентным INSERT, потому что нет индекса, который можно использовать для определения того, дублирует ли новая строка другую.

person SparKot    schedule 05.03.2013
comment
Что, если у нас есть уникальный индекс, скажем, столбец A, и я хочу сделать REPLACE INTO table` (a, b) VALUES ('A', 'B')`? Это хороший вариант использования? - person kevin; 09.10.2018

Что делать, если у вас есть несколько строк, соответствующих полям?

Рассмотрите возможность добавления ключа, который вы можете сопоставить и использовать INSERT IGNORE.. ON DUPLICATE KEY UPDATE. Принцип работы INSERT IGNORE немного отличается от REPLACE.

INSERT IGNORE работает очень быстро, но может иметь некоторые невидимые побочные эффекты.

INSERT... ON DUPLICATE KEY UPDATE

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

Дополнительные сведения о побочных эффектах см. по адресу: https://stackoverflow.com/a/548570/1301627.

Использование INSERT IGNORE, по-видимому, хорошо работает для очень быстрого поиска таблиц MyISAM с несколькими столбцами (возможно, просто полем VARCHAR).

Например,

create table cities (
    city_id int not null auto_increment,
    city varchar(200) not null,
    primary key (city_id),
    unique key city (city))
    engine=myisam default charset=utf8;

insert ignore into cities (city) values ("Los Angeles");

В этом случае многократная повторная вставка «Лос-Анджелес» вообще не приведет к каким-либо фактическим изменениям в таблице и предотвратит создание нового идентификатора авто_инкремента, что может помочь предотвратить исчерпание поля идентификатора (использование всего доступного диапазона авто_инкремента). на сильно набитых столах).

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

person fatal_error    schedule 03.02.2015
comment
Также обратите внимание: если вставка игнорируется, значение из last_insert_id() не определено. Таким образом, вместо того, чтобы использовать это, вам нужно будет выполнить select city_id from cities where city="Los Angeles" после insert ignore, чтобы убедиться, что вы получили хорошее значение идентификатора (если оно вам нужно). Несмотря на это, это все равно будет намного быстрее по сравнению с ON DUPLICATE KEY UPDATE, поскольку (почти всегда) запись выполняется медленнее, чем чтение. (В Innodb при желании используйте транзакцию.) - person fatal_error; 04.02.2015
comment
Если вы собираетесь проголосовать против, пожалуйста, добавьте комментарий, объясняющий, почему вы считаете, что это недопустимый пункт. - person fatal_error; 09.03.2015
comment
В Postgresql это называется UPSERT. - person fatal_error; 09.03.2015