GB18030(2000→2005→2022)
Unicode是自USC(ISO/IEC 10646)发展而来的国际标准字符集,它将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换。
E000至F8FF 私用区 Private Use Area(在 GB 18030-2000 的时代,有一些汉字还没有被 Unicode 标准正式收录,被收录到此区域)
4E00至9FFF 中日韩统一表意文字 CJK Unified Ideographs
F900至FAFF 中日韩兼容表意文字 CJK Compatibility Ideographs 解决历史遗留一字多码
GB 18030-2000,兼容 Unicode 3.0 中日韩统一表意文字,共收27533个汉字;
GB 18030-2005,更新至 Unicode 4.1 中日韩统一表意文字及增加少数民族文字,共有70244个汉字;
GB 18030-2022,更新至 Unicode 15中日韩统一表意文字及增加少数民族文字,共有87887个汉字;2024年10月补充了9793个汉字,使得该标准收录汉字达到97680个。
GB18030的设计思路可以概括到以下几点:
1单字节部分与Unicode一致。
2双字节部分与GBK兼容。适当调整一些字符与Unicode的映射。
这些字符原来因为Unicode没有收录而被映射到PUA,现在因为Unicode已经收录而调整到非PUA的Unicode码位。
3将Unicode BMP部分还没有映射的39420个码位顺序映射到从0x81308130开始的四字节部分。
4将Unicode BMP以外的16个辅助平面映射到39420个码位顺序映射到从0x90308130开始的四字节部分。
GB 18030-2022
GB18030码位分配
GB18030编码采用单字节、双字节和四字节三种方式对字符编码。
1单字节部分采用GB/T 11383的编码结构与规则,使用0x00至0x7F码位(对应ASCII码位)。
2双字节部分,首字节码位从0x81至0xFE,尾字节码位分别是0x40至0x7E和0x80至0xFE。
3四字节部分采用GB/T 11383未采用的0x30到0x39作为对双字节编码扩充的后缀,这样扩充的四字节编码,其范围为0x81308130到0xFE39FE39。其中第一、三个字节编码码位均为0x81至0xFE,第二、四个字节编码码位均为0x30至0x39。
1.GB18030作为服务端编码
1.1 为什么pg中GB18030不支持作为服务端编码?
1.1.1 GB18030 在pg中是ASCII不安全的编码
GB18030编码采用单字节、双字节和四字节三种方式对字符编码。
1单字节部分采用GB/T 11383的编码结构与规则,使用0x00至0x7F码位(对应ASCII码位)。
2双字节部分,首字节码位从0x81至0xFE,尾字节码位分别是0x40至0x7E和0x80至0xFE。
3四字节部分采用GB/T 11383未采用的0x30到0x39作为对双字节编码扩充的后缀,这样扩充的四字节编码,其范围为0x81308130到0xFE39FE39。其中第一、三个字节编码码位均为0x81至0xFE,第二、四个字节编码码位均为0x30至0x39。
目前,PostgreSQL 的 SQL 解析器,都假定了一个前提——字符串数据中的任何一个字节都不会与有特殊含义的 ASCII 字节相混淆。然而,由于 GB18030 编码的第二个和第四个字节的取值范围在 0x40 到 0x7E 之间(这与许多 ASCII 字符重叠),将会对后端造成混淆。
1.1.2 pg_wchar.h中pg_enc枚举编号限制
pg_wchar.h是PostgreSQL源码中负责多字节字符处理的核心头文件之一。其中定义了一个名为pg_enc的枚举类型,它的作用是为pg支持的每一种字符集分配一个唯一的整数ID作为内部使用
2. GB18030和UTF8的转换
2.1 转换的map文件从哪里来?
Map文件记录着gb18030和unicode的转换表,是通过perl脚本读取ICU维护的数据文件生成的。 数据文件分为三种,按时间先后顺序是txt,xml,ucm。
早期pg引入PG18030时,使用txt数据文件,后来更换为ICU组织维护的xml文件。因为xml文件为了提高转换效率,只列出了无规则需要查表的编码,有规则的大块连续区域使用偏移函数计算。
目前pg17在使用的是GB18030-2000.xml。ICU维护的GB18030-2005、2022版编码文件,因为xml格式无法表示一字双码,现在只维护ucm格式。
2. 修改GB18030编码的属性和函数
1)将GB18030的内部编码ID设置可作为为服务端编码 2)设置最大最小字节 3)设置wchar的转换函数,长度计算函数
https://www.cnblogs.com/shangdawei/archive/2013/05/07/3065496.html
OceanBase支持gb18030-2022:完整的.c数据文件
OpenGauss支持gb18030-2022:增加GB18030-2000基础上的新表,增加一个新的编码
工具: 汉字字符集编码查询
pg讨论: Retire GB18030 https://www.postgresql.org/message-id/flat/aC68DmpyYer87rau%40paquier.xyz
May “PostgreSQL server side GB18030 character set support” reconsidered? https://www.postgresql.org/message-id/flat/20201006.121142.2002518154310370203.t-ishii%40sraoss.co.jp#d9b9258c7d05c66e7252e76a7949110f