2011-05-06 175 views
124

我們以前的程序員在表中設置了錯誤的排序規則(Mysql)。他用拉丁語整理,當它應該是UTF8,現在我有問題。每個有中國和日本字符的記錄轉到???字符。如何更改數據庫的默認排序規則?

是否可以更改排序規則並取回字符的細節?

+0

可能重複[MySql alter table Collat​​ion](http://stackoverflow.com/questions/742205/mysql-alter-table-collat​​ion) – kenorb 2015-03-03 14:45:44

回答

285

改變數據庫排序規則:

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

變化表歸類:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

變化列排序規則:

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

更多信息:

+4

請注意'CHARACTER SET utf8'將默認爲'utf8_general_ci',但您也可以定義這樣的排序規則:'ALTER DATABASE CHARACTER SET utf8 COLLATE utf8_unicode_ci;'如果需要 – KCD 2014-02-17 08:10:41

+0

...並且我建議你測試它'create table testit(a varchar(1));顯示創建表testit \ G drop table testit;' – KCD 2014-02-17 08:13:07

+0

謝謝@Timo Huovinen,命令工作像魅力:D – 2014-06-03 17:40:35

3

here很好地描述了這個過程。但是,一些不適合拉丁空間的角色將永遠消失。 UTF-8是latin1的SUPERSET。不是相反的。大多數人會適合單字節的空間,但任何不確定的人不會(檢查LATIN1名單 - 不是所有的256個字符的定義,取決於MySQL的latin1的定義)

14

要注意的是在MySQL中,utf8字符集是隻有真正的UTF8字符集的一個子集。爲了節省一個字節的存儲空間,Mysql團隊決定只存儲三個字節的UTF8字符而不是四個字節。這意味着一些東亞語言和表情符號不完全支持。爲確保可以存儲所有UTF8字符,請在Mysql中使用utf8mb4數據類型,並使用utf8mb4_binutf8mb4_general_ci

+1

這是非常有幫助:) – Raz0rwire 2016-07-14 05:02:23

+1

也閱讀http://stackoverflow.com/questions/367711/what-is-the-best-collat​​ion-to-use-for-mysql-with-php?rq=1 – 2016-09-08 07:40:21

29

如何更改所有數據庫/表/列。運行這些查詢,它們將輸出將整個模式轉換爲utf8所需的所有後續查詢。希望這可以幫助!

- 更改數據庫的默認排序規則

SELECT DISTINCT concat('ALTER DATABASE `', TABLE_SCHEMA, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;') 
from information_schema.tables 
where TABLE_SCHEMA like 'database_name'; 

- 更改表整理/字符集

SELECT concat('ALTER TABLE `', TABLE_SCHEMA, '`.`', table_name, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;') 
from information_schema.tables 
where TABLE_SCHEMA like 'database_name'; 

- 更改列排序規則/字符集

SELECT concat('ALTER TABLE `', t1.TABLE_SCHEMA, '`.`', t1.table_name, '` MODIFY `', t1.column_name, '` ', t1.data_type , '(' , t1.CHARACTER_MAXIMUM_LENGTH , ')' , ' CHARACTER SET utf8 COLLATE utf8_unicode_ci;') 
from information_schema.columns t1 
where t1.TABLE_SCHEMA like 'database_name' and t1.COLLATION_NAME = 'old_charset_name'; 
+0

好。 !大約一個小時,我試圖解決同樣的問題。我使用這3個命令,並且我看到字符集已經改變了。但主要問題仍然存在。如果我直接寫入數據庫,那麼在我的瀏覽器中一切都很好。但是,如果我從網站表單添加了一些內容,數據庫中的結果就是??????。有什麼我應該考慮的嗎?我的網絡應用程序是一個.NET MVC應用程序。 – Tchaps 2015-07-11 16:16:47

+0

保存到未來項目的有用查詢中。 – Manatax 2016-03-01 23:08:44

+0

我提出了一些編輯,因爲這些自動查詢還不夠安全。 CHARACTER_MAXIMUM_LENGTH仍然存在問題:當您從例如「最新動態」更改爲「最新動態」時,該值可能會過高。 latin1_swedish_ci到utf8_unicode_ci。 – Ruben 2016-05-03 15:06:37

4

添加到什麼大衛Whittaker發佈,我創建了一個查詢生成完整的表和列alter語句w虐待每個錶轉換。運行

SET SESSION group_concat_max_len = 100000;

首先要確保您的組concat不超過極限,如here所示。

 SELECT a.table_name, concat('ALTER TABLE ', a.table_schema, '.', a.table_name, ' DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci, ', 
     group_concat(distinct(concat(' MODIFY ', column_name, ' ', column_type, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ', if (is_nullable = 'NO', ' NOT', ''), ' NULL ', 
     if (COLUMN_DEFAULT is not null, CONCAT(' DEFAULT \'', COLUMN_DEFAULT, '\''), ''), if (EXTRA != '', CONCAT(' ', EXTRA), '')))), ';') as alter_statement 
    FROM information_schema.columns a 
    INNER JOIN INFORMATION_SCHEMA.TABLES b ON a.TABLE_CATALOG = b.TABLE_CATALOG 
     AND a.TABLE_SCHEMA = b.TABLE_SCHEMA 
     AND a.TABLE_NAME = b.TABLE_NAME 
     AND b.table_type != 'view' 
    WHERE a.table_schema = ? and (collation_name = 'latin1_swedish_ci' or collation_name = 'utf8mb4_general_ci') 
    GROUP BY table_name; 

以前的答案之間這裏的差別在於它使用UTF-8,而不是ut8mb4並使用與t1.CHARACTER_MAXIMUM_LENGTH t1.data_type對枚舉沒有工作了。此外,我的查詢排除視圖,因爲這些視圖將分別進行更改。

我簡單地使用Perl腳本將所有這些變量作爲數組返回並遍歷它們,修復了太長的列(當數據通常只有20個字符時,通常它們是varchar(256)是一個簡單的修復)。

我發現一些數據在從latin1 - > utf8mb4改變時被破壞。它似乎是UTF8編碼的拉丁字符在列中會被轉化爲僞裝。我只是從列前面和後面的列中知道將要成爲內存問題的列中的數據,並將它們進行比較並生成更新語句以修復數據。

相關問題