2012-11-30 40 views
1

在我的公司中,數據庫中的表格創建不善。每張表都有不同的排序和字符集。MySQL整理問題

這非常糟糕,當然,但它會使查詢的性能大幅下降,直到服務器崩潰(甚至不是一個好的數據庫......)。

我想知道是否有任何好的MySQL工具,命令或程序轉換表整理和字符集。

只要執行alter table並執行convert就會制動特殊字符。這是正常的還是我做錯了什麼?

編輯: 作爲例子:我有一個表財務與uft8整理和拉丁瑞典與表費用。每張桌子有1000到5000行。下面的查詢需要15秒到執行:

select ex.* from expense ex 
    inner join finance fin on fin.ex_id = ex.id 

執行有更大的表多絡合劑查詢運行得更快,當他們有相同的排序規則。

編輯2: 數據庫中的另一個錯誤:行ids都是varchar(15),而不是int。

+0

即使每一列都有不同的字符集,它也不應該使性能嚴重劣化,並且如果一切正常處理,它不應該搞亂特殊字符。您應該提供更多關於究竟發生了什麼的細節。 – deceze

+0

除非這些id字段是文本,否則charset不應該在聯接中影響性能。 –

回答

1

我不建議使用「工具」來解決這個問題。

之前你做任何事情轉儲數據庫已在情況下,你搞砸了一個備份;)

,您可以簡化您的字符集和校對兩種方式

方法1:將您的數據

  • 創建的所有表中配置的正確的字符集和歸類一個完全新的數據庫

  • 用INSERT SELECT語句填充新表格

    INSERT INTO newdatabasetable選擇*從olddatabasetable

MySQL將您的數據自動轉換成正確的字符集

方法2:改變你的表

如果更改字符集的現有表中,所有現有的內容將也要轉換成

例如

舊錶

CREATE TABLE `myWrongCharsetTable` (
    `name` varchar(255) COLLATE latin1_german1_ci NOT NULL DEFAULT '' 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; 

放入一些數據進行演示

INSERT INTO `myWrongCharsetTable` (`name`) VALUES ('I am a latino string'); 
INSERT INTO `myWrongCharsetTable` (`name`) VALUES ('Mein Name ist Müller'); 
INSERT INTO `myWrongCharsetTable` (`name`) VALUES ('Mein Name ist Möller'); 

SELECT * FROM myWrongCharsetTable INTO outfile '/tmp/mylatinotable.csv'; 

在一個UTF-8控制檯我這樣做

# cat /tmp/mylatinotable.csv 
I am a latino string 
Mein Name ist M▒ller 
Mein Name ist M▒ller 

正確的,奇怪的字符集..這是拉丁語1顯示在utf-8控制檯上

# cat /tmp/mylatinotable.csv | iconv -f latin1 -t utf-8 
I am a latino string 
Mein Name ist Müller 
Mein Name ist Möller 

是的,所有的好

所以我現在該如何解決這個問題?

ALTER TABLE myWrongCharsetTable 
    MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '', 
    DEFAULT CHARSET = utf8 COLLATE utf8_unicode_ci; 

就是這樣:)

編寫OUTFILE再次

mysql> SELECT * FROM myWrongCharsetTable INTO outfile '/tmp/latinoutf8.csv'; 
Query OK, 3 rows affected (0.01 sec) 

mysql> exit 
Bye 
dbmaster-001 ~ # cat /tmp/latinoutf8.csv 

I am a latino string 
Mein Name ist Müller 
Mein Name ist Möller 

的工作,所有的罰款,我們很高興

編輯:

有實際上是另一種方法,

方法3:轉儲,修改並重新加載數據

如果你用好sed和awk可以自動執行此,或編輯文件手動

# dump the structure, possibly routines and triggers 
mysqldump -h yourhost -p -u youruser --no-data --triggers --skip-comments --routines yourdatabase > database_structure_routines.sql 

# dump the data 
mysqldump -h yourhost -p -u youruser --no-create-info --skip-triggers --skip-routines yourdatabase > database_data.sql 

現在在打開database_structure_routines.sql編輯器根據您的需要修改表

我建議刪除/ *!40101 SET character_set_client = utf8 * /中的所有註釋,因爲這可能會覆蓋表格默認值

當你完成後,創建

mysql > CREATE DATABASE `newDatabase` DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci; 
mysql > use `newDatabase` 
mysql > ./database_structure_routines.sql; 

不要忘了重新檢查表

mysql > SHOW CREATE TABLE `table`; 

如果這是你可以重新導入數據的所有權利,字符集轉換又一個新的數據庫和結構會自動完成

mysql -h yourhost -p -u youruser newDatabase < database_data.sql 

希望這有助於

+0

非常感謝。我會嘗試的。 –

+0

增加了第三種方法,可能對你來說最簡單的方法,但也有一些方法搞砸:)無論哪種方式,首先創建一個備份! ;) –

+0

我已經執行了很多測試,所以備份不是問題。第三種方法與@ray相同,正如我告訴他的那樣,這將是最後的手段。但是,謝謝,斯蒂爾。 –

0

您可以嘗試使用CONVERT或CAST來更改字符集 - 創建一個新列並使用CAST來填充具有新校正字符集的新列。
http://dev.mysql.com/doc/refman/5.0/en/charset-convert.html

+0

正如我在問題中提到的那樣,出於某種奇怪的原因,alter table正在打破特殊字符 –

+0

對不起,讀得太快了。我用另一個想法編輯了我的答案。 – Aerik

2

我知道繼承由認爲「整理」是某種疾病形式的人創建的遺傳模式的樂趣。

最好的選擇是使用good ole'mysqldump將帶有數據的表導出到SQL轉儲文件。然後在轉儲文件中手動修改create語句以設置字符集和歸類。我是'utf8'的忠實粉絲。如果轉儲文件很大,請使用像sed這樣的命令行工具來高效編輯文件,而無需在編輯器中打開它。

然後刪除現有的表重新導入修改後的轉儲。

您以我的經驗做這件事的任何其他方式都可以是擲骰子。

這可能是將它們全部轉換爲相同存儲引擎的好時機,或者將MySQL服務器升級到5.5。

+0

我害怕不得不訴諸這樣的解決方案。數據庫中有很多表格.​​.....感謝回覆。 –

+0

@LeandroBarreto和大個子真的很爛。恭喜趕上熱土豆。 – Ray

+0

你拖延修複數據的時間越長,在你最終被迫這樣做之前就越糟糕。 –