2016-05-20 25 views
0

私は、文字セットと照合latin1/latin1_swedish_ciからutf8mb4/utf8mb4_unicode_ciに変換しようとするかなり大きなデータベースを持っています。私は、スレーブへのレプリケーションをセットアップし、変換を実行してから、ダウンタイムを避けるためにスレーブをプロモートすることを望んでいます。 構造変更なしでMySQLをUTF8に変換する

は私が気づいたクエリを実行しているときに...

ALTER TABLE `sometable` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 

... MySQLは自動的に変換しtextmediumtextまたはlongtextmediumtextなど

オフこの機能を有効にする方法はあります? MySQLにはこの機能がありますが、スレーブ上のテーブルの構造がマスターと異なるため、レプリケーションが壊れるという問題があります。

+0

私はここでこれについての話題を覚えていて、文字セットを 'BLOB' *にしてから' UTF8mb4'文字セットにすることの中間点がありましたが、私の記憶はこの点で不十分です。また、それが何に変わるかは重要ですか?それは私が知っている限り、データの長さにのみ影響するので、単純にALTERテーブルに変換して中文字をあなたが望むものに変更してください...(?) – Martin

+0

'mediumtext'か' text'かどうかは関係ありません。重要なのはそれが変わらないということです。マスター→スレーブレプリケーションの設定があり、最初にスレーブで変換を実行したい場合、マスターが新しいデータをスレーブに挿入しようとすると、レプリケーションは中断します。 2つのテーブルの構造は同じではありません。 –

+1

私が正しく覚えていれば、MySQLがテキストサイズを拡張する理由は、 'utf8mb4'が3バイトではなく1文字あたり4バイトを使用するためです。' latin1_'に最大文字数があれば、オーバーフローして同じバイトサイズのコンテナ'utf8mb4'で – Martin

答えて

2

ALTER TABLE Syntax下で文書化されるように:VARCHAR又はTEXTタイプのいずれかのデータ型を持つカラムについて

CONVERT TO CHARACTER SET新しい列がするのに十分な長さであることを保証するために必要に応じて、データ型を変更します元の列と同じ数の文字を格納します。たとえば、TEXT列には2つの長さのバイトがあり、列の値のバイト長を最大65,535まで格納します。 latin1TEXT列の場合、各文字には1バイトが必要なため、列には65,535文字まで格納できます。列がutf8に変換された場合、可能な最大長は3×65,535 = 196,605バイトで、各文字は最大3バイト必要です。その長さはTEXTカラムの長さバイトに収まらないため、MySQLはデータタイプをMEDIUMTEXTに変換します。これは、長さバイトが196,605という値を記録できる最小の文字列タイプです。同様に、VARCHAR列はMEDIUMTEXTに変換される可能性があります。

このタイプのデータ型の変更を避けるには、CONVERT TO CHARACTER SETを使用しないでください。代わりに、MODIFYを使用して個々の列を変更してください。たとえば、次のように

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8; 
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;
0

ケース1(そうでもない答えが、いくつかの例示的な実施例):テキストが正しくLATIN1でlatin1の列として保存されています。

mysql>  CREATE TABLE alters (
    ->   c VARCHAR(11) CHARACTER SET latin1 NOT NULL 
    -> ); 

mysql>  INSERT INTO alters (c) VALUES ('aabc'), (UNHEX('61e06263')), (UNHEX('61e16263')); 

mysql>  SELECT c, HEX(c) from alters; 
+-------+----------+ 
| c  | HEX(c) | 
+-------+----------+ 
| aabc | 61616263 | 
| aàbc | 61E06263 | 
| aábc | 61E16263 | 
+-------+----------+ 

mysql>  ALTER TABLE alters CONVERT TO CHARACTER SET utf8; 

mysql>  SELECT c, HEX(c) from alters; 
+-------+------------+ 
| c  | HEX(c)  | 
+-------+------------+ 
| aabc | 61616263 | 
| aàbc | 61C3A06263 | 
| aábc | 61C3A16263 | 
+-------+------------+ 

mysql>  -- Observation: text was correctly converted to utf8. 

