postgresql 中输入逃逸字符\n\r\b\t

例如:

1.建表

create table test(a1 text,a2 varchar(100),a3 char(200));
2.插入数据,使用关键字‘E‘

insert into test(a1,a2,a3) values(E'aaa\n\aaa\n', E'aaa\n\aaa\n',E'aaa\n\aaa\n');

参考:

http://www.postgresql.org/docs/9.1/interactive/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS

(4.1.2.2. String Constants with C-style Escapes)

3.命令行下查看插入的数据(注意:不要用pgadmin查看数据,pgadmin查看不到完整数据)

select * from test;

test=> select a1 from test;
 a1
-----
 aaa
 aaa

(1 row)
test=> select a2 from test;
 a2
-----
 aaa
 aaa

(1 row)
test=> select a3 from test;
 a3

-------

 aaa
 aaa

(1 row)

<think>嗯,用户现在想了解PostgreSQL数据库中中文字符和英文字符的存储区别,这个与之前讨论的Oracle数据库的问题很相似。不过需要特别注意,用户贴出的引用内容是关于PostgreSQL字符集和连接字符串的,说明ta可能正在处理PostgreSQL的实际问题。用户可能正在设计一个包含中英文混合存储的数据库表,或者遇到了存储空间计算或字符截断的问题。考虑到ta之前询问过Oracle的类似问题,应该是对不同数据库的字符处理机制有系统性了解的需求。从引用材料看,关键点在于字符集和编码的关系:比如UTF-8是Unicode的一种实现,而PostgreSQL默认使用UTF-8编码。这和Oracle类似,但具体实现细节可能有差异。需要重点说明:存储空间方面,英文始终占1字节,而中文在UTF-8下占3字节(基本平面字符)或4字节(扩展字符)。Oracle使用VSIZE函数,但PostgreSQL可以用LENGTH或OCTET_LENGTH函数来验证,也可以用char_length函数明确按字符计数。字段定义要注意char和varchar类型默认按字节计算长度,可能导致中文字符存储数量少于预期。这和Oracle的VARCHAR2(XXCHAR)语法不同,PG需要使用charactervarying(n)配合文本模式解决。用户可能没说出来但需要知道的是排序规则的影响——中文按拼音排序和按笔画排序对索引性能的影响不同。还有bytea类型存储二进制时和中文字符处理的区别。关于引用材料提到的连接字符串部分(npgsql),虽然用户没直接问,但可能在.net环境下使用PG,后续可能会问乱码问题如何解决,可以准备连接字符串中CharacterSet参数的说明作为知识储备。</think> 好的,我们来详细探讨一下 PostgreSQL 数据库中存储中文字符和英文字符的区别,核心在于字符编码和由此决定的存储空间。PostgreSQL 高度依赖服务器的**数据库编码**设置来处理字符。 以下是核心区别分析: ### 一、 核心存储机制 1. **英文字符存储**: * 在主流编码如 **UTF-8**、**Latin1**、**ASCII** 下,存储一个 **标准英文字母(A-Z, a-z)、数字(0-9)、基本标点符号** 等,通常只需要 **$1$ 字节**。 * 这是因为这些字符属于 ASCII 字符集或其扩展(如Latin1)的基本部分,在一个字节内即可表示。 2. **中文字符存储**: * **UTF-8 编码(推荐)**:存储一个 **常用汉字(在 Unicode 基本多文种平面 - BMP 中)** 需要 **$3$ 字节**。少数生僻汉字(在 Unicode 辅助平面)需要 **$4$ 字节**。 * **GBK / GB18030 编码**:存储一个汉字通常需要 **$2$ 字节**。GB18030 是 GBK 的超集,也兼容部分 4 字节字符(但主要用于兼容历史系统和满足某些标准)。 > **存储空间计算公式**: > $$ > \text{总字节数} = \sum (n_{en} \times s_{en}) + \sum (n_{zh} \times s_{zh}) > $$ > 其中: > * $n_{en}$:英文字符数量,$s_{en} = 1$(字节) > * $n_{zh}$:中文字符数量 > * $s_{zh}$: > * $UTF-8 \ (BMP)$:$3$ > * $UTF-8 \ (SMP/SIP/etc.)$:$4$ > * $GBK/GB18030$:$2$ (常用汉字) 或 $4$ (极少数扩展字符) ### 二、 关键验证函数 PostgreSQL 提供了区分字符数和字节数的函数: * **`LENGTH(str)` / `CHAR_LENGTH(str)`**: * 作用:统计字符串中的字符数量(无论字符占用多少字节)。 * 示例: ```sql SELECT LENGTH('PostgreSQL中国'); -- 返回:13 (P-o-s-t-g-r-e-S-Q-L-中-国,共 13 个字符) ``` * **`OCTET_LENGTH(str)`**: * 作用:统计字符串占用的实际存储字节数。 * 示例 (UTF-8 环境下): ```sql SELECT OCTET_LENGTH('PostgreSQL中国'); -- 返回:17 (11*1 + 2*3 = 11 + 6 = 17) SELECT OCTET_LENGTH('A'); -- 返回:1 SELECT OCTET_LENGTH('中'); -- 返回:3 (UTF-8) ``` ### 三、 字段定义与长度限制的本质 理解字符编码对表结构设计至关重要: 1. **长度限制本质**: * 当使用 `VARCHAR(n)` 或 `CHAR(n)`(无 `CHARACTER VARYING(n CHAR)` 语法时): * `n` 指定的是该字段允许的 **最大字节数 (octet_length)**,而不是字符数 (char_length)。 * **UTF-8 环境陷阱**: ```sql CREATE TABLE example ( desc VARCHAR(10) -- 定义最多 10 字节 ); -- 插入纯英文:10个字母没问题 (10字节) INSERT INTO example VALUES ('ABCDEFGHIJ'); -- 成功 -- 插入纯中文:'中国你好世界' (5个汉字, UTF-8下约15字节 > 10) INSERT INTO example VALUES ('中国你好世界'); -- 失败:ERROR: value too long for type character varying(10) -- 插入混合:'你好AB' (2个汉字 * 3 + 2个字母 * 1 = 8字节 <= 10) INSERT INTO example VALUES ('你好AB'); -- 成功 ``` * **GBK/GB18030 环境限制**:一个汉字占 2 字节,`VARCHAR(10)` 最多能存 5 个纯汉字。 2. **按字符数定义长度(PostgreSQL 特有解决方案)**: * PostgreSQL 提供了按字符定义长度限制的方法: ```sql CREATE TABLE safe_example ( name VARCHAR(30 CHAR) CHARACTER SET utf8, -- 或 TEXT COLLATE "zh_CN.utf8" desc TEXT COLLATE "zh_CN.utf8" -- TEXT类型无长度限制,但排序规则确保字符处理正确 ); INSERT INTO safe_example (name) VALUES ('张三李四王五赵六钱七孙八周九吴十'); -- 可存储最多 30 个字符(无论英汉) ``` * 使用 `VARCHAR(n CHAR)` 或 `TEXT`配合适当的 **COLLATION**(排序规则)是处理多语言字符存储、避免长度限制错误的 **更佳实践**。 ### 四、 字符编码的影响与选择 数据库编码设置在初始化数据库集群 (`initdb`) 时决定,建议选择 `UTF8`: | 编码选择 | 英文字节 | 中文字节 | 兼容性 | 优势 | 劣势 | |----------|----------|----------|---------|------|------| | **UTF-8** | $1$ | $3$ 或 $4$ | 全球语言,含 Emoji | 通用性最强,未来兼容性好 | 中文字符存储空间略大,索引稍慢 | | **GBK / GB18030** | $1$ | $2$ (常用) | 简体中文为主 | 中文存储空间节省,历史系统兼容 | 通用性差,难以处理其他语言(如希腊语、阿拉伯语、生僻字) | > ⚠️ **重要提示**:修改已有数据库的编码极其复杂,通常需要 `pg_dump` -> `initdb` (新编码) -> `pg_restore`。创建数据库时请 **谨慎选择** 最佳编码。 ### 五、 排序规则 (`COLLATION`) * **作用**:除编码存储字节外,字符比较(排序、`LIKE`、`ORDER BY`)也受 `COLLATION` 影响。 * **中英文区别**: * 英文排序通常简单(按字母 A-Z)。 * 中文排序规则多样,常用有: * `zh_CN`:按 **简体中文拼音** 排序。 * `zh_TW`:按 **繁体中文拼音** 或 **笔画数** 排序。 * **示例**: ```sql -- 在 UTF-8 环境下,指定不同中文排序规则,结果顺序可能不同 SELECT * FROM chinese_names ORDER BY name COLLATE "zh_CN.utf8"; -- 按拼音 SELECT * FROM chinese_names ORDER BY name COLLATE "zh_TW.utf8"; -- 可能按笔画或拼音(取决于系统配置) ``` ### 六、 `TEXT` 类型 * `TEXT` 类型是 **无限长度**的变长字符串类型(实际长度受行大小限制)。 * 它在 **字符处理** (`LENGTH`, `SUBSTRING`, 正则表达式等) 上与 `VARCHAR(n)` **没有区别**,都遵循数据库的编码和排序规则。 * 它 **没有预定义的长度限制**,避免了按字节限制的长度陷阱(如 `VARCHAR(255)` 在 UTF-8 下只能存 85 个中文字符)。在现代 PostgreSQL 中,使用 `TEXT` 配合适当 `COLLATION` 通常是更灵活和推荐的选择[^1]。 ### 总结关键区别表 | 特性 | 英文字符 | 中文字符 (UTF-8) | 中文字符 (GBK) | |------|----------|-------------------|----------------| | **存储字节(基本字符)** | $1$ | $3$ | $2$ | | **函数:LENGTH() 结果** | $1$ (字符) | $1$ (字符) | $1$ (字符) | | **函数:OCTET_LENGTH() 结果** | $1$ | $3$ | $2$ | | **VARCHAR(n) 限制** | $n$ 字符 | $\approx \lfloor n / 3 \rfloor$ 字符 | $\lfloor n / 2 \rfloor$ 字符 | | **推荐长度定义** | `VARCHAR(n)` | `VARCHAR(n CHAR)` 或 `TEXT` | `VARCHAR(n CHAR)` 或 `TEXT` | | **推荐数据库编码** | UTF8 | **UTF8** | GBK (仅限特定环境) | | **排序规则影响** | 小 (主要字母顺序) | 大 (拼音、笔画差异) | 大 (拼音、笔画差异) |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值