Mysql Ошибка повторяющейся записи при ON DUPLICATE KEY UPDATE - PullRequest
5 голосов
/ 25 июня 2009

Я использую таблицу памяти . Он имеет несколько идентификаторов и счетчик всех данных является целым числом. Мой код обновляет счетчик на 1, если данные существуют, или создает строку со счетчиком = 1, если нет.

Я использую запрос:

INSERT INTO linked_mem
        ( id1, id2, id31, id4 cnt)
        VALUES (31316, 0, 557158967, 261470594, 1)
        ON DUPLICATE KEY UPDATE cnt= cnt+1

Иногда (около 5% вставок) я получаю «Дублирующую запись» [номера ключей] »для ключа 1

В чем может быть проблема? Разве часть ON DUPLICATE KEY UPDATE не должна обрабатывать дубликат ключа?

Обновление: добавление создания таблицы реальной таблицы

CREATE TABLE `linked_mem` (
  `li_sid` int(10) unsigned NOT NULL default '0',
  `li_id1` int(10) unsigned NOT NULL default '0',
  `li_cid1` int(10) unsigned NOT NULL default '0',
  `li_id2` int(10) unsigned NOT NULL default '0',
  `li_cid2` int(10) unsigned NOT NULL default '0',
  `cnt` int(10) unsigned NOT NULL default '1',
  `li_filter` int(10) unsigned NOT NULL default '0',
  `li_group` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`li_id1`,`li_sid`,`li_cid1`,`li_cid2`,`li_group`,`cnt`,`li_id2`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1

Ответы [ 5 ]

10 голосов
/ 25 июня 2009

Это может произойти, если вы обновите поле, помеченное UNIQUE, и второе нарушение ключа произойдет в UPDATE.

Обновление

Из структуры вашей таблицы я вижу, что это именно ваш случай.

Вот что происходит:

INSERT INTO linked_mem
        ( id1, id2, id31, id4 cnt)
        VALUES (31316, 0, 557158967, 261470594, 1)

-- inserts

INSERT INTO linked_mem
        ( id1, id2, id31, id4 cnt)
        VALUES (31316, 0, 557158967, 261470594, 1)

-- updates `cnt` to 2

INSERT INTO linked_mem
        ( id1, id2, id31, id4 cnt)
        VALUES (31316, 0, 557158967, 261470594, 1)

-- tries again to update `cnt` to 2 and fails

Удалите cnt из вашего PRIMARY KEY определения.

1 голос
/ 25 июня 2009

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

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

INSERT INTO linked_mem
    ( id1, id2, id31, id4, cnt)
VALUES 
    (1, 1, 1, 1, 1),                  // (1, 1, 1, 1, 1) added
    (1, 1, 1, 1, 1),                  // (1, 1, 1, 1, 1) -> (1, 1, 1, 1, 2)
    (1, 1, 1, 1, 1),                  // (1, 1, 1, 1, 1) added (now two rows)
    (1, 1, 1, 1, 1)                   // error
ON DUPLICATE KEY UPDATE cnt = cnt+1

в четвертом ряду (1, 1, 1, 1, 1) будет обновлено до (1, 1, 1, 1, 2), но это уже существует.

1 голос
/ 25 июня 2009

cnt находится в первичном ключе, возможно, именно это приводит к ошибке / невозможности его ОБНОВИТЬ.

0 голосов
/ 17 июля 2014

У меня была такая же проблема.

Использование ON DUPLICATE KEY UPDATE с сохранением ошибки: Повторяющаяся запись

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

0 голосов
/ 25 июня 2009

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

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