javascript - 多字节字符占用的字符数在 JavaScript 和 MySQL 中是不同的

标签 javascript mysql unicode encoding

最近,我在测试使用 MySQL 的后端系统时遇到了一个奇怪的行为。

在我的前端,当我打印一个字符串的长度时,我得到了一个与 MySQL 不同的值。

为了测试,我使用了 0123456789😀🤷🏻‍♀️ 表情符号来检查字符串的长度。

Javascript(在浏览器控制台中):

> "🤷🏻‍♀️".length
<- 7
> "😀".length
<- 2
> "0123456789".length
<- 10

enter image description here

MySQL(使用 MySQL Workbench):

CREATE TABLE testing_char_length 
  ( 
     id  INT auto_increment PRIMARY KEY, 
     txt VARCHAR(10) 
  ) 
DEFAULT charset utf8mb4; 

INSERT INTO testing_char_length 
            (txt) 
VALUES     ('0123456789'), 
            ('😀'), 
            ('🤷🏻‍♀️'); 

SELECT *, 
       Char_length(txt) NumberOfChars, 
       Length(txt)      SizeInBytes 
FROM   testing_char_length; 

DROP TABLE testing_char_length; 

输出:

| id    | txt           | NumberOfChars     | SizeInBytes   |
|----   |------------   |---------------    |-------------  |
| 1     | 0123456789    | 10                | 10            |
| 2     | 😀            | 1                 | 4             |
| 3     | 🤷🏻‍♀️            | 5                 | 17            |

enter image description here


最初我认为这可能是由于一些编码问题。因此,尝试搜索 Javascript 和 MySQL 使用的编码。

Javascript uses UTF-16

因此,我还尝试将 MySQL 编码设置为 utf16 以确保它不是罪魁祸首,即使在使用 default charset utf16 之后,输出也与utf8mb4.

为什么 Javascript 和 MySQL 的字符数不同?

我敢肯定,有些事情我到现在还没有遇到过,希望能得到一些关于这种行为的答案。

测试于:

Google Chrome 版本 81.0.4044.122(正式版)(64 位)

MySQL 工作台:8.0.19

MySQL:8.0.19

操作系统:macOS Catalina 版本 10.15.3


更新:1

字符串"0123456789"的HEX码在JS和MySQL中都是一样的。其他两个不一样。

JS Fiddle for Hex values 。计算HEX的代码取自here

JS Hex values

MySQL Fiddle for Hex values (摘自评论 below )

MySQL Hex values

即使编码相同,为什么十六进制值不同? UTF 编码不应该是通用的和相同的吗?

最佳答案

如您所见,您的应用程序语言使用的是 UTF-16,而 MySQL 使用的是它的 utf8mb4(也称为 UTF-8)。

UTF-8、UTF-16 和 UTF-32 具有不同的十六进制表示形式,可能有不同数量的字节和“字符”,但可以相互转换。

在“BMP”中,16 位字符在utf8 中可以用3 个字节表示,在utf16 中可以用2 个字节表示。除此之外,utf8 达到 4 个字节(1 个字符),而 utf16 达到 4 个字节(2 个字符)。第二个字符表示“ panic ,我们超过了 16 位,我们需要一些东西来扩展字符集”。

utf8 可能达到 5 个字节,但此类字符尚未标准化。

关于javascript - 多字节字符占用的字符数在 JavaScript 和 MySQL 中是不同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61808621/

相关文章:

javascript - div 拖在一起而不是分开

javascript - 当我自己引起 Angular $watch 事件时,如何忽略它?

MySQL - 如何有效地获取 ID 最低的行?

php - 使用session返回消息只返回一条消息

python - 在 python 中绘制盒子

javascript - 用于一个祖先的多个元素的 JQuery 选择器

javascript - 通过 POST ajax 调用下载文件

python Mysql数据存储

python - 如何在 python 3 中生成希伯来语字符串?

javascript - csv export with symbol # as content 导出结束