Mysql: вставить, если строка не существует безопасно с ключом и уникальным атрибутом

Фон:

Я построил скребок в Python (не уверен, если это имеет значение). Я очищаю сайт и обновляю свою HTML-таблицу. В основной таблице хранятся autogenerated_id, url, raw_html, date_it_was_scrapped, last_date_the_page_was_updated (предоставленные веб-сайтом). В моей таблице много повторяющихся URL-адресов, которых не должно быть, поэтому я планирую сделать URL-адреса уникальными в базе данных.

Желаемый результат:

Я хочу вставить строку только в том случае, если URL-адрес не существует, и обновить HTML, если last_date_the_page_was_updated> date_it_was_scrapped.

Решение:

Следующий пост stackru показывает, как.
Я не проверял это из-за предупреждения о выбранных ответах: оператор INSERT ... ON DUPLICATE KEY UPDATE для таблицы, содержащей более одного уникального или первичного ключа, также помечается как небезопасный.

Что я планирую сделать, основываясь на вопросе stackru.

INSERT INTO html_table (url, raw_html, date_it_was_scrapped, last_date_the_page_was_updated)
VALUES (the data)
ON DUPLICATE KEY UPDATE
    url = VALUES(url), 
    raw_html = VALUES(raw_html),
    date_it_was_scrapped = VALUES(date_it_was_scrapped),
    last_date_the_page_was_updated=VALUES(last_date_the_page_was_updated)
WHERE last_date_page_was_update > date_it_was_scrapped

Вопрос:

Что в этом небезопасного и есть ли безопасный способ сделать это?

1 ответ

Решение

Из описания ошибки 58637, которая связана на странице документации MySQL, которая помечает INSERT ... ON DUPLICATE KEY UPDATE как небезопасно:

Когда таблица имеет более одного уникального или первичного ключа, этот оператор чувствителен к порядку, в котором механизмы хранения проверяют ключи. В зависимости от этого порядка механизм хранения может определять разные строки для mysql, и, следовательно, mysql может обновлять разные строки [...] Порядок, в котором механизм хранения проверяет ключи, не является детерминированным.

Я понимаю, что ваша таблица имеет автоинкрементный первичный ключ, и вы планируете добавить уникальный ключ в столбец URL. Поскольку первичный ключ автоинкрементен, вы не передадите его в качестве параметра для INSERT команды, как показано в вашей команде SQL. Следовательно, MySQL не нужно будет проверять наличие дубликатов в этом столбце; он будет проверять только дубликаты на url, Как следствие, это INSERT должен быть в безопасности.

Другие замечания по вашему вопросу.

  • вам не нужно обновлять url команда на дубликаты ключей (мы знаем, что это то же самое)

  • Цель WHERE Пункт в вашем запросе неясен, вы уверены, что он нужен?

  • Вам нужно будет удалить дубликаты, прежде чем вы включите уникальное ограничение для URL.

Другие вопросы по тегам