MySQL和Oracle的CHAR、VARCHAR类型对比

在实际开发过程中,是否不确定字符类字段在数据库中设置多大合适,设置哪种类型,比如支持输入30个中文的地址字段。

CHAR与VARCHAR的区别

可变长度与不可变长度的区别。
CHAR(n):固定长度,存储时会在尾部添加空格,查询时去掉尾部空格。
VARCHAR(n):可变长度,存储时保留尾部空格,查询时也会原样返回(不会截断)。仅占用实际字符长度 + 1-2字节的长度标识(用于记录字符串实际长度),不会填充额外字符

类型适合场景典型例子
CHAR长度固定、短字符串、查询频繁手机号(11位)、性别(1-2字符)、邮编(6位)
VARCHAR长度不固定、差异大、节省空间用户名(3-20字符)、地址、商品描述、备注

优先根据数据长度是否固定--------固定长度用CHAR(性能优先),可变长度用VARCHAR(空间优先)。

MySQL中的CHAR与VARCHAR

MySQL中的CHAR/VARCHAR默认按“字符数”定义长度。

  1. CHAR类型(固定长度,不足补空格)
    CHAR(n)中的n是字符数(5.0.3+),无论英文还是中文,最多存储n个字符(仅受字符集是否支持中文影响)
    若编码格式为utf8,占3n字节
    若编码格式为utf8mb4(MySQL特有),占4n字节
  2. VARCHAR类型(可变长度,仅存实际字符)

Oracle中的CHAR和VARCHAR2

Oracle推荐用VARCHAR2(VARCHAR已废弃),且长度定义支持显示指定BYTE(字节)或CHAR(字符),默认值由参数NLS_LENGTH_SEMANTICS决定(11g前默认BYTE,11g后默认CHAR)。

  1. NLS_LENGTH_SEMANTICS=BYTE,占n字节,最多存n个字节。
  2. NLS_LENGTH_SEMANTICS=CHAR,最多存n个字符。所能存储的最大字节数,由数据库所设定的字符编码来定。
  1. CHAR类型(固定长度,不足补空格)
    CHAR(n BYTE)或CHAR(n CHAR),n分别代表“字节数”或“字符数”。
    a. CHAR(n CHAR)是存储中文的推荐方式,字符数与英文一致;
            若字符编码格式为UTF-8,占3n字节
            若字符编码格式为AL32UTF8(Oracle特有),占4n字节
    b. CHAR(n BYTE)需按中文字节数折算,存储量更少。
  2. VARCHAR2类型(可变长度,无补空格)

字符编码与字符集

其实在上面问题中,涉及字符编码问题。在开发过程中,常常会看到UTF-8、GBK、Unicode等。这些概念,特别容易混淆。(有些场景也将下面表格中的ASCII、GBK、UTF-8等编码方式说是字符集,无需纠结,理解含义即可)

类型代表本质含义
字符集Unicode定义了全球所有语言字符(文字、符号、emoji等)的集合及唯一编号(码点)
编码方式ASCII、GBK、UTF-8规定如何将字符集中的字符等转化为计算机可存储的二进制码

为什么会有乱码?

乱码的本质是编码解码方式不匹配。

例如:用GBK编码的“中”字(二进制DXD6D0),若用UTF-8解码,会解析为错误的字符,导致乱码。

解决方案:系统中统一使用UFT-8编码(全球化场景)或GBK(纯中文场景)。

维度ASCIIGBKUTF-8
类型编码方式编码方式编码方式
字符覆盖范围

仅英文及基础符号

共128个字符(0-127),包括大小写字母、数字、标点和控制字符(如换行)

中日韩等东亚字符全球所有字符
中文编码长度不支持中文2字节通常3字节
兼容性无依赖兼容ASCII兼容ASCII
应用场景早起英文系统中文Windows系统互联网、跨语言系统

在MySQL中,支持utf8(即utf8mb3)和utf8mb4(大家可以查看mysql中新建数据库,选择字符集时,其中有utf8(即utf8mb3)、utf8mb4选项)

