阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

关于Oracle数据库字符集的选择

143次阅读
没有评论

共计 9563 个字符,预计需要花费 24 分钟才能阅读完成。

如何选择数据库的字符集是一个有争议的话题,字符集本身涉及的范围很广,它与应用程序、客户的本地环境、操作系统、服务器等关系很密切,因此要做出合适的 选择,需要明白这些因素之间的关系。另外对字符集的基本概念,Oracle 数据库字符集的一些知识也需要了解。

随着国内的软件产品逐步走向海外,对于多语言的支持已经成为软件的一个基本要求,采用 UNICODE 标准也逐渐成为通用的设计方案,此时 ORACLE 数据库的字符集应该如何选择?很多人都有自己的见解,在网上也可以看到很多关于字符集的文章。这些文章有很多精华值得去学习,但是另一方面还存在一些错误,尤其对 UNICODE,存在一些概念不清的地方。

数据库字符集的选择并不存在绝对意义上的正确或错误,每种字符集都有它适用的环境。对于我们来说,了解得越多,越能帮助自己做出适当地选择,而且可以采取措施去主动防范或规避可能出现的问题。反之,如果数据库字符集选择不恰当,会给后面的工作带来很多的麻烦,需要花费很多时间和精力去解决问题,有些问题甚至会影响到客户的业务使用。本文希望可以给大家提供一些相对全面的知识,方便大家了解数据库字符集的相关概念,因此有些繁琐,请大家见谅。另外由于个人的局限,有何不妥之处还请大家不吝指正。

下面我们由浅入深,先由概念入手,再给出几种常用的字符集设置建议,对一些可能遇到的问题做出分析,最后给出自己的建议。

1、字符集的一些基本知识

讲到数据库的字符集设置,首先需要对字符集的知识有些了解。以下是字符集的基本知识介绍:由于计算机只能存储使用二进制数据,因此对于一些字符或符号,需要对它们进行编码,用编码后的数值来表示这些字符。对于一组符号的编码集合就是字符集。

字符集有很多种,最初的字符集是 ASCII,它用一个字节中的 7 位来表示 128 个字符,第 8 位没有使用。它包括大小写字母、数字 0 -9、标点符号、非打印字符(换行符、制表符等 4 个)以及控制字符(退格、响铃等)等。由于 ASCII 支持的字符很有限,因此随后又出现了很多的编码方案,这些编码方案大部分都是包括了 ASCII 的,它们只是做了扩展,这些扩展的内容一般各不相同,因此说 ASCII 是一个比较基本的编码,EBCDIC 编码是另一个比较基本的编码,它的部分字符采用了和 ASCII 不同的编码值,因此两者是不兼容的基本编码方案。采用 EBCDIC 编码的比较少,目前主要是 IBM 的系统采用,如 AS400 及 S390 系统,大部分的系统都是基于 ASCII 编码的。

由于亚洲国家的字符集相对复杂一些,因此一般都使用了两个及以上的字节进行编码的方案。对于简体中文,GB2312 码是国家 1981 年实施的编码标准,通行于大陆。新加坡等地也使用此编码。GBK 编码是 GB2312 码的扩展,是 1995 年发布的指导性规范,它在字汇一级支持 ISO/IEC 10646-1 和 GB 13000-1 的全部中日韩 (CJK) 汉字(20902 字)。目前最新的汉字字符集是 2000 年的 GB18030,它是取代 GBK1.0 的正式国家标准。该标准收录了 27484 个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。目前简体 WINDOWS 的缺省内码还是 GBK,可以通过 GB18030 升级包升级到 GB18030。不过 GB18030 相对 GBK 增加的字符,普通人是很难用到的,因此 GBK 还是我们目前最常用的简体中文字符集。

由于编码方案太多且彼此之间不兼容,存在互相之间存在冲突的情况,即对于同一个编码数值,在两种不同的编码方案中代表的是两个不同的字符。这样对于一些 WEB 应用来说,由于多种语言文字的同时使用及存储,需要采用一种统一的字符集。为此,国际标准化组织 (ISO) 制定了 ISO 10646 码表,而 Unicode 协会制定了 Unicode 规范,这两个体系刚开始时是独立建立的,在 1991 年,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从 Unicode2.0 开始,Unicode 项目采用了与 ISO 10646- 1 相同的字库和字码。目前两个项目仍都存在,并独立地公布各自的标准。Unicode 协会现在的最新版本是 2006 年的 Unicode 5.0。ISO 的最新标准是 10646-3:2003。下面简单介绍一下几种常见的编码方式:

