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.