3 月 19 2008
用 MySQL 處理時間資料所應該注意的事
我在 之前的文章 提過 MySQL 裡面,協助我們處理時間資料的 functions,現在來講一下該注意的事。
可能很多人還沒發現到 Year 2038 Problem 。
2007 年 12 月,我在開發某個網頁系統時碰上了這個問題。
在 PHP5 裡面, mktime(11, 14, 7, 1, 19, 2038)
傳回 2147483647,mktime(11, 14, 8, 1, 19, 2038)
卻丟出空白值,而 2147483647 正好是 C 語言中,signed long int 的最大值。
而且,MySQL 的 UNIX timestamp 也有這種問題,以下這串語法傳回來的數值是 0 。
SELECT UNIX_TIMESTAMP( NOW( ) + INTERVAL 50 YEAR );
目前,就我測試過的部份,PHP4 與 JAVA 都沒有這種問題。
可是,我們不知道 PHP4 開發出來的系統,會不會被拿到 PHP5 上面跑。
所以,在 MySQL 裡面使用 datetime 或 timestamp 來紀錄時間資料,並搭配處理時間資料的 functions 來處理時間型資料,不僅方便我們辨識時間,也可以省去不必要的麻煩。
有些人可能會覺得,使用 datetime 或 timestamp 來紀錄時間資料,取出來的資料型態是字串,如果只需要年、月、日,就得作字串分割。
其實,MySQL 的 DATE_FORMAT 就足以應付這種狀況了。
最後,用 MySQL 處理 datetime 或 timestamp 型態的資料,請多注意一件事:
SELECT '2008-01-31 00:00:00' + INTERVAL 1 MONTH;
其結果為 2008-02-29 00:00:00。
SELECT '2008-01-31 00:00:00' + INTERVAL 30 DAY;
其結果則是 2008-03-01 00:00:00。
以上,我的報告完畢,謝謝收看。
8 月 30 2008
謹慎使用 MySQL 的 InnoDB storage engine…
幾個月前,我幫人家建置了一套網頁系統,用以觀察網站瀏覽趨勢。
想當然爾,這種系統勢必會對資料庫產生大量 INSERT 或 UPDATE 的 query,而且會保留大量歷史性資料。
為了使系統能快速存取後端資料庫,我將存放 raw data 資料表的 storage engine 設定為 InnoDB。
(因為 InnoDB 支援了 row lock。 )
並搭配定時執行的 script 整理資料,進行統計,並存放在 MyISAM 格式的資料表中。
最近,這套系統的後端資料庫伺服器,mysqld 三不五時會自行 restart,系統狀態也看似正常(根據他們的說法)。
追蹤後,發現 InnoDB 的運作狀態被忽略了…
光是其中一塊放置 raw data 的資料表就存放了三百多萬筆資料,佔用了 3xx MB 的空間,可是 innodb_buffer_pool_size 只有 256 MB,連 mysqldump 都無法完全撈出這塊資料表的內容…
追查程式後,發現原本用以刪除過期 raw data 的那些程式碼片段都被註解掉.. =_=|||
這段故事給我們幾個啟示:
By Joe Horn • Database 0 • Tags: InnoDB, MySQL