2014-05-10 37 views
0

在我的表mytable中。我有一個名爲session_time (float)的列,其中存儲添加行時的時間(微秒)(我使用PHP函數microtime(true)獲取浮點數)。我如何刪除表格mytable中超過20分鐘的所有行?在MySQL中刪除超過30分鐘的行

我已經嘗試過這樣的事情:

DELETE FROM mytable WHERE session_time < DATE_SUB(NOW(), INTERVAL 1800 SECOND) 

但這刪除所有行!

+1

表格有多大?如果這是一個經常更新的表,並且這種方法可以滿足您的需求,那麼我傾向於採用分區方法並刪除分區。 –

+0

DATE_SUB將使用MySQL的DATETIME/TIMESTAMP格式,而不是PHP的microtime。爲什麼不使用DATETIME代替session_time的float? – Devon

回答

2

更新中...

而不是使用PHP microtime(true)的,你現在應該使用MySQL()函數。刪除舊列,並作出一個新問題:

ALTER TABLE your_table ADD session_time DATETIME NOT NULL DEFAULT NOW(); 

現在,當您添加行,它的session_time將被自動設置爲當前時間,你不需要插入用於session_time任何價值。

現在刪除所有行超過30分鐘,使用:

DELETE FROM your_table WHERE TIMESTAMPDIFF(MINUTE,session_time,NOW()) > 30; 
+0

這是最好的方法,因爲如果您在PHP和MySQL之間混合使用時間戳計算,那麼您只是要求您的站點稍後再中斷。例如,如果將數據庫放在遠程節點上,如果使用microtime()設置時間,但使用NOW()進行比較,則時間戳會稍微偏離。由於他們正在測試微秒,所以稍微不合適是一件大事。 –

+0

@JoshfromQaribou是的。如果我們在數據庫本身中完成所有這些工作,那麼我們使用數據庫服務器的時間,所以時間戳之間不會有任何區別。 –

+0

是的,這是我在評論中推薦的。微秒是他們的存儲空間,但他們正在比較30分鐘,所以在這種情況下微秒是不必要的。我不知道他們的推理微秒,假設OP有一個。你也可以使用PHP來填充查詢,所以如果微秒確實重要,那麼它就依賴於同一個時鐘,因爲我在下面給出了我的答案。 – Devon

0

嘗試

DELETE FROM myTABLE WHERE session_time < (now() - interval 30 minute) 

我沒有測試它。我認爲它也適用。

0

PHP microtime()使用UNIX時間戳格式,而不是DATETIME格式。如果你存儲這樣的東西,你可以使用PHP來填充查詢或使用MySQL的unix_timestamp() function

對於PHP,這將是簡單:

$query = 'DELETE FROM mytable WHERE session_time < '.time() - 1800; 

我只想使用上session_time的DATETIME格式,雖然建議,你應該把MySQL的存儲類型的優勢。

0

聽起來好像您正在比較PHP中生成的微秒值與mysql中生成的時間戳值。有幾件事情在這裏可能會出錯,因爲你可能實際上並沒有時間比較而是時間浮動,或者你的PHP應用使用的是與你的mysql不同的時鐘。

由於您在SQL中進行比較,因此您應該也基於SQL保存session_time值。這是一個默認值的好地方,例如:

mysql> create table mytable (id int not null, session_time timestamp default now()); 
+0

時差與unix時間差別不大,因爲它全部採用UTC。 – Devon

+0

UTC不是重點。如果它是一個遠程節點,它們會。您可以在PHP代碼中計算時間戳,使用您在那裏計算的時間戳在PHP服務器上提交事務,然後將其發送到數據庫服務器。在php和db服務器時鐘上設置的時間也會有細微的差別。 您也忽略了列計算與PHP計算的值的差異。有一百種不同的方法可以在這裏損失微秒級精度。 –

+0

是的,我同意,但對於這種情況,比較是30分鐘而不是微秒,即使存儲是微秒。 – Devon