mysql>  SHOW CREATE TABLE alters\G 
Create Table: CREATE TABLE `alters` (
    `c` varchar(11) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

ケース2への変換を使用:テキストが正しくはlatin1でlatin1の列として保存されています。 "ダブルALTER" 3

mysql>  CREATE TABLE alters (
    ->   c VARCHAR(11) CHARACTER SET latin1 NOT NULL 
    -> ); 

mysql>  INSERT INTO alters (c) VALUES ('aabc'), (UNHEX('61e06263')), (UNHEX('61e16263')); 

mysql>  ALTER TABLE alters MODIFY c VARBINARY(11) NOT NULL; 

mysql>  ALTER TABLE alters MODIFY c VARCHAR(11) CHARACTER SET utf8 NOT NULL; 
Query OK, 3 rows affected, 2 warnings (0.10 sec) 
Records: 3 Duplicates: 0 Warnings: 2 

mysql>  SHOW WARNINGS; 
+---------+------+----------------------------------------------------------+ 
| Level | Code | Message             | 
+---------+------+----------------------------------------------------------+ 
| Warning | 1366 | Incorrect string value: '\xE0bc' for column 'c' at row 2 | 
| Warning | 1366 | Incorrect string value: '\xE1bc' for column 'c' at row 3 | 
+---------+------+----------------------------------------------------------+ 

mysql>  SELECT c, HEX(c) from alters; 
+------+----------+ 
| c | HEX(c) | 
+------+----------+ 
| aabc | 61616263 | 
| a | 61  | 
| a | 61  | 
+------+----------+ 

mysql>  -- Observation: text was truncated ! BAD 

mysql>  SHOW CREATE TABLE alters\G 
Create Table: CREATE TABLE `alters` (
    `c` varchar(11) CHARACTER SET utf8 NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

ケース使用:テキストが誤っ latin1の列でUTF8として格納されだったが、修正するために「ダブルALTERを使用して

mysql>  CREATE TABLE alters (
    ->   c VARCHAR(11) CHARACTER SET latin1 NOT NULL 
    -> ); 

mysql>  INSERT INTO alters (c) VALUES ('aabc'), (UNHEX('61c3a06263')), (UNHEX('61c3a16263')); 

mysql>  ALTER TABLE alters MODIFY c VARBINARY(11) NOT NULL; 
mysql>  ALTER TABLE alters MODIFY c VARCHAR(11) CHARACTER SET utf8 NOT NULL; 

mysql>  SELECT c, HEX(c) from alters; 
+-------+------------+ 
| c  | HEX(c)  | 
+-------+------------+ 
| aabc | 61616263 | 
| aàbc | 61C3A06263 | 
| aábc | 61C3A16263 | 
+-------+------------+ 

mysql>  SHOW CREATE TABLE alters\G 
Create Table: CREATE TABLE `alters` (
    `c` varchar(11) CHARACTER SET utf8 NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

ケース4:ALTERを使用して...修正する。私はSHOWをした一つのケースを除いて

  • ません警告:LENGTHとCHAR_LENGTH

    mysql>  CREATE TABLE alters (
        ->   c VARCHAR(9) CHARACTER SET latin1 NOT NULL 
        -> ); 
    
    mysql>  INSERT INTO alters (c) VALUES ('aabc'), (UNHEX('61e06263')), 
        ->     (UNHEX('61e16263')), 
        ->     (UNHEX('61e162633536373839')); 
    
    mysql>  SELECT c, HEX(c), LENGTH(c), CHAR_LENGTH(c) from alters; 
    +------------+--------------------+-----------+----------------+ 
    | c   | HEX(c)    | LENGTH(c) | CHAR_LENGTH(c) | 
    +------------+--------------------+-----------+----------------+ 
    | aabc  | 61616263   |   4 |    4 | 
    | aàbc  | 61E06263   |   4 |    4 | 
    | aábc  | 61E16263   |   4 |    4 | 
    | aábc56789 | 61E162633536373839 |   9 |    9 | 
    +------------+--------------------+-----------+----------------+ 
    
    mysql>  ALTER TABLE alters MODIFY c VARCHAR(9) CHARACTER SET utf8 NOT NULL; 
    
    mysql>  SELECT c, HEX(c), LENGTH(c), CHAR_LENGTH(c) from alters; 
    +------------+----------------------+-----------+----------------+ 
    | c   | HEX(c)    | LENGTH(c) | CHAR_LENGTH(c) | 
    +------------+----------------------+-----------+----------------+ 
    | aabc  | 61616263    |   4 |    4 | 
    | aàbc  | 61C3A06263   |   5 |    4 | 
    | aábc  | 61C3A16263   |   5 |    4 | 
    | aábc56789 | 61C3A162633536373839 |  10 |    9 | 
    +------------+----------------------+-----------+----------------+ 
    
    mysql>  SHOW CREATE TABLE alters\G 
    Create Table: CREATE TABLE `alters` (
        `c` varchar(9) CHARACTER SET utf8 NOT NULL 
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 
    1 row in set (0.00 sec) 
    

    注意事項に注意してください。

  • デフォルトテーブルCHARSETは変更されていませんが、問題はありません。
関連する問題