维度utf8(即utf8mb3)uftbmb4
支持的字符范围仅支持1-3字节Unicode字符(如中文、英文)(中文字符占3字节,英文字符占1字节)1-4字节的所有Unicode字符(含emoji、罕见字符)(中文字符占3字节,英文字符占1字节,emoji、生僻字占4字节)
存储占用每个字符最多占3字节每个字符最多占4字节
兼容性与旧版本MySQL兼容需MySQL5.5.3及以上版本支持
对emoji的支持不支持(会显示为?或截断)完全兼容
与标准的utf8的关系子集(不完整实现)完全符合标准

MySQL Oracle 数据库中的 `VARCHAR` 类型在行为上存在显著差异,主要体现在默认单位、字符集处理以及存储机制等方面。 ### 字符长度字节长度的定义差异 在 Oracle 中,`VARCHAR2(M)` 的默认单位是 **BYTE**,除非显式指定为 `CHAR` 单位。这意味着如果使用多字节字符集(如 UTF-8),`VARCHAR2(20 BYTE)` 实际上只能容纳少于 20 个字符的情况,具体取决于每个字符所占用的字节数。例如,在 UTF-8 编码下,一个中文字符通常占用 3 到 4 个字节,因此 `VARCHAR2(20 BYTE)` 最多只能存储 6 个中文字符[^1]。 而在 MySQL 中,`VARCHAR(M)` 的定义是基于字符数而非字节数。这意味着 `VARCHAR(20)` 可以存储最多 20 个字符,无论这些字符是单字节的英文字符还是多字节的中文字符。然而,实际存储空间的计算仍然依赖于字符集。例如,若使用 `utf8mb4` 字符集(每个字符最多占用 4 字节),则存储 20 个中文字符可能需要高达 80 字节的空间[^3]。 ### 存储限制索引长度 Oracle 对 `VARCHAR` 类型的长度限制较为宽松,支持高达 32767 字节的变长字符串(对于 `VARCHAR2` 类型而言,在 PL/SQL 中为 32767 字节)。此外,Oracle 的索引机制也更为灵活,对索引键长度的限制远高于 MySQL,默认情况下可以支持更大的索引键长度。 相比之下,MySQL 的 `VARCHAR` 类型最大长度受制于行大小限制使用的字符集。例如,在使用 `utf8mb4` 字符集的情况下,InnoDB 引擎中单个列的最大长度为 65535 字节除以最大字符宽度(即约 16383 个字符)。但需要注意的是,MySQL 的索引长度限制为 1000 字节(InnoDB MyISAM 表),这意味着如果字段使用 UTF-8 编码,则最多只能索引 333 个字符长度的内容[^3]。 ### 示例代码:创建表并测试 VARCHAR 容量 以下 SQL 示例展示了如何在两种数据库中创建包含 `VARCHAR` 类型的表,并插入数据以测试其容量: #### Oracle ```sql CREATE TABLE test_varchar_oracle ( id NUMBER PRIMARY KEY, content VARCHAR2(20 CHAR) ); -- 插入中文字符 INSERT INTO test_varchar_oracle (id, content) VALUES (1, '这是一个测试'); ``` #### MySQL ```sql CREATE TABLE test_varchar_mysql ( id INT PRIMARY KEY, content VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 插入中文字符 INSERT INTO test_varchar_mysql (id, content) VALUES (1, '这是一个测试'); ``` ### 总结 | 特性 | Oracle `VARCHAR2` | MySQL `VARCHAR` | |------|-------------------|-----------------| | 默认单位 | BYTE | CHAR | | 多字节字符处理 | 需要根据字符编码调整长度定义 | 自动按字符数计算 | | 最大长度限制 | 高达 32767 字节(PL/SQL) | 受行大小限制,最大约 65535 字节 | | 索引长度限制 | 较宽松 | 最大 1000 字节 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值