注册
达梦数据库汉字存储知多少
专栏/金的探索记录/ 文章详情 /

达梦数据库汉字存储知多少

2021/03/24 7286 11 3
摘要 达梦数据库汉字存储知多少

前言

当我们在 DM7 中处理汉字的时候,经常会用到 varchar 的数据类型。但是,根据数据库初始化时的参数不同,varchar 中能存储的汉字的个数也不尽相同。那么在每种情况下,字符的存储有什么区别呢?本文就将带大家一探究竟。

参数简介

在使用 DMINIT 初始化数据库的时候,我们有以下这两个跟字符集有关的参数,UNICODE_FLAG 和 LENGTH_IN_CHAR。

  • UNICODE_FALG

此参数表示了数据库中所有数据的字符集,包括数据字典的字符集。需要注意的是,数据库一旦初始化完成,字符集就将无法修改。我们可以使用 select unicode 来查询当前数据库的字符集种类,0 代表 gb18030,1 代表UTF-8。

  • LENGTH_IN_CHAR

此参数决定了,数据库中的 VARCHAR 类型对象的长度是否以字符为单位。取值为 1 则设置为以字符为单位,将存储长度值按照理论字符长度进行放大。取值为 0 则所有 VARCHAR 类型对象的长度以字节为单位。

同样,如果我们采用 DBCA 助手来创建数据库,也可以在初始化参数那一步来修改这两个参数的值。

1.png

测试

根据 Unicode 和 length_in_char 的取值不同(0 或 1),我们总共初始化四个不同的数据库,针对不同的情况进行测试。

本文演示环境: DM Database Server x64V7.1.6.48-Build(2018.03.01-89507)ENT

UNICODE_FLAG=0,LENGTH_IN_CHAR=0

根这种情况是初始化数据库时的默认配置,即字符集为 gb18030,varchar 长度以字节为单位。相关测试如下:

2.png

我们知道,gb18030 下一个汉字或者全角字符一般需要占用两个字节。所以 varchar(3) 型可以插入一个汉字加上一个半角字符,但是无法插入两个汉字。

UNICODE_FLAG=1,LENGTH_IN_CHAR=0

字符集为 utf-8,varchar 长度以字节为单位,相关测试如下:

3.png

Utf-8 的情况下,一个汉字一般需要占据三个字节,所以 varchar(3) 只能插入一个汉字。

UNICODE_FLAG=0,LENGTH_IN_CHAR=1

字符集为 utf-8,varchar 长度以字符为单位,测试如下:

4.png

我们知道在 length_in_char=1 的情况下,varchar 的实际可存储字节数会按一定比例放大。所以在使用 gb18030 的时候,varchar(3) 实际可以存储 3 个汉字,也就是 3*2=6 个字节的数据。

UNICODE_FLAG=1,LENGTH_IN_CHAR=1

字符集为 utf-8,varchar 长度以字符为单位:

5.png

这里我们会发现一个奇怪的情况,明明设置是 varchar(3),为什么可以插入 4 个汉字呢。这是因为在 DM7 中数据库实际存储数据是以字节为单位。在 lengtg_in_char=1 且字符集为 utf-8 的时候,VARCHAR 类型对象的实际存放的最大长度是 VARCHAR 类型定义的长度 *4 字节。

也就是说,这里一个 varchar(3) 的结构可以存放的数据为 3*4=12 个字节。然而事实上 UTF-8 中的一个汉字一般只用占用 3 个字节,所以这里我们可以插入 12/3=4 个汉字。

总结

当 LENGTH_IN_CHAR=0 的情况下,varchar() 的长度是以字节数为单位。这时我们只需要考虑汉字和全角字符所占用字节数,其中 gb18030 的一个汉字是两个字节,utf-8 的一个汉字一般是三个字节。如果插入数据的总字节数大于 varchar 定义的长度,则会插入失败。

当 LENGTH_IN_CHAR=1 的情况下,varchar() 所能存储的字节数将会按照一定比例扩展。字符集为 gb18030 时 varchar 的字节数等于定义长度 *2,字符集为 utf-8 时 varchar 的字节数为定义长度 *4。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服