我觉得我还不明白这一点令人气愤,但也许一些解释会有所帮助。这是一个由两部分组成的问题,但希望这两部分都很小并且直接相关:
展示
我们最近遇到了一个问题,即内容将U+00a0
(不间断空格)字符插入到带有latin1
字符集的 DB 列中。只需在SELECT
列中打印出“”。我不确定这是选择的产物还是显示器的产物,但我相信是前者。 SELECT BINARY col
而是打印出“”,因为我的外壳有$LANG = en_US.utf8
.
一个更明显的例子是“â„¢”与“™”
使用SELECT CONVERT(col USING utf8)
仍然会打印出“”和“â„¢”——我不一定期望它会有所不同,但问题出在哪里?是存储时出现的问题吗?有没有办法从数据库中获取 UTF8 显示,而不是依赖 UI 来正确显示它(如果这有意义的话?)
贮存
为了自己重现此问题,我执行了以下操作:
CREATE TABLE chrs (
lat varchar(255) charset latin1,
utf varchar(255) charset utf8
);
INSERT INTO chrs VALUES ('™', '™');
INSERT INTO chrs VALUES (' ', ' '); -- U+00a0
但是,这会导致:
> SELECT * FROM chrs;
+------+------+
| lat | utf |
+------+------+
| ™ | ™ |
| | |
+------+------+
我希望lat
显示“”和“â„¢”,所以显然有些东西我不明白。
更重要的是:
> SELECT BINARY lat, BINARY utf FROM chrs;
+------------+------------+
| BINARY lat | BINARY utf |
+------------+------------+
| � | ™ |
| � | |
+------------+------------+
这表明这些值被不正确地 (?) 存储到lat
.
我注意到那SELECT @@character_set_client
是utf8
,所以我将其更改为latin1
并再次插入空格,但这会产生
| Â | Â |
对于两列。 SELECT BINARY lat
正确显示空格,但SELECT binary utf8
仍打印出“Â.” 我希望该utf8
列能够更正确地工作。
总结一下:
- 当您插入字符时,MySQL 实际上对字符做了什么?它是否取决于列字符集、客户端集、两者或其他?
- 由于上述不匹配,是否有可能在插入时搞砸数据?或者是否总是可以恢复最初插入的数据?
charset
列上的 实际对存储/显示有什么作用?