MySQL中的varchar与char

本文详细解析了MySQL数据库中CHAR与VARCHAR两种字符串类型的特点与使用场景。CHAR适合存储固定长度的字符串,无论实际存储数据长度如何,都会占用相同的空间,且索引效率较高;而VARCHAR则用于存储变长字符串,其存储效率较低,但能更经济地利用存储空间。

MySQL中的varchar与char

varchar:
存储变长数据,但存储效率没有char高. 如果一个字段可能的值是不固定长度的, 我们只知道它不可能超过10个字符, 把它定义为varchar(10) 是最合算的

char:
char存储定常数据很方便, char字段上的索引效率高, 比如定义 char(10) , 那么不论你存储的数据是否达到了10个字节,都要去占去10个字节的空间.

<think>我们正在讨论MySQL中的两种字符串类型:VARCHARCHAR,以及它们定义中长度参数的含义(如varchar(50)中的50int(20)中的20)。同时,我们也要探究MySQL这样设计数据类型参数规则的原因。 根据引用内容,我们可以总结如下: 1. **VARCHARCHAR的区别**: - CHAR是固定长度的类型,分配的空间是固定的,如果实际数据长度小于定义的长度,会用空格填充到指定长度。 - VARCHAR是可变长度的类型,存储的是实际数据,不需要用空格填充,但需要额外的1-2字节来存储数据的长度信息。 2. **varchar(50)中50的含义**: - 表示该字段最多可以存储50个字符(注意,在MySQL中,字符数取决于字符集,例如在utf8mb4字符集下,一个字符可能占用1~4个字节)。因此,这里50表示字符的最大数量,而不是字节数。 3. **int(20)中20的含义**: - 对于整数类型,括号中的数字并不表示存储空间的大小,而是表示显示宽度。整数类型(如INT)的存储空间是固定的(INT为4字节)。显示宽度20表示当该字段被格式化输出时(例如使用ZEROFILL),显示的数字宽度为20位,不足的用0填充。如果没有ZEROFILL,则这个显示宽度通常没有实际效果。 4. **MySQL设计这些规则的原因**: - 对于CHARVARCHAR,设计成固定长度可变长度是为了在存储效率性能之间取得平衡。CHAR适合存储长度相对固定的数据(如MD5值、国家代码等),可以避免碎片化,提高存取效率;而VARCHAR适合存储长度变化大的数据,节省存储空间。 - 对于整数类型,显示宽度的设计主要是为了控制输出格式,这在某些报表场景下可能有用,但通常情况下并不影响存储。 接下来,我们将详细展开回答,并按照要求添加引用标识。 注意:在回答中,我们可能会使用到一些技术细节,如存储结构、存储过程等,这些内容在引用[3][4]中有所提及。 另外,关于整数类型的显示宽度,引用[1][2]都提到了,尤其是引用[1]明确指出“int(M)中的M indicates the maximum display width”。 最后,我们还需要生成相关问题,放在回答末尾。 </think> ### MySQL 字符串数值类型深度解析 #### 一、`VARCHAR` `CHAR` 核心区别 ```mermaid graph TD A[字符串类型] --> B[CHAR] A --> C[VARCHAR] B --> D[固定长度] B --> E[存储时填充空格] B --> F[读取时移除尾部空格] C --> G[可变长度] C --> H[1-2字节长度前缀] C --> I[仅存实际数据] ``` | **特性** | **CHAR** | **VARCHAR** | |----------------|-----------------------------------|-------------------------------------| | **存储方式** | 固定长度,不足补空格 | 可变长度 + 长度前缀(1-2字节) | | **存储效率** | 浪费空间(短数据) | 节省空间(无填充)[^4] | | **读写性能** | 读取快(直接定位) | 写入快(无空格处理)[^4] | | **尾部空格** | 自动移除 | 保留原始空格 | | **适用场景** | MD5值/邮编等定长数据 | 用户名/地址等变长数据 | > **底层结构差异**: > `VARCHAR` 存储 = 长度前缀(1-2字节) + 实际数据[^3] > `CHAR` 存储 = 固定字节空间(字符集决定) #### 二、数据类型参数深度解析 1. **`VARCHAR(50)` 中 50 的含义** - 表示 **最大字符容量**(非字节数) - 实际存储空间 = **长度前缀 + 实际字符数 × 字符字节数** - 示例:`VARCHAR(50) CHARSET=utf8mb4` - 最大存储:50字符 × 4字节/字符 = 200字节 - 实际存储"你好":1字节(长度前缀) + 6字节(两汉字) = 7字节 2. **`INT(20)` 中 20 的含义** - 表示 **显示宽度**(display width) - 实际存储固定为 **4字节**((20)无关) - 仅在使用 `ZEROFILL` 时生效: ```sql CREATE TABLE t (id INT(4) ZEROFILL); INSERT INTO t VALUES (12); -- 显示 0012 ``` #### 三、MySQL 设计原理探究 1. **`VARCHAR/CHAR` 差异化设计原因** - **性能平衡**: - `CHAR` 用空间换时间(适合高频读取) - `VARCHAR` 用计算换空间(`长度前缀`解析开销) - **存储优化**: 避免`CHAR`的尾部空格浪费(平均节省30%空间)[^5] - **兼容性**: 支持多字符集(如utf8mb4的变长字符) 2. **`INT(M)` 显示宽度设计原因** - **数据格式化**:对齐数值输出(报表场景) - **历史兼容**:早期终端显示限制(已逐步淘汰) - **开发友好**:提示字段预期范围(文档作用) #### 四、选型建议最佳实践 ```sql -- 定长数据选 CHAR(性能优先) CREATE TABLE user_auth ( token CHAR(32) -- MD5固定32字符 ); -- 变长数据选 VARCHAR(空间优先) CREATE TABLE user_profile ( name VARCHAR(50) CHARSET=utf8mb4 ); -- 避免无效显示宽度(INT默认即可) CREATE TABLE orders ( id INT -- 等效于INT(11)且无ZEROFILL ); ``` > **关键配置原则**: > - `VARCHAR(N)` 的 `N` 按**业务真实最大值**设定 > - 超过 255 字符时长度前缀占 **2字节**[^3] > - `CHAR` 长度超过 255 时自动转为 `TEXT` 类型 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值