2009-11-06 81 views
1

我剛剛接受了一個類似的問題(PHP + MySQL Queue),但我意識到,這不是我的問題了正確的問題,但我的問題:)PHP + MySQL的循環隊列

正確的答案我有一個MySQL(MyISAM類型)由工作人員抓取的網站表。

CREATE TABLE `site` (
    `id` int(11) NOT NULL auto_increment, 
    `url` text, 
    `last_pop` int(13) default NULL, 
    `md5` varchar(32) default NULL, 
    `disabled` tinyint(1) default '0', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `md5` (`md5`), 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

我需要的是爲每個工人取消一個站點而不重複。 所以,如果我有3點和2個工系統需要像這樣的工作:

 ID URL LAST_POP 
t4 1 site1 t1   <- worker1 scrap site1 
t4 2 site2 t2   <- worker2 scrap site2 
t5 3 site3 t3   <- worker1 scrap site3 
t6 1 site2 t4   <- worker2 scrap site2 
t6 2 site1 t4   <- worker1 scrap site1 
t7 3 site3 t5   <- worker2 scrap site3 
.... 

這就像通過last_pop ASC一個循環隊列訂貨。

我該怎麼做?

回答

1

您可能需要跟蹤每個站點的兩條信息:最後一次被抓取的時間以及當前是否被抓取。

使用您的其他問題的答案,將scraping字段設置爲工作人員的ID以將其與其他工作人員進行鎖定。當工作人員完成任務時,將scraping字段設置回null,並將last_scrape日期設置爲當前時間。

CREATE TABLE `site` (
    `id` int(11) NOT NULL auto_increment, 
    `url` text, 
    `last_scrape` TIMESTAMP, 
    `scraping` tinyint(1) default NULL, 
    `md5` varchar(32) default NULL, 
    `disabled` tinyint(1) default '0', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `md5` (`md5`), 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

鎖定和檢索下一個工作(這是最後的部位刮時間最長的前):

Update site 
    set `scraping` = '$worker_id' 
    where `scraping` is null 
    order by `last_scrape` ASC limit 1; 

$job = 
    Select * from site 
    where `scraping` = '$worker_id' 

解除作業回排隊:

Update site 
    set `scraping` = NULL, 
    `last_scrape` = NOW() 
    where `scraping` = '$worker_id'; 
+0

你可能結合使用時間戳和刮取狀態,只要它們的值不會衝突。如果您可能有100名工人,只需選擇'last_scape'> 101的工作,並將'last_scrape'設置爲最多100的工人ID以指定它正在處理中。請確保您將該字段初始化爲更大的值,或者它們可能已顯示爲已鎖定給所有工作人員。 – gapple 2009-11-07 00:20:34

+0

這夠好。謝謝。 – inakiabt 2009-11-09 19:56:11

0

爲什麼不添加一個額外的布爾列狀態,以便您可以通過LAST_POP命令。所以當一個工作人員選擇一個網站進行報廢時,用UPDATE site SET status = '1'運行第二個查詢。當下一個工人選擇下一個工地時,用SELECT * FROM site WHERE status = '0' ORDER BY last_pop ASC運行查詢。