UCS(Universal Character Set)是按 ISO-10646 定义的字符集,有两种最常用编码方式:UCS- 2 和 UCS-4。

UCS-2:使用 0 -65535 之间的数表示一个 unicode 字符。UCS- 2 无法表示所有的 unicode 字符,只能表示其前 65536 个字符(称为 Basic Multilingual Plane,BMP)。我们一般经常使用的 UNICODE 码就是指这个编码方案。

UCS-4: 使用 0 -FFFFFFFF 之间的数表示一个 unicode 字符,但为了和 unicode 体系兼容(unicode 体系是一个 20bit 系统),ISO-10646 表示所有定义的字符将不超过 10FFFF。UCS- 4 可以表示所有的 unicode 字符。

Unix 下使用 UCS-2/UCS- 4 会导致非常严重的问题,因为有一些特殊的字符, 比如 ‘/0’ 或 ‘/’, 它们在文件名和其他 C 的库函数参数里都有特别的含义,C 语言使用 ’/0’ 作为字符串结尾,而 Unicode 里恰恰有很多字符都有一个字节为 0,这样一来,C 语言的字符串函数将无法正常处理 Unicode,除非把世界上所有用 C 写的程序以及他们所用的函数库全部换掉。

为了解决这个问题,于是产生了将 Unicode 编码规则和计算机的实际编码对应起来的一个规则,UTF, 英文为 UCS Transformation Format,即 UCS 转换格式,目前常用的有 UTF-8、UTF-16、UTF-32 三种。(还有 UTF- 7 在此就不介绍了)。正如名字所示,它们分别使用 8 位、16 位、32 位比特对 UCS 进行编码。

UTF-8:一种变长的 Unicode 编码方式,使用 1 到 4 个字节表示一个字符。这种方式的最大好处,是 UTF-8 保留了 ASCII 字符的编码作为它的一部分,因此在 ASCII 表示的 128 个字符在 UTF- 8 的编码没有变化,它的兼容性比较好。UTF- 8 在目前 WEB 应用上使用很广泛。

UTF-16: 一种变长 Unicode 编码方式,使用两个或者四个字节表示一个字符。这种编码方式比较节省空间,因为它把最常使用的字符都用两个字节来表示,而那些不常用的字节则用两个或四个字节来表示。但对于英文字符来说,它要用两个字节来编码。

UTF-32: 一种固定长度的 Unicode 编码方式,使用四个字节表示一个字符,它适用在内存很充足,需要定长的编码场合。

2、ORACLE 数据库的字符集

ORACLE 的字符集名字一般由以下部分组成:语言或区域、表示一个字符的比特位数、标准字符集名称(可选项,S 或 C,表示服务器或客户端)。ORACLE 字符集 UTF8 与 UTFE 不符合此规定,其它基本都是这种格式。

对于 US7ASCII,表示区域是 US,用 7 个比特位表示一个字符,标准的字符集名称为 ASCII。

对于中文字符集 ZHS16GBK,表示简体中文(ZHT 为繁体中文),一个字符需要 16 位比特,标准的字符集名称为 GBK。而 ZHS16CGB231280 表示简体中文,一个字符需要 16 位比特,标准的字符集名称为 GB231280,属于我们前面提过的 1981 年发布的 GB2312-80 标准。虽然我们说,GBK 编码标准是 GB2312 编码标准的扩展,但是数据库字符集 ZHS16GBK 与 ZHS16CGB231280 之间却不是严格的超集与子集的关系,主要是有些汉字的编码在两个字符集中的数值是不同的,因此它们进行字符集转换时会出现问题。

在本文中,有时候使用的是标准字符集名称,有时候又需要使用 ORACLE 字符集的名称,因此希望大家明白两者之间的对应关系。

ORACLE 数据库有国家字符集(national character set)与数据库字符集 (database character set) 之分。两者都是在创建数据库时需要设置的。国家字符集主要是用于 NCHAR、NVARCHAR、NCLOB 类型的字段数据,而数据库字符集使用很广泛,它用于:CHAR、VARCHAR、CLOB、LONG 类型的字段数据;表名、列名、PL/SQL 中的变量名;输入及保存在数据库的 SQL 和 PL/SQL 的源码。

ORACLE 支持的 Unicode 字符集有以下几种,下面的列表给出了字符集的名称、对应的数据库版本范围、采用的 Unicode 的版本。

字符集 对应的数据库版本范围 Unicode 的版本   

字符集
对应的数据库版本范围
Unicode 的版本
AL24UTFFSS
7.2-8.1
1.1
UTF8
8.0-10g
2.1 (8.0-8.1.6)
3.0 (8.1.7-10g)
UTFE
8.0-10g
2.1 (8.0-8.1.6)
3.0 (8.1.7-10g)
AL32UTF8
9.0-10g
3.0 (9.0)
3.1 (9.2)
3.2 (10.1)
4.01(10.2)
AL16UTF16
9.0-10g
3.0 (9.0)
3.1 (9.2)
3.2 (10.1)
4.01(10.2)

AL24UTFFSS:是 ORACLE 第一种支持 Unicode 的字符集,从 7.2 版本开始使用,但是它支持的 Unicode 版本为 1.1,因此从 9i 开始就不支持此字符集了。

UTF8: 是 ORACLE 从 ORACLE8 开始使用的属于 UTF- 8 编码的字符集,从 ORACLE8.0 到 ORACLE8.16,Unicode 版本为 2.1,而 ORACLE817 到 10g,采用的 Unicode 标准为 3.0

UTFE:用于 EBCDIC 码平台上的数据库 Unicode 字符集。因此它属于专用系统使用的字符集,其它属性与 UTF8 基本相同。

AL32UTF8:是从 ORACLE9 开始使用的属于 UTF- 8 编码的字符集,���UTF8 相比,它采用的 Unicode 版本更新,在 10g 版本中使用的是 Unicode 4.01 标准,而 UTF8 因为兼容性的考虑,在 10g 版本中用的是 Unicode 3.0 标准。

AL16UTF16:是 ORACLE 第一种采用 UTF-16 编码方式的字符集,从 ORACLE9 开始使用,是作为缺省的国家字符集使用,它不能被用作数据库的字符集。这是因为数据库的字符集决定了 SQL 与 PL/SQL 源码的编码方式,对于 UTF-16 这种使用固定的两个字节来表示英文字母的编码方案来说,确实不适于用作数据库的字符集,ORACLE 目前采用的数据库字符集都是基于 ASCII 或 EBCDID 作为子集的编码方案。

从以上几种字符集的介绍来看,Unicode 字符集一般使用 UTF8 和 AL32UTF8。如果数据库版本都在 9i 及其以上,不需要考虑 ORACLE8 的数据库,建议使用 AL32UTF8 字符集,它采用的 Unicode 标准要比 UTF8 采用的 Unicode 标准更新,支持的字符也更多一些。如果要考虑 ORACLE8 数据库,建议使用 UTF8 字符集,它的兼容性好,在 ORACLE8 及 8I 数据库上使用 AL32UTF8 字符集容易出现问题。

3、如何选择合适的数据库字符集

前面我们介绍了字符集的一些概念,并对 ORACLE 数据库的常用几个字符集有了一些了解,下面就具体对数据库字符集的选择阐述一些个人的观点:

3.1、数据库需要存储的数据类型是字符集选择的首要考虑目标。

由于数据库的主要功能在于存储数据,因此要保证数据的正确性。采用何种数据库字符集需要看存储数据是何种类型的。对于只存储英文信息的数据库等来说,一般采用 US7ASCII 或 WE8ISO8859P1 等单字节的字符集就比较合适,在性能和空间上也是最优,如果采用 ZHS16GBK 编码,虽然可以使用,但从数据库字符集本身的含义来说,属于不恰当的选择。同样,存储了中文信息的数据库,如果采用单字节的字符集,也是不合适的。在这种情况下,数据库的字符集虽然是 US7ASCII 或 WE8ISO8859P1 编码,但里面存储的数据编码实际上却是另外的编码格式,这种不一致的情况很容易引起问题,建议不要这样使用。ORACLE 提供了很多种类的字符集供客户选择,就是要满足各种文字不同的编码需要。

3.2、字符集的选择需要优先考虑应用程序的需要。

目前出于国际化的需要,软件需要可以对不同的语言文字进行处理,尤其一个系统中需要容纳多种语言文字的时候,一般都会采用 Unicode 这样的通用解决方案,即使会有一些空间和运行效率的损失也是值得的。此时数据库字符集建议可以采用 AL32UTF8 或 UTF8 编码,一种比较理想的模式就是由程序负责编码格式的转换,而数据库只提供一个透明的数据存储;

客户在应用程序中输入数据,此时数据的编码格式是由客户操作系统的区域及语言设置决定的,如在简体中文 XP 的环境下,输入的中文编码属于 GBK 编码。在客户输入结束后,程序首先判断客户的本地环境,并把编码转换成 UNICODE,并通过 NET 传送到服务器端。由于客户端与服务器数据库的字符集均为 UTF8 格式,ORACLE 在传送过程中不会进行字符转换,直接把数据按 UTF8 格式存储到数据库中。查询时是一个反向的过程,应用程序从数据库中取出 UTF8 编码的数据,再由应用程序根据客户的本地环境,把 UTF8 编码的数据转换成客户本地的编码格式,最后把结果数据显示给客户。此方案的关键在于应用程序要能很好的支持 UNICODE 编码,编码的转换由应用程序来负责,数据库只是提供了一个数据存储功能。

对于部分程序来说,由于对 UNICODE 支持不够,没有提供编码的转换功能,则可以使用 ORACLE 提供的字符集转换功能来实现同样的目的。

客户在应用程序中输入数据,此时数据的编码格式是由客户操作系统的区域及语言设置决定的,如在简体中文 XP 的环境下,输入的中文编码属于 GBK 编码。在客户输入结束后,程序直接把数据并通过 NET 传送到服务器端。由于客户端与服务器数据库的字符集不一致,因此 ORACLE 会把客户端的编码转换成 UTF8 格式,再把数据按 UTF8 格式存储到数据库中。这种方案的优点就是程序可以不用支持 UNICODE,由 ORACLE 数据库自动进行转换。由于数据库的字符集为 UTF8,是其它字符集的超集,因此在转换过程中不会发生数据丢失的情况。对于英文的字符符号,在 UTF8 中使用单字节存储,转换的工作量很小,可以忽略,而对于一些亚洲字符集,在 UTF8 中一般需要两到三个字节存储,需要的数据库空间增加,而且转换的工作量也相对大一些,性能会有一些损失。

4、与字符集相关的问题分析

4.1、在 UTF8 环境下运行 SQL 语句报错的问题:

我们前面讲过,SQL*PLUS 工具不提供编码自动转换的功能,当数据库字符集为 UTF8,客户端的 NLS_LANG 如果也是 UTF8,那么在 SQL*PLUS 中运行 SQL 语句时,语句全是英文,不会出现问题,如果语句包含了中文或其它一些特殊字符,SQL 语句运行时就会报错。对于返回的含中文的结果,SQL*PLUS 也会显示乱码。

造成此错误的原因在于当 SQL 语句中包含汉字等一些特殊字符时,由于这些字符的编码属于 GBK,ORACLE 没有进行字符转换,而是直接把 SQL 语句送到服务器上进行解析。此时服务器的字符集是 UTF8,因此它按 UTF8 编码格式对 SQL 语句中 GBK 编码的字符解析时就会产生错误。如果把客户端的 NLS_LANG 设置为本地环境的字符集,如 ZHS16GBK,此时可以直接在 SQL*PLUS 中输入包含中文的 SQL 语句,ORACLE 在把 SQL 语句提交到服务器时会自动转换成 UTF8 编码格式,因此 SQL 语句可以正常运行。对于英文字母,由于它在 UTF8 中的编码数值采用的还是 ASCII 的编码数值,因此英文字母可以直接使用而不需要转换,这就是如果 SQL 语句或输出结果全是英文时不会出现错误的原因。

正确的做法是先把需要运行的 SQL 做成脚本文件,用代码转换工具把它转换成 UTF8 编码格式的文件,(注意!XP 中的记事本是提供了代码转换功能的,可以在保存文件或选择文件另存为的时候,弹出的对话框最后一项,编码,选择 UTF8,再保存,即可把文件转换成 UTF8 编码格式)。完成后用 IE 打开这个脚本,选择编码-》UTF8,观察此时 SQL 脚本是否含有乱码或“?”符号。如果没有,说明编码格式已经是 UTF8 了,此时在 SQL*PLUS 中运行这个脚本就不会产生错误了。运行结束后,输出的结果中如果包含中文,需要把结果 SPOOL 输出到一个文件中,然后用代码转换工具把这个结果文件由 UTF8 转换成本地编码格式,再用写字板打开,才能看到正常显示的汉字。由于 IE 具有代码转换功能,因此也可以不用代码转换工具,直接在 IE 中打开输出的结果文件,选择 UTF8 编码,也能正常显示含中文的结果文件。

4.2、数据库出现乱码的问题:

数据库出现乱码的问题主要和客户的本地化环境,客户端 NLS_LANG 设置,服务器端的数据库字符集设置这三者有关,如果它们的设置不一致或者某个设置错误,就会很容易出现乱码,下面我们简要介绍以下几种情况:

4.2.1、数据库字符集设置不当引起的乱码:

这种错误是由于数据库字符集选择错误而引起的。我们前面讲过,由于每种语言文字都有一些自己特殊的字符,甚至一些字符的写法都有不同的讲究,因此即使对于欧美国家来说,也不是可以随便通用的。像西欧的字符集标准 ISO 8859- 1 是 8 位编码,它就有自己的一些特殊符号,这些字符在 US7ASCII 编码中找不到对应的编码值。如果需要使用这些特殊符号,就必须选用本地字符集或者是它的超集的字符集。如果选用的字符集两者都不是,那么在数据库存储的数据实际编码和数据库字符集的设置就产生了不一致,很容易产生乱码。

例如:一个存储简体中文字符的数据库,它的字符集选用了 US7ASCII,当它的客户端 NLS_LANG 也选用 US7ASCII 时,这个系统单独使用是没有问题的,因为两者设置一致,因此 ORACLE 不会进行字符集的转换,客户输入的 GBK 码被直接在数据库中存储起来,当查询数据时,实际客户端取出来的数据也是 GBK 的编码,因此显示也是正常的。但当其它的系统需要从这个数据库取数据,或者它的数据要 EXP 出来,IMP 到其它数据库时,问题就会开始出现了。其它系统的字符集一般是 ZHS16GBK,或者其它系统客户端的 NLS_LANG 设置为 ZHS16GBK,此时必然会产生字符集的转换。虽然数据库字符集设置为 US7ASCII,但我们知道,实际存储的数据编码是 ZHS16GBK 的。可惜 ORACLE 不会知道,它会把存储的 ZHS16GBK 编码数据当作 US7ASCII 编码的数据,按照 US7ASCII 转换成 ZHS16GBK 的转换算法进行转换,可以想象,这种情况下,乱码的产生是必然的。

结论是:如果要选择一个非本地环境的数据库字符集,在不需要考虑和其它系统的数据接口和数据交换的情况下,或者你有面对这种麻烦的心理准备的话,那么这种选择是可行的,但是别忘了数据库字符集一定要和客户端的 NLS_LANG 保持一致。

4.2.2、数据库字符集与客户端 NLS_LANG 设置不同引起的乱码:

由于 ORACLE 提供了字符集的转换功能,因此数据库字符集与客户端 NLS_LANG 设置不同是可以接受的,前提条件是数据库的字符集必须是客户端 NLS_LANG 设置字符集的超集,那么由于客户端使用的字符是属于数据库字符集中的一部分,因此不会产生转换时数据丢失及乱码的情况。

