我有一个相当大的数据库,我正在尝试将字符集和排序规则latin1/latin1_swedish_ci
转换为utf8mb4/utf8mb4_unicode_ci
。我希望设置复制到从站,运行转换,然后在完成时提升从站,以避免停机。
我注意到在运行查询时...
ALTER TABLE `sometable` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
... MySQL自动将text
转换为mediumtext
或mediumtext
转换为longtext
等。
有没有办法关闭此功能? MySQL有这个功能很好,但问题是它打破了复制,因为从机上的表结构与主机不同。
答案 0 :(得分:4)
正如ALTER TABLE
Syntax所述:
对于数据类型为
VARCHAR
或其中一种TEXT
类型的列,CONVERT TO CHARACTER SET
会根据需要更改数据类型,以确保新列的长度足以支持存储与原始列一样多的字符。例如,TEXT
列有两个长度字节,用于存储列中值的字节长度,最大值为65,535。对于latin1
TEXT
列,每个字符都需要一个字节,因此该列最多可以存储65,535个字符。如果列转换为utf8
,则每个字符最多可能需要三个字节,最大可能长度为3×65,535 = 196,605字节。该长度不适合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;
答案 1 :(得分:0)
(不是一个真正的答案,而是一些说明性的例子。)
案例1:文本在latin1列中正确存储为latin1;使用CONVERT TO
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;使用" Double ALTER"
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
案例3:文本错误地存储为latin1列中的utf8;使用" Double 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 ... MODIFY;注意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)
注意: