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

【学习笔记】mogdb管理指南---字符集支持

原创 哇哈哈 2022-11-26
600

字符集支持

MogDB支持以各种字符集(也称为编码)存储文本,包含单字节字符集,比如ISO-8859系列,和多字节字符集,比如EUC(扩展Unix编码)、UTF-8、Mule国际编码。所有支持的字符集都可以被客户端透明地使用,但有一些不支持在服务器内使用(即作为服务器端的编码)。缺省字符集是在使用gs_initdb初始化数据库集群时选择的。创建数据库时可以重写此缺省值。因此,您可以创建多个具有不同字符集的数据库。

但是,存在一个重要的限制,每个数据库的字符集必须与该数据库的LC_CTYPE(字符类别)以及 LC_COLLATE(字符串排序顺序)区域设置相兼容。对于C或者 POSIX区域,允许使用任意字符集, 但对于其他区域则只有设置某一个字符集时能正常运行。(不过在Windows上,UTF-8编码可用于任何区域。)

支持的字符集

表1显示了可以在MogDB中使用的字符集。

表1 MogDB字符集

名称描述语言服务器端是否支持字节数/字符别名
BIG5大五码繁体中文1-2WIN950Windows950
EUC_CN扩展UNIX代码-CN简体中文1-3
EUC_JP扩展UNIX代码-JP日文1-3
EUC_JIS_2004扩展UNIX代码-JP, JIS X 0213日文1-3
EUC_KR扩展UNIX代码-KR韩文1-3
EUC_TW扩展UNIX代码-TW繁体中文,台湾1-3
GB18030国标码中文1-2
GBK扩展国标码简体中文1-2WIN936Windows936
ISO_8859_5ISO 8859-5, ECMA 113拉丁/西里尔语1
ISO_8859_6ISO 8859-6, ECMA 114拉丁/阿拉伯语1
ISO_8859_7ISO 8859-7, ECMA 118拉丁/希腊语1
ISO_8859_8ISO 8859-8, ECMA 121拉丁/希伯莱语1
JOHABJOHAB韩语1-3
KOI8RKOI8-R西里尔语(俄国)1KOI8
KOI8UKOI8-U西里尔语(乌克兰)1
LATIN1ISO 8859-1, ECMA 94西欧语1ISO88591
LATIN2ISO 8859-2, ECMA 94中欧语1ISO88592
LATIN3ISO 8859-3, ECMA 94南欧语1ISO88593
LATIN4ISO 8859-4, ECMA 94北欧语1ISO88594
LATIN5ISO 8859-9, ECMA 128土耳其语1ISO88599
LATIN6ISO 8859-10, ECMA 144日耳曼语1ISO885910
LATIN7ISO 8859-13波罗的海语1ISO885913
LATIN8ISO 8859-14凯尔特语1ISO885914
LATIN9ISO 8859-15带有欧洲语系和语调的LATIN11ISO885915
LATIN10ISO 8859-16, ASRO SR 14111罗马尼亚语1ISO885916
MULE_INTERNALMule internal code多语种Emacs1-4
SJISShift JIS日语1-2MskanjiShiftJISWIN932Windows932
SHIFT_JIS_2004Shift JIS, JIS X 0213日语1-2
SQL_ASCIIunspecified (see text)任意1
UHCUnified Hangul Code韩语1-2WIN949Windows949
UTF8Unicode, 8-bit全部1-4Unicode
WIN866Windows CP866西里尔语1ALT
WIN874Windows CP874泰国语1
WIN1250Windows CP1250中欧语1
WIN1251Windows CP1251西里尔语1WIN
WIN1252Windows CP1252西欧语1
WIN1253Windows CP1253希腊语1
WIN1254Windows CP1254土耳其语1
WIN1255Windows CP1255希伯来语1
WIN1256Windows CP1256阿拉伯语1
WIN1257Windows CP1257波罗的语1
WIN1258Windows CP1258越南语1ABCTCVNTCVN5712VSCII

并非所有API都支持上面列出的编码。SQL_ASCII设置与其它设置不同。如果服务器字符集是SQL_ASCII,服务器根据ASCII标准解析0-127的字节值,而字节值为128-255的则当作未解析的字符。如果设置为SQL_ASCII就不会有编码转换。因此,这个设置基本不用来声明所使用的编码,因为此声明会忽略编码。在大多数情况下,如果使用了任何非ASCII数据,那么我们不建议使用SQL_ASCII,因为MogDB无法转换或者校验非ASCII字符。

设置字符集

gs_initdb可以为一个MogDB集群定义缺省字符集(编码),详细说明请参见gs_initdb

您也可以通过SQL语句在数据库创建时指定非缺省编码,但是指定的编码必须与所选的区域相兼容:

CREATE DATABASE chinese WITH ENCODING 'UTF8' LC_COLLATE='en_US.UTF8' LC_CTYPE='en_US.UTF8' TEMPLATE=template0;
复制

Copy

注意上述命令声明拷贝template0数据库。当拷贝任何其他数据库时,来自源数据库的编码和区域设置不能被改变,因为可能导致数据损坏。参阅CREATE DATABASE获取更多信息。

数据库的编码存储在pg_database系统表中。您可以使用gsql-l选项或\l 命令列出这些编码。

