Мне нужно сохранить список уникальных страниц в таблице pages
, связанных отношением «многие ко многим» с таблицей page_providers
через таблицу page_xref_page_provider
. Мне трудно разработать эффективную операцию atomi c bulk refre sh, состоящую из следующего:
- Новый список страниц получен от поставщика страниц. Некоторые страницы в этом списке могут быть такими же, как уже записанные в базе данных (с тем же
Url
), в то время как некоторые страницы могут быть удалены из списка, а некоторые могут быть добавлены. - Есть некоторые постраничная статистика в базе данных, поэтому я не должен удалять старую страницу (идентифицированную уникальным
Url
), если есть хотя бы один провайдер страниц, для которого эта страница все еще находится в списке. - Если обновленный список от текущего поставщика страниц не содержит страницу, которую он ранее содержал, и никакой другой поставщик списка страниц не содержит эту страницу в своем списке, страницу следует удалить из таблицы
pages
. - Страницы которые не зарегистрированы на момент получения списка страниц, должны быть добавлены в таблицу
pages
и указаны в page_xref_page_provider
То, что я пробовал:
-- We use IGNORE to handle duplicate URLs on the list we received from the current page provider
-- pages_temp is a temporary table whose creation I have omitted
INSERT IGNORE INTO pages_temp (Url, Host, Port) VALUES (?, ?, ?);
BEGIN;
-- In the DB client program, we get the last inserted ID from the following query and the number of
-- rows affected, so to get a range of newly inserted IDs
INSERT IGNORE INTO pages (Url, Host, Port) SELECT Url, Host, Port FROM pages_temp;
-- This doesn't work (wrong syntax), could you correct me here?
-- When preparing this statement, we parameterize it with the current PageProviderID, the
-- last inserted ID (which is actually the first ID in the bulk) and the number of rows inserted
-- plus the first ID in the bulk.
INSERT INTO page_xref_page_provider (PageProviderID, PageID) SELECT ?, i BETWEEN ? AND ?;
-- This query is parametrized with the current page provider ID
DELETE page_xref_page_provider FROM page_xref_page_provider AS pxpp
JOIN pages ON pxpp.PageID = pages.ID AND pxpp.PageProviderID=?
WHERE pages.Url NOT IN (SELECT Url FROM pages_temp);
-- This seems inefficient because the subquery also fetch the relations not affected by the current
-- list of pages / page provider
DELETE FROM pages WHERE pages.ID NOT IN (SELECT DISTINCT PageID FROM page_xref_page_provider);
COMMIT;