On Duplicate Key Update

Alien85

I like my cat
Сегодня в лог записалась ошибка:

Duplicate entry '96405' for key 'other_id'

INSERT INTO `events` (`other_id`, `city_id`, `type_id`, `user_id`, `url`, `rus_name`, `date`, `genre`)
VALUES ('96405', '2', '3', '3', 'myurl', 'nazvanie', '2011-05-05 09:45:01', 'Рок')
ON DUPLICATE KEY UPDATE
`other_id`=VALUES(`other_id`),
`rus_name`=VALUES(`rus_name`),
`genre`=VALUES(`genre`)

Еще есть поле id - Primary Key

Уникальные индексы:
1. id
2. other_id
3. city_id, type_id, url

Как такое может быть?
Я так понял, что mysql сначала нашел одинаковый третий индекс (city_id, type_id, url), стал обновлять эту запись и уперся, т.к. в другой записи уже есть такой же other_id.
Тогда не понятно, почему mysql сначала не стал использовать индекс other_id?
В документации об этом ни слова...
 

Alien85

I like my cat
Вот что есть в базе:
other_id, city_id, type_id, url
88079, 2, 3, 'myurl'
96405, 2, 3, 'youurl'

вставляется запись:
96405, 2, 3, 'myurl'

Косяк конечно в структуре таблице, но по другому не сделать.
MySQL тут оказалась не причем, при любом раскладе она эту запись не сможет ни вставить, ни изменить.
Придется вручную удалить/изменить запись: 96405, 2, 3, 'youurl'. А я уже успел погрешить на mysql.

Всем спасибо, только не понятно, зачем я всё это тут написал?..
 

itprog

Cruftsman
В документации об этом ни слова...
Открываем документацию и читаем:
If column b is also unique, the INSERT is equivalent to this UPDATE statement instead:
UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
If a=1 OR b=2 matches several rows, only one row is updated. In general, you should try to avoid using an ON DUPLICATE KEY clause on tables with multiple unique indexes.
Т.е. твой запрос будет аналогичен:
UPDATE table SET `other_id`=VALUES(`other_id`) WHERE `other_id` = '96405' OR (`city_id` = 2 AND `type_id` = 3 AND `url` = 'myurl')LIMIT 1;

Т.к. сортировки при этом никакой нет, обновить оно может абсолютно любую запись. Если он найдет запись по второй части OR-условия, то mysql сделает ему `other_id` = 96405, даже если это будет duplicate entry
 

Alien85

I like my cat
itprog, ну это понятно. Непонятно только, какая именно строка будет обновлена, т.к. есть совпадение и с первым индексом и со вторым, а строки разные...
If a=1 OR b=2 matches several rows, only one row is updated.
 
Сверху