例如:对于一个需要存储简体文信息的数据库来说,它的字符集设置和客户端 NLS_LANG 设置一般可以使用 ZHS16GBK 编码。但是如果数据库字符集选用了 UTF8 的话,也是可以的,因为 ZHS16GBK 编码属于 UTF8 的子集。ORACLE 在数据库与客户端进行数据交换时自动进行编码的转换,在数据库中实际存储的也是 UTF8 编码的数据。此时其它数据库和此数据库也可以正常的进行数据交换,因为 ORACLE 会自动进行数据的转换。在实际使用中,遇到过繁体 XP 的字符集 ZHT16MSWIN950 转换成 AL32UTF8 字符集时,一些特殊的字符和个别冷僻的汉字会变成乱码。后来证实是 XP 需要安装一个字库补丁软件,最后顺利解决此问题。

结论:对于数据库字符集为 UTF8,而客户端采用本地字符集的情况,最好进行测试验证,因为 UNICODE 标准本身发展很快,一些客户端的操作系统对 UNICODE 标准支持的力度不一致,有些操作系统支持不好,有些特殊字符在转换后会产生乱码。由于这个话题已经超出了本文的范畴,在此就不详细讨论了。

4.2.3、客户端 NLS_LANG 与本地化环境不同引起的乱码:

一般情况下,客户端 NLS_LANG 与本地化环境采用了不同的字符集会出现乱码,除非本地化环境的字符集是客户端 NLS_LANG 设置字符集的子集。如果把客户端 NLS_LANG 设置为 UTF8 就属于这种情况,由于目前还没有可以直接使用 UNICODE 字符集的操作系统,因此客户本地化环境使用的字符集只能是某种语言支持的字符集,它属于 UTF8 的子集。下面我们就着重讨论这种情况。

虽然目前 WINDOWS 的内核是支持 UNICODE 的,但是 WINDOWS 并不支持直接显示 UNICODE 编码的字符, 而且它并不知道目前的字符采用了何种字符集,所以默认情况下,它使用缺省的代码页来解释字符。因此,对于其它类型的编码,需要先进行转换,变成系统目前的缺省代码页支持的字符集才能正常使用。

WINDOWS 中的缺省代码页是由控制面板设置中的语言及区域的选择所决定的,属于客户本地化的环境设置。简体中文 WINDOWS 的字符编码就是 GBK,它的缺省代码页是 936。对于其它非 WINDOWS 的操作系统,我们可以把它们目前缺省使用的字符集作为用户的本地化环境设置。另外,我们使用的大部分工具,如写字板,SQL*PLUS 等,它们没有提供编码转换功能,因此在客户端直接输入或查询数据往往都会遇到乱码的问题,必须由应用程序或一些工具去做编码的转换,才能保证正常的使用。比如 SQL*PLUS 遇到的问题,我们在 4.1 节中已经进行了详细的论述。

5、最后的结论及建议:

以上不厌其烦的列举了种种因为选用了不恰当的数据库字符集而出现的问题,最后总结归纳起来,以下几点就是我个人的建议了:

1) 一般情况下,建议优先考虑客户的本地化环境,选用本地通用的字符集作为数据库的字符集和客户端 NLS_LANG 的设置,使得数据库、客户端 NLS_LANG、客户端操作系统三者的字符集可以完全兼容,这样出现的问题和麻烦最少。就简体中文而言,目前最常用的字符集是 ZHS16GBK,建议大家选用。

2) 如果系统需要支持多语言,采用了 UNICODE 标准,那么 ORACLE 数据库字符集在版本 9 以上可以选用 AL32UTF8,如果涉及到 ORACLE8 及 8i 的数据库,字符集可以选用 UTF8。

3) 如果应用程序完全支持 UNICODE,可以根据客户的本地化环境自动转换编码,则客户端的 NLS_LANG 可以设置成和数据库服务器端字符集完全一致。如果应用程序不能自动进行编码的转换或需要在客户端进行一些管理维护活动,则建议把客户端的 NLS_LANG 设置成本地环境使用的字符集,由 ORACLE 来进行编码的转换工作。此时需要对客户端的操作系统进行验证测试,因为目前各个操作系统对 UNICODE 标准支持的程度不同,有时会出现一些特殊字符转换不正常的情况。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-01/139969.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计9563字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中