Php MySQL:不同的文本内容有不同的字符集,值得吗?

Php MySQL:不同的文本内容有不同的字符集,值得吗?,php,mysql,database-design,utf-8,character-encoding,Php,Mysql,Database Design,Utf 8,Character Encoding,我的数据库在所有表和所有char/varchar/text列中都使用utf8mb4。一切都很好,但我想知道我是否真的需要它的所有栏目。我的意思是,我有一些列将包含需要utf8mb4的用户文本,因为用户可以输入任何语言,插入表情符号,等等。但是,我有不同的列,其中包含其他类型的字符串,如用户访问令牌、国家代码、不包含奇怪字符的用户昵称等等 是否值得将这些列的字符集更改为ascii或latin1?它会提高数据库空间、效率吗?我的感觉是,为永远不包含unicode字符的内容设置utf84mb这样的字符

我的数据库在所有表和所有char/varchar/text列中都使用utf8mb4。一切都很好,但我想知道我是否真的需要它的所有栏目。我的意思是,我有一些列将包含需要utf8mb4的用户文本,因为用户可以输入任何语言,插入表情符号,等等。但是,我有不同的列,其中包含其他类型的字符串,如用户访问令牌、国家代码、不包含奇怪字符的用户昵称等等

是否值得将这些列的字符集更改为ascii或latin1?它会提高数据库空间、效率吗?我的感觉是,为永远不包含unicode字符的内容设置utf84mb这样的字符集是对“某物”的浪费。。。但我真的不知道MySQL是如何在内部管理这一点的

在另一端,我从php连接到这个数据库,并将连接字符集设置为uft8mb4,因此我假设所有非utf8列都将自动转换。我想这不是个问题,因为utf8是ascii或latin1的超集


有什么建议吗?赞成和反对?谢谢

简单的答案是将所有列和表默认设置为同一事物,即UTF-8

答案很长,是因为UTF-8的编码方式,其中ASCII将1:1映射到UTF-8,并且不会像UTF-16或UTF-32那样产生任何额外的存储开销,这不是什么大问题。如果存储非ASCII字符,则会占用更多空间,但如果存储这些字符,则无论如何都需要支持

在表中使用混合字符集只是自找麻烦。唯一的例外是定义非UTF-8而是二进制的
BINARY
BLOB
类型列时


甚至明确了唯一的问题是
CHAR
列,而不是
VARCHAR
,但首先使用
CHAR
列并不是一个好主意。

简单的答案是让所有列和表都默认为同一个东西,UTF-8

答案很长,是因为UTF-8的编码方式,其中ASCII将1:1映射到UTF-8,并且不会像UTF-16或UTF-32那样产生任何额外的存储开销,这不是什么大问题。如果存储非ASCII字符,则会占用更多空间,但如果存储这些字符,则无论如何都需要支持

在表中使用混合字符集只是自找麻烦。唯一的例外是定义非UTF-8而是二进制的
BINARY
BLOB
类型列时


甚至明确了唯一的问题是
CHAR
列,而不是
VARCHAR
,但首先使用
CHAR
列并不是一个好主意。

ASCII是UTF-8的严格子集,所以,如果您没有使用UTF-8中存储的特殊字符,那么在空间效率方面就完全没有增益。如果使用拉丁语-1而不是UTF-8来存储拉丁语派生文本(UTF-8使用2个字节的特殊字符可以仅使用拉丁语-1中的一个字节来存储),则在空间效率方面会有轻微的提高,但这样做会带来很多麻烦,并且会失去与更广泛字符集的兼容性

例如,ñ在UTF-8中存储为
0xC3 0xB1
,而拉丁语-1将其存储为
0xF1
。另一方面,a在两种编码中都是
0x61
。发明UTF8的聪明人就是这样做的。只为特殊字符保存一个字节


TL;DR在任何情况下都使用UTF-8。如果你不得不问,你不需要其他任何东西。

ASCII是UTF-8的一个严格子集,因此如果你没有任何使用UTF-8中存储的特殊字符的东西,那么在空间效率上的增益就完全为零。如果使用拉丁语-1而不是UTF-8来存储拉丁语派生文本(UTF-8使用2个字节的特殊字符可以仅使用拉丁语-1中的一个字节来存储),则在空间效率方面会有轻微的提高,但这样做会带来很多麻烦,并且会失去与更广泛字符集的兼容性

例如,ñ在UTF-8中存储为
0xC3 0xB1
,而拉丁语-1将其存储为
0xF1
。另一方面,a在两种编码中都是
0x61
。发明UTF8的聪明人就是这样做的。只为特殊字符保存一个字节


TL;DR在任何情况下都使用UTF-8。如果你不得不问,你不需要其他任何东西。

Utf8非常小,当字符集是拉丁-1时,你失去了多字节的选择以获得很少的收益。优点非常少,它只会让你在以后编码时更头疼,所以不要做。F-8是ASCII的超集,所以x00-x7F范围内的任何文本都是单字节。它在ASCII、拉丁语-1或UTF-8中占用相同的空间量。将特定字段(列)从UTF-8更改为ASCII或拉丁语-1是不值得的,特别是如果这已经在生产中使用。就处理时间而言,您可能会在UTF-8字段上花费更多的时间(需要检查多字节字符),但这不应该是一个大问题,你失去了多字节的选择,只能获得很少的收益。优点是非常少的,它只会给你以后的编码带来更多的麻烦,所以不要这样做,因为F-8是ASCII的超集,所以x00-x7F范围内的任何文本都是单字节的。它在ASCII、拉丁语-1或UTF-8中占用相同的空间量。将特定字段(列)从UTF-8更改为ASCII或拉丁语-1是不值得的,特别是如果这已经在生产中使用。就处理时间而言,您可能会在UTF-8字段上花费更多的时间(需要检查多字节字符),但这不应该是一个大的成功。