Archive for the ‘MySQL’ Category

MySQL ROUND() function

星期日, 三月 1st, 2009

最近又需要將大批的數值資料進行四捨五入處理,無奈 MySQL 4.0 的 ROUND() 函式不能用,只好另外用 PHP 去處理,這遠比直接下 SQL 指令慢多了。

MySQL 4.0 的 ROUND() 函式不能用的原因是,ROUND(0.5) 預期會是 1,但是實際跑出來的結果卻是 0。
根據官方網站的說明,ROUND() 函式對數值得處理方式,取決於系統 C 函式庫的處理方式,而可能有以下幾種模式:

  1. round to the nearest even number
  2. always up
  3. always down
  4. always toward zero

不幸地,我的系統是採用第一種,對於 0.5 來說,最近的偶數是 0,因此 ROUND(0.5) 之後會得到 1。

官網上也有網友提出解決的方法,ROUND(X,D) 可以用以下公式替換:

TRUNCATE((X+SIGN(X)*(POW(10,(1-D))/18)), D)

到了 MySQL 5.0 之後,ROUND() 的實作方式也有了改進,根據官方網站的說明,ROUND() 對依據第一個輸入參數的型態進行不同的處理:

  • For exact-value numbers, ROUND() uses the “round half up” or “round toward nearest” rule: A value with a fractional part of .5 or greater is rounded up to the next integer if positive or down to the next integer if negative. (In other words, it is rounded away from zero.) A value with a fractional part less than .5 is rounded down to the next integer if positive or up to the next integer if negative.
  • For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the "round to nearest even" rule: A value with any fractional part is rounded to the nearest even integer.

如此 ROUND(0.5) 便會得到 1,這才是我想要的結果。

針對手邊現有的 FreeBSD 版本與 MySQL 版本進行測試,得到以下結果:

FreeBSD version MySQL version ROUND(0.5) ok?
5.2.1 4.1.11 0 X
5.3 4.0.24 0 X
6.2 4.0.27 0 X
6.2 5.0.45 1 O
7.0 5.0.51a 1 O
7.0 4.0.27 0 X
7.1 4.0.27 0 X

的確,MySQL 5.0.45 之後的 ROUND() 函式比較好用了!

iconv 與 NULL

星期四, 九月 25th, 2008

今天在處理一個文字檔匯入的工作,遇到了 iconv 與 NULL 的小狀況,值得留意一下。

由於網頁是 utf-8,而匯入檔是 big5,因此利用 iconv 來做編碼轉換:

$name = iconv('big5', 'utf-8', $name);

這是再標準不過的寫法了。

但是實際執行匯入時,資料有四萬多筆,卻只匯入了一萬多筆就停了。
打開 log 瞧瞧,發現 MySQL 有錯誤訊息:

Column 'name' cannot be null

原來是有的資料 iconv 轉不出來,就回傳 false,然後欄位 name 又設定不可為 NULL,因此 MySQL 就回傳錯誤訊息。

本來想說,把欄位 name 設定成可接受 NULL 就好,
但這樣又會影響到其他程式,如果其他程式沒有考慮到會有 NULL 的狀況,可能會造成錯誤。
因此最好的做法就是改變匯入時的寫法,遇到 false 就賦予空值,多個小步驟就能解決這個問題。

$name = iconv('big5', 'utf-8', $name);
$name = ($name) ? $name : '';

資料庫比對程式 – diffdb.php

星期一, 九月 17th, 2007

別人寫的總是用不順手,還是自己寫的比較好用。

這程式的目的很簡單,比對兩個資料庫裡的所有資料表,把兩邊不一樣的地方 highlight 出來,可以一目了然地知道那邊不一樣。

使用情境:
一、撰寫程式時常會調整測試資料庫上的資料結構,在程式上線前一定要同步調整上線資料庫的結果,否則程式一上線,系統馬上就會出錯。
二、將程式模組移植到另一個系統時,要先確認兩邊的資料結構是否有差異,如果該有的欄位沒有、或欄位屬性不一致,那麼程式移植過去後一樣會出問題。

Demo: http://weblog.gilbert.tw/public/scripts/diffdb/
Download: http://weblog.gilbert.tw/public/scripts/diffdb/diffdb.zip
這程式是在 FreeBSD 4.11 + PHP 4.4.4 + MySQL 4.0.18 環境下開發測試,有興趣的人請自行下載、修改,不用客氣。

