暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

最佳实践 | 告别乱码!GB18030字符集应用全攻略

GaussDB DWS 2025-08-15
982

01




前言
  • 适用版本:【9.1.1(及以上)】

  • 解决gbk字符集的因为字符范围不足导致生僻字和少数民族文字无法识别

  • 满足《信息技术产品国家通用语言文字使用管理规定》强制要求

02




GB18030编码介绍

2.1 编码结构与原理

2.1.1 多字节编码体系

GB18030采用1/2/4字节变长编码结构:

字节数编码范围字符类型

1字节

0x00-0x7F

ASCII兼容字符

2字节

0x81-0xFE 0x40-0x7E/0x80-0xFE

基本汉字区(20902字)

4字节

0x81-0xFE 0x30-0x39 0x81-0xFE 0x30-0x39

扩展区(70,000+汉字)

2.1.2 编码示例

常用汉字编码示例

    2.2 标准演进与版本对比

    2.2.1 各版本核心差异

    特性GB18030-2000GB18030-2005GB18030-2022

    汉字数量

    27,533

    70,244

    87,887

    支持Unicode版本

    3.0

    4.0

    11.0

    新增字符

    CJK扩展A

    CJK扩展B

    CJK扩展C-G

    少数民族文字

    基本支持

    增强支持

    完整支持

    部首支持

    228部首

    2.2.2 汉字覆盖范围

    2.3 GB18030 vs GBK

    2.3.1 技术差异矩阵

    维度GBKGB18030

    编码空间

    23940字符

    160万+字符

    字节结构

    固定双字节

    1/2/4字节变长

    Unicode映射

    部分支持

    完全支持

    生僻字支持

    < 10% (如"")

    100%覆盖

    少数民族文字

    不支持

    完整支持(苗文、傈僳文等)

    Emoji支持

    完整支持(😊✅🔥)

    2.4 DWS对GB18030的完整支持

    2.4.1 支持范围

    • 字符集:完整支持87,887汉字+228部首

    • 少数民族文字:

      • 滇东北苗文 (U+16F00-U+16F9F)

      • 傈僳文 (U+A4D0-U+A4FF)

      • 西夏文 (U+17000-U+187FF)

    • 特殊符号:

      • 易经八卦符号 (U+4DC0-U+4DFF)

      • 太玄经符号 (U+1D300-U+1D35F)

      • 麻将牌符号 (U+1F000-U+1F02F)

    03




    环境配置与基本操作

    3.1 数据库创建最佳实践

    3.1.1 完整建库语句

    CREATE DATABASE gb18030_db
        ENCODING = 'GB18030'
        LC_COLLATE = 'zh_CN.GB18030'
        LC_CTYPE = 'zh_CN.GB18030'
        DBCOMPATIBILITY = 'TD'
        TEMPLATE = template0;

    3.1.2 参数详解

    LC_COLLATE:指定数据库使用的字符集。例如,gbk编码通过lc_collate=‘zh_CN.gbk’,utf8通过lc_collate=‘en_us.utf8’,gb18030/gb18030-2022通过lc_collate=‘zh_CN.GB18030’。该参数的使用会影响到对字符串的排序顺序,可以通过查pg_collate表找到对应编码的lc_collate。

    LC_CTYPE:指定新数据库使用的字符分类。例如,通过lc_ctype = 'zh_CN.gbk’设定该参数。该参数的使用会影响到字符的分类,如大写、小写和数字。默认是使用模板数据库的字符分类。

    ENCODING:指定数据库字符集

    DBCOMPATIBILITY:兼容Teradata语法

    3.2 表与字段级配置

    3.2.1 创建支持GB18030的表

    -- 普通表
    CREATETABLEusers (
        idSERIAL PRIMARY KEY,
        nameVARCHAR(50NOTNULLCOLLATE"zh_CN.gb18030",
        id_card CHAR(18COLLATE"zh_CN.gb18030"
    );

    -- 分区表示例
    CREATETABLE census_data (
        region_code CHAR(6),
        family_name VARCHAR(20COLLATE"zh_CN.gb18030",
        population INT
    PARTITIONBYrange(population)
    (PARTITION p1 START(1END(10) EVERY(1));

    3.2.2 列级Collation设置

    -- 为特定列设置排序规则
    ALTERTABLEusers
    ALTERCOLUMNnameTYPEVARCHAR(50COLLATE"zh_CN.gb18030";

    -- 查询当前collation配置
    SELECT a.attname, c.collname 
    FROM pg_attribute a
    JOIN pg_collation c ON a.attcollation = c.oid
    WHERE a.attrelid = 'users'::regclass;

    04




    应用场景详解

    4.1 生僻字处理

    生僻字插入与查询

    -- 创建测试表
    CREATETABLE rare_characters (
        idSERIAL PRIMARY KEY,
        characterTEXTCOLLATE"zh_CN.gb18030",
        unicode_point VARCHAR(10)
    );

    -- 插入生僻字示例
    INSERTINTO rare_characters (character, unicode_point) VALUES
    ('䶮''U+4DAE'), -- GB18030编码: 0x9835FC39
    ('𰾅''U+30F85'),-- CJK扩展G区
    ('''U+31350'); -- 傈僳文字符

    -- 查询验证
    SELECT * FROM rare_characters 
    WHEREcharacter = '䶮';

    ```sql
    INSERTINTO t_gb18030 ('䶮');
    INSERT0 1

    4.2 GDS数据迁移全流程

    完整GDS导入流程

     -- 1. 启动GDS服务
    gds -d data/gds_dir -p ip:port -H address_string -l log_file -D -t worker_num

    -- 2. 创建外部表
    CREATEFOREIGNTABLE gb18030_import (
        idINT,
        full_name TEXT,
        address TEXT
    SERVER gsmpp_server OPTIONS (
        location 'gsfs://ip:port/filepwd',
        format'text',
        delimiter '|',
        encoding'GB18030',
        compatible_illegal_chars 'true',
        replace_illegal_chars '',
        fill_missing_fields 'true',
        ignore_extra_data 'true',
        noescaping 'on'
    );

    -- 3. 导入目标表
    CREATETABLE citizens AS
    SELECT * FROM gb18030_import;

    -- 4. 验证数据
    SELECTcount(*) FROM citizens;
    SELECT * FROM citizens WHERE full_name LIKE'%䶮%';

    -- 5. 数据导出
    CREATEFOREIGNTABLE gds_out
    (
        a intnotnull,
        b text;
        c text;
    )SERVER gsmpp_server
        OPTIONS(location 'gsfs://ip:port',
        format 'text',
        delimiter ',',
        compatible_illegal_chars 'True',
        REPLACE_ILLEGAL_CHARS ' '
    ) WRITE ONLY;

    INSERTINTO gds_out SELECT * FROM t1 ORDERBY a;

    4.3 字符函数应用

    4.3.1 编码转换函数

    -- 二进制转文本
    SELECT convert_from('\x8149''GB18030'AS chinese_char; -- 输出:'両'

    -- 文本转二进制
    SELECT convert_to('华为''GB18030'AS byte_stream; -- 输出:\xBBAACC

    -- 编码间转换
    SELECT convert('\x8149''GB18030''UTF8'AS utf8_bytes;

    4.3.2 字符串处理函数

    -- 获取字符数(非字节数)
    SELECTchar_length('中文䶮'); -- 返回3(3个字符)

    -- 按字符截取
    SELECTsubstring('中国䶮云南'32); -- 返回'䶮云'

    -- 四字节字符处理
    SELECT overlay('ABCDEF'
                   PLACING '䶮'
                   FROM3FOR2); -- 返回'AB䶮EF'

    05




    常见问题

    Q1:如何检查数据库当前字符集?

    -- 查看数据库编码
    SELECT datname, pg_encoding_to_char(encoding
    FROM pg_database;
    SHOW service_encoding;

    -- 查看客户端编码
    SHOW client_encoding;

    Q2:插入时遇到"invalid byte sequence"错误?
    该字符的码位不支持。


    往期精彩回顾



    恭喜!大数据“星河”标杆案例奖+

    中国实时湖仓市场,华为云位居领导者类别

    华为云入选Gartner®云数据库挑战者象限

    广州供电计量自动化系统3.0正式上线

    最佳实践 | 打破方言壁垒!sql_dialect插件实现SQL自由兼容

    最佳实践 | GaussDB(DWS) 查询过滤器:让烂SQL无处遁形



    戳阅读原文,了解更多

    文章转载自GaussDB DWS,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论