web-dev-qa-db-ja.com

すべての行の照合順序をlatin1_swedish_ciからutf8_unicode_ciに変更するにはどうすればよいですか?

開発中にデータベース内のすべてのvarchar行にデフォルトのlatin1_swedish_ci文字エンコーディングを無意識に使用しましたが、これが私が抱えている文字エンコーディングの問題の原因であると判断しました。それに加えて、最近のほとんどの人はutf8_unicode_ciの使用を推奨しているようです。

データベース内のすべての行の文字エンコードをlatin1_swedish_ciからutf8_unicode_ciに変換したいのですが、phpMyAdminで行ごとに変更する方法しかありません。これは本当に時間がかかります。

すべてのvarchar/text行の照合をlatin1_swedish_ciからutf8_unicode_ciに変更する実行可能なクエリなど、より高速な方法はありますか?

20
Nate

列がデフォルトのテーブル文字セットを使用している場合、変換するのはテーブルごとに1つのクエリだけです。

ALTER TABLE t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

文字セットが各列で個別に設定されている場合、AFAIKでは、データベース内のすべてのテーブルのすべての列に対してMySqlで直接設定する方法はありませんが、選択した言語で小さなプログラムを作成することができます。

プログラムは INFORMATION_SCHEMA.COLUMNS テーブルをクエリし、CHARACTER_SET_NAME列を確認します。

SELECT * FROM `INFORMATION_SCHEMA.COLUMNS`
WHERE TABLE_SCHEMA = 'dbname' AND CHARACTER_SET_NAME = 'latin1'

結果行ごとに、文字セットと照合順序を適切に変更するALTER TABLEクエリをその場で合成して実行することは簡単です。

ALTER TABLE t MODIFY col TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

上記のクエリでは、tcolおよびTEXTは、TABLE_NAME結果セットのCOLUMN_NAMEDATA_TYPEおよびINFORMATION_SCHEMA.COLUMNS列の値になります。

40
Jon

これは実際には、プロシージャを使用してMySQL内で実行できます。

https://stackoverflow.com/a/12718767/161227 に基づいています。現在のデータベースを使用しているため、正しいデータベースで実行していることを確認してください。

delimiter //

DROP PROCEDURE IF EXISTS convert_database_to_utf8 //

CREATE PROCEDURE convert_database_to_utf8()
BEGIN
    DECLARE table_name VARCHAR(255);
    DECLARE done INT DEFAULT FALSE;

    DECLARE cur CURSOR FOR
        SELECT t.table_name FROM information_schema.tables t WHERE t.table_schema = DATABASE() AND t.table_type='BASE TABLE';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
        tables_loop: LOOP
            FETCH cur INTO table_name;

            IF done THEN
                LEAVE tables_loop;
            END IF;

            SET @sql = CONCAT("ALTER TABLE ", table_name, " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
            PREPARE stmt FROM @sql;
            EXECUTE stmt;
            DROP PREPARE stmt;
        END LOOP;
    CLOSE cur;
END //

delimiter ;
call convert_database_to_utf8();
9
arnoud