星期三, 5月 29, 2019

MySQL 到底有沒有 case sensitive ?

公司的程式有人回報說,在搜尋電子郵件時,沒有區分大小寫 (case insensitive),我心裡想,雖然電子郵件並沒有嚴格區分大小寫,但我應該沒有特別做這件事,照理說,是要有區分大小寫才是,於是我開始看程式碼去找是不是 Django 等框架/函式庫自動加上了。
不過我找了好一陣子都沒找到,看來應該不是程式的問題。既然不是程式問題,那就可能是資料庫問題了,我在開發環境的 SQLite 裡用 SELECT SQL 查詢,有區分大小寫;生產環境是用 MySQL,我改在 MySQL shell 用 SELECT SQL 來查詢。結果,真的是資料庫設定問題,上網搜尋,才確定真的是 MySQL 問題:
簡單的說,是 collation 問題,所以解決方法也算是簡單,一個方法是改變 collation,看是要資料庫整個改,還是個別 table/column 去改;一個方法則是改 column data type。
MySQL 手冊對 collation 的說明是這樣的 (連結),只要後綴是 _cs 的或是 _bin 的,都是 case-sensitive 的。改 collation ,可以先使用 SHOW COLLATION WHERE COLLATION LIKE “%_cs” 來找,但 utf8 是沒有後綴名為 _cs 的 collation,只能使用 utf8_bin 。找到合適的 collation 後,要改指定 column data type ,可以使用 ALTER TABLE documents__document CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;
以 Django 來說,當然最好是一開始在建立資料庫時,就指定好 charset 跟 collation,之後的作法就是自己寫 Migration 執行自訂的 SQL 來變更指定欄位的 data type 了。

沒有留言: