表情符号字符搞乱了我们构建的加载系统,我正在寻找一个简单的短期解决方案。
它是一个Java加载程序,它使用JDBC来执行具有以下结构的MySQL命令:
LOAD DATA
LOCAL INFILE `filepath`
REPLACE INTO TABLE `SOME_TABLE`
CHARACTER SET utf8
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\'' ESCAPED BY ''
LINES TERMINATED BY '\n'
(`col1`,...,`coln`)
SOME_TABLE有ENGINE=InnoDB DEFAULT CHARSET=utf8
。
我们正在运行MySQL 5.6.22。
多年来它一直运行良好,但最近我们加载的文件开始偶尔出现非BMP字符(恰好是emojis)和LOAD DATA LOCAL INFILE ...命令会引发异常,如:
java.sql.SQLException: Incorrect string value: '\xF0\x9D\x93\x9C' for column 'fieldm' at row 3004
据我所知,长期解决方案是我们需要将表格移至CHARSET=utf8mb4
。但是,此时表格很大,转换并不容易。索引还有VARCHAR(255)
个字段,这些字段需要转换为VARCHAR(191)
[以适应最大密钥长度767],或者我们需要转到DYNAMIC行格式并设置innodb_large_prefix=true
。
我们正在寻找一个短期解决方案,直到我们有时间和资源迁移到utfmb4。
在短期内,可以简单地丢弃具有非BMP(表情符号)字符的行。但是,LOAD DATA LOCAL INFILE filepath REPLACE ...
不会跳过坏行,它会使整个文件失败。
此时,看起来我们需要在Java中编写一些过滤来删除非BMP(表情符号)行,然后再调用LOAD DATA LOCAL INFILE filepath REPLACE ...
。但是,我认为在MySQL中必须有一些方法可以做到这一点,而不必引入那种预过滤器。
有没有人想要一个简单的方法让MySQL简单地跳过那些包含非BMP(表情符号)数据的行?
*****更新***** 看起来使用CONVERT可能是短期解决方案。这样做会用'????'取代表情符号在col4。
LOAD DATA
LOCAL INFILE `filepath`
REPLACE INTO TABLE `SOME_TABLE`
CHARACTER SET utf8
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\'' ESCAPED BY ''
LINES TERMINATED BY '\n'
(`col1`,`col2`,`col3`,@q, ..., `coln`)
SET `col4` = CONVERT(CONVERT(@q USING utf8mb4) USING utf8);
有人看到有问题吗?
答案 0 :(得分:0)
为了存储表情符号,你必须使用utf8mb4,而不是utf8。
191索引问题的快捷方式(可能)是升级到5.7。在那里,你可以保留255 和有索引。
只有某些列会持有表情符号,对吗?只转换那些列。 (对于同一个表中的不同列,可以使用不同的字符集和/或排序规则。)