2012-02-08 3 views
17

У меня есть основная таблица со столбцами:Слишком много приращения авто с дублированием KEY UPDATE

  • идентификатор (первичный с AI)
  • имени (уникальная)
  • и т.д.

Если уникальная колонка не существует, ВСТАВЛЯЙТЕ строку, в противном случае ОБНОВЛЯЙТЕ строку ....

INSERT INTO pages (name, etc) 
VALUES 
    'bob', 
    'randomness' 
ON DUPLICATE KEY UPDATE 
name = VALUES(name), 
etc = VALUES(etc) 

Проблема в том, что если он выполняет ОБНОВЛЕНИЕ, значение auto_increment в столбце id увеличивается. Поэтому, если выполняется целая группа UPDATES, идентификатор auto_increment проходит через крышу.

Видимо это была ошибка: http://bugs.mysql.com/bug.php?id=28781

... но я использую InnoDB на MySql 5.5.8 на виртуальный хостинг.

Другие люди, имеющие проблемы с не решение лет назад: prevent autoincrement on MYSQL duplicate insert и Why does MySQL autoincrement increase on failed inserts?

Идеи на исправление? Возможно, я каким-то образом структурировал базу данных?

****** EDIT ****: Похоже, добавление innodb_autoinc_lock_mode = 0 в файл my.ini устраняет проблему, но какие параметры у меня есть для общего хостинга?

****** EDIT 2 ******: Хорошо, я думаю, что мой единственный вариант - это перейти на MyISAM в качестве механизма хранения. Будучи мега-новичком mySQL, я надеюсь, что это не вызовет много проблем. Да?

+0

Одна большая проблема с MyISAM является то, что он не поддерживает определение отношений базы данных. InnoDB действительно поддерживает это. – bakkerjoeri

+2

innodb_autoinc_lock_mode = 0 работал для меня. спасибо –

+0

Я переключился на Aria (MyISAM в MariaDB), который предотвращает auto_increment – DanFromGermany

ответ

12

Я не думаю, что есть способ обойти это поведение INSERT ... ON DUPLICTE KEY UPDATE.

Однако вы можете поставить два заявления, одно UPDATE и один INSERT, в одном transaction:

START TRANSACTION ; 

UPDATE pages 
SET etc = 'randomness' 
WHERE name = 'bob' ; 

INSERT INTO pages (name, etc) 
SELECT 
     'bob' AS name 
    , 'randomness' AS etc 
FROM dual 
WHERE NOT EXISTS 
     (SELECT * 
     FROM pages p 
     WHERE p.name = 'bob' 
    ) ; 

COMMIT ; 
+0

Спасибо, чувак. Я закончил этот маршрут. Эта проблема с автоматическим увеличением - это боль в заднице. Не нужны части «AS name» и «AS и т. Д.». –

+0

Нет, эти псевдонимы не нужны. –

+0

@NathanWaters: Добавлена ​​ссылка на документацию MySQL о транзакциях. –

-3

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

+3

Это не так быстро, как я вижу –

Смежные вопросы