台灣縣市及鄉鎮市區 sql 匯入檔

星期六, 八月 18th, 2007

一時找不到現成的,參考幾個網站後自己 key,日後有需要直接 import 就好了。

  • 台灣縣市 sql 匯入檔
  • 台灣鄉鎮市區 sql 匯入檔
  • phpMyAdmin 的設定參數說明

    星期四, 五月 24th, 2007

    phpMyAdmin 有 wiki 了,裡頭有 config.inc.php 的各項參數說明:

    http://wiki.cihar.com/pma/Config

    MySQL Server 啟動、停止、重開 @Ubuntu 7.04

    星期四, 五月 24th, 2007

    記錄一下指令,免得搞混

    啟動: /etc/rc.d/mysql start
    停止: /etc/rc.d/mysql stop
    重開: /etc/rc.d/mysql restart

    修正 mysqldumpslow.sh

    星期五, 四月 13th, 2007

    依據 MySQL 官方網站的說明,MySQL Slow Log 可以用 mysqldumpslow 來察看,而使用語法可以參考 mysqldumpslow –help 得知。
    但實際上在 MySQL 4.0, 4.1, 5.0 執行 mysqldumpslow –help 後的結果卻是出現以下訊息:

    Unknown option: help
    Bad option at /usr/bin/mysqldumpslow line 19.

    官方網站上已經對此提出修正:
    http://lists.mysql.com/internals/22845
    照官方的說明是要利用 BitKeeper 來修正,不過看修正內容只是修改一下 mysqldumpslow.sh,自己修一下 code 就可以了。

    修正後的檔案可以從此處下載: http://weblog.gilbert.tw/public/mysqldumpslow.sh.gz

    phpMyAdmin 登入時出現 MySQL #1251 錯誤探究

    星期五, 十月 13th, 2006

    安裝 phpMyAdmin 之後,如果登入 MySQL 4.1 以上的 Server 時,有時候會出現錯誤訊息如下:
    #1251 – Client does not support authentication protocol requested by server; consider upgrading MySQL client
    參考 MySQL 官方網站上的說明: http://dev.mysql.com/doc/refman/4.1/en/old-client.html
    照著指示去調整登入帳號的密碼就可以解決此一問題。

    可是為什麼會出現這種錯誤呢?
    是 phpMyAdmin 沒設定好?還是伺服器上的 PHP 沒裝好?還是有其他原因?
    繼續閱讀 »

    MySQL 保留字

    星期二, 七月 18th, 2006

    MySQL 4.1 以前:
    http://dev.mysql.com/doc/refman/4.1/en/reserved-words.html
    MySQL 5.0:
    http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html
    MySQL 5.1:
    http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html

    MySQL – 重新設定 Slave Replication Server 的資料

    星期三, 四月 26th, 2006

    若 MySQL Replication 已運作若干時日,欲重新設定 Slave Server 上的資料,則可依照下列步驟進行:

    ~~~MySQL Master Replication Server 處理開始~~~
    一、取消 Master 上的 log-bin 功能:編輯 my.cnf 檔。
    二、重新啟動 Master 的 MySQL 伺服器:/usr/local/share/mysql.server restart
    三、清除 binary log 檔:bin.index、bin.XXX。
    三、停止 Master 的 MySQL 伺服器:/usr/local/share/mysql.server stop
    四、將 Master 的 MySQL 資料全部壓縮起來。
    五、壓縮完成後,設定開啟 Master 的 log-bin 功能:編輯 my.cnf 檔。
    六、啟動 Master 的 MySQL 伺服器:/usr/local/share/mysql.server start
    七、將壓縮檔傳送到 Slave 伺服器上,並解壓縮至暫存資料夾。
    ~~~MySQL Master Replication Server 處理步驟完成。~~~

    ~~~MySQL Slave Replication Server 處理開始~~~
    八、停止 Slave 的 MySQL 伺服器:/usr/local/share/mysql.server stop
    九、清除所有 replication 記錄檔,包含 master.info、replay-bin.index、replay-bin.XXX、relay-log.info。
    十、將 Master 的 MySQL 資料庫複製到 Slave 的 MySQL 目錄下。
    十一、啟動 Slave 的 MySQL 伺服器:/usr/local/share/mysql.server start
    ~~~MySQL Slave Replication Server 處理步驟完成~~~