$ gsql -l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges
-----------+-------+----------+-------------+-------------+-------------------
 chinese   | omm   | UTF8     | en_US.UTF8  | en_US.UTF8  |
 mogdb     | omm   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 mogila    | omm   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres  | omm   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | omm   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/omm           +
           |       |          |             |             | omm=CTc/omm
 template1 | omm   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/omm           +
           |       |          |             |             | omm=CTc/omm
(6 rows)
复制

Copy

注意:在大多数现代操作系统中,MogDB可以通过LC_CTYPE的设置决定使用哪种字符集,并且强制只使用匹配的数据库编码。在旧的操作系统上您需要确保使用所选区域所期望的编码。如果设置不正确很可能导致与区域相关的操作表现异常,比如排序。

LC_CTYPE不是C或者POSIX时,MogDB也允许超级用户创建使用SQL_ASCII编码的数据库。如上所述,SQL_ASCII不强制要求存储在数据库中的数据具有任何特定的编码,因此会存在出现区域相关错误行为的风险。我们不建议使用这样的设置组合,未来版本也许会完全禁止。

服务器和客户端之间的自动字符集转换

MogDB支持在服务器和客户端之间的自动字符集转换。转换信息存储在系统表pg_conversion中。MogDB自带一些预定义的转换,如表2所示。

表2 客户端/服务器字符集转换

服务器端字符集可用的客户端字符集
BIG5不支持做服务器端编码
EUC_CNEUC_CNMULE_INTERNALUTF8
EUC_JPEUC_JPMULE_INTERNALSJISUTF8
EUC_KREUC_KRMULE_INTERNALUTF8
EUC_TWEUC_TWBIG5MULE_INTERNALUTF8
GB18030不支持做服务器端编码
GBK不支持做服务器端编码
ISO_8859_5ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866WIN1251
ISO_8859_6ISO_8859_6UTF8
ISO_8859_7ISO_8859_7UTF8
ISO_8859_8ISO_8859_8UTF8
JOHABJOHABUTF8
KOI8RKOI8RISO_8859_5MULE_INTERNALUTF8WIN866WIN1251
KOI8UKOI8UUTF8
LATIN1LATIN1MULE_INTERNALUTF8
LATIN2LATIN2MULE_INTERNALUTF8WIN1250
LATIN3LATIN3MULE_INTERNALUTF8
LATIN4LATIN4MULE_INTERNALUTF8
LATIN5LATIN5UTF8
LATIN6LATIN6UTF8
LATIN7LATIN7UTF8
LATIN8LATIN8UTF8
LATIN9LATIN9UTF8
LATIN10LATIN10UTF8
MULE_INTERNALMULE_INTERNALBIG5EUC_CNEUC_JPEUC_KREUC_TWISO_8859_5KOI8RLATIN1 to LATIN4SJISWIN866WIN1250WIN1251
SJIS不支持做服务器端编码
SQL_ASCII任意(不会发生编码转换)
UHC不支持做服务器端编码
UTF8所有支持的编码
WIN866WIN866ISO_8859_5KOI8RMULE_INTERNALUTF8WIN1251
WIN874WIN874UTF8
WIN1250WIN1250LATIN2MULE_INTERNALUTF8
WIN1251WIN1251ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866
WIN1252WIN1252UTF8
WIN1253WIN1253UTF8
WIN1254WIN1254UTF8
WIN1255WIN1255UTF8
WIN1256WIN1256UTF8
WIN1257WIN1257UTF8
WIN1258WIN1258UTF8

要打开自动字符集转换功能,您必须键入想在客户端使用的字符集(编码)。 可以通过以下几种方法来实现。

  • 用gsql里的\encoding命令。 \encoding允许动态修改客户端编码。 比如,把编码改变为SJIS,键入:

    \encoding SJIS
    复制

    Copy

  • 使用libpq函数控制客户端编码。

  • 使用SET client_encoding TO语句。使用下面的SQL命令设置客户端编码:

    SET CLIENT_ENCODING TO 'value';
    复制

    Copy

    您也可以使用标准SQL语法SET NAMES

    SET NAMES 'value';
    复制

    Copy

    查询当前客户端编码:

    SHOW client_encoding;
    复制

    Copy

    重置默认编码:

    RESET client_encoding;
    复制

    Copy

  • 使用PGCLIENTENCODING。如果在客户端环境里定义了 PGCLIENTENCODING环境变量,那么在与服务器进行连接时将自动选择这个客户端编码。此编码可以用上文介绍的方法重写。

  • 使用client_encoding配置变量。 如果在client_encoding里设置了该变量, 那么在与服务器建立了连接之后,将自动选定这个客户端编码。此设置可以用上文介绍的方法重写。

如果无法进行特定的字符转换,比如,所选的服务器编码是EUC_JP而客户端是LATIN1,那么部分日文字符无法转换,此时将会报错。

如果客户端字符集定义成了SQL_ASCII, 那么编码转换会被禁用,无论服务器字符集设置如何。和服务器一样,除非您的业务环境全部使用ASCII数据,否则不建议使用SQL_ASCII

进一步阅读

您可以查阅以下资料了解各种类型的编码系统。

  • CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing

    包含EUC_JPEUC_CNEUC_KREUC_TW的详细说明。

  • http://www.unicode.org/

    Unicode主页。

  • RFC 3629

    UTF-8(8-bit UCS/Unicode转换格式)的定义。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论