Mysql中表字段VARCHAR(N)类型及长度的解释

 本文将针对MySQL 中 varchar (N)类型字段的存储方式进行解释,主要是对字符和字节的关系的理解。

 1. varchar (N) 中的 N

  • varchar (N) 中的 N 表示字符数,而不是字节数。这意味着 `N` 表示你可以存储多少个字符。

   字符数:指的是字符的个数,而不是这些字符在存储中所占的字节数。

   例如,varchar (255)意味着可以存储最多 255 个字符。

 2. 字符与字节的关系

  • VARCHAR字段的实际存储大小会受到字符集(如 UTF-8)影响。UTF-8 编码对于不同字符有不同的字节占用。
  •  常见字符(如英文字母、数字)占用 1 字节。
  • 一些 Unicode 字符(例如汉字、表情符号等)则需要 3 字节或 4 字节。

   - 如果你使用 UTF-8 编码,一个汉字通常占用 3 个字节。因此,varchar (255) 对于汉字来说,可以存储 255 个汉字,而如果是英文字符,可以存储 255 个字符,且每个字符占 1 字节。

3. VARCHAR`存储长度的计算

  • 存储长度:MySQL 会使用不同的字节数来存储 VARCHAR 的长度信息,具体如下:
  •  如果 N < 256,MySQL 会使用 1 字节来存储该字段的长度。
  •  如果 N >= 256,MySQL 会使用 2 字节来存储字段长度。

 这是为了节省存储空间。对于较小的 N,1 字节就足够表示长度;而对于较大的 N,2 字节可以表示更大的长度值。

    这里会有同学问,为什么 如果 N < 256,MySQL 会使用 1 字节 来存储该字段的长度。 如果 N >= 256,MySQL 会使用 2 字节 来存储字段长度?是规定好的么?

    是的,MySQL 对 VARCHAR`类型字段的长度存储采用了这样的设计,是为了在性能与空间优化之间取得平衡。这种机制的设计有以下几个原因:

 1.空间效率

      存储的长度指的是记录在表中实际数据的长度信息(即字符串的实际长度)。MYSQL需要用某种方式记录每个varchar字段的长度,因为varchar是可变的长度的类型。

      如果N<256时,最长只能记录255个字符,那么使用一个字节(8位)来存储长度信息就足够了。1字节可以标识0~255之间的数字。

      如果 `N >= 256`,则可能需要表示的长度会大于 255 个字符,这时 MySQL 使用 **2 字节** 来记录长度信息。2 字节可以表示的数字范围是 0 到 65535。

      这种机制可以有效节省存储空间。对于大部分使用 varchar 字段的场景,字段长度通常小于 256 个字符,因此只需 1 字节来存储长度,避免了使用 2 字节造成的额外空间浪费。

  2.性能考虑

     使用 1 字节表示长度时,MySQL 在读取和处理数据时所需的资源更少,读取速度会更快。
     当 N < 256 时,直接使用 1 字节来存储长度信息,不仅减少了存储所需的内存或磁盘空间,也加快了操作速度,因为处理较小的数据量会提升效率。

 3. 符合常见的数据使用模式

     在实际应用中,许多字符串数据(如姓名、邮件地址等)长度通常较短,常见字段长度往往小于 256 个字符。因此,使用 1 字节足以满足大多数场景的需求,而 2 字节则适用于存储长字符串数据的特殊场景。
     这种划分基于常见的数据使用模式,既能在存储小数据时提高效率,又能在需要时扩展到较大的字段长度。

**例子说明**
       如果你有一个 VARCHAR(100) 字段,存储的数据最多不超过 100 个字符。对于这个字段,MySQL 会使用 1 个字节来记录它的实际长度(0-255 之间的数),这意味着只需 1 字节就可以表示这个字段中字符串的长度。
       如果你有一个 `VARCHAR(300)` 字段,存储的数据可以超过 255 个字符。为了能记录所有可能的长度(0-300),MySQL 必须使用 2 个字节来存储长度信息,因为 1 字节不能表示超过 255 的数字。

结论:
     MySQL 的这一设计是规定好的,目的是在性能和空间使用之间做出折中。对于大多数应用场景,短文本占主导,因此 1 字节表示长度足够高效;而在需要更长文本的情况下,使用 2 字节也可以处理更大范围的字符长度。 

 4.存储限制与内存操作

     - MySQL 中的每个表中,所有 varchar字段的最大总字节数限制是65535 字节。
     - 在查询、排序或创建临时表时,MySQL 会基于 VARCHAR 的实际字节数来计算内存使用。
     - 因此,VARCHAR(255) 如果用于存储汉字,实际的内存占用会比存储英文字符多。

 **具体实例**
假设有一个表,包含如下两个字段:

1. name: varchar(255),用于存储英文名。
2. description: varchar(255),用于存储汉字描述。

存储英文字符的情况
  假设 name 字段存储的是英文字符:"John Doe"(10个字符)。
  varchar(255) 为该字段分配了 255 字符的空间,而实际存储了 10 个字符。
  由于字符是 ASCII 编码的,英文字符只占用 1 字节,所以这个字段占用了 10 字节的存储空间。
  存储长度:MySQL 使用 1 字节来存储 `name` 字段的长度,表示 10 个字符。

存储汉字的情况
  假设 description`字段存储的是中文字符:"这是一个描述"(7个汉字)。
  在 UTF-8 编码中,每个汉字占用 3 字节。因此,`description` 实际占用了 7 * 3 = 21 字节。
  由于 varchar(255)仍然分配了 255 个字符的空间,但由于是汉字,实际的字节数更高,因此该字段占用了 21 字节来存储数据。
存储长度:MySQL 使用 1 字节来存储 description字段的长度,表示 7 个汉字。

总内存占用
   name字段占用 10 字节数据 + 1 字节长度 = 11 字节。
   description字段占用 21 字节数据 + 1 字节长度 = 22 字节。
   总共的内存占用 = 11 + 22 = 33 字节。

总结
- varchar(N) 表示存储最多 N个字符,而不是字节数,实际的字节数取决于字符集(如 UTF-8)中的字符所占字节数。
- 对于存储长度,MySQL 使用 1 字节来表示字段长度(如果 N小于 256),使用 2 字节来表示更大长度的字段。
- 存储过程中要注意字符的字节数,因为不同字符集和字符可能占用不同的字节空间,特别是对于非 ASCII 字符(如汉字)。

5、问题总结

1.只有1字节和2字节两种选择吗,再大的字节不行么?

   在 MySQL 中,varchar类型字段的长度信息只有 1 字节和 2 字节 两种选择,而不会使用更多的字节。具体原因和设计考量如下:

   1. varchar 的设计限制

     - MySQL 对 varchar字段的最大长度限制为 65535 字节。这是由 MySQL 的存储机制决定的,一个表中 varchar字段的总字节数不能超过 65535 字节。
     - 因此,使用 2 字节已经足够表示 varchar字段的最大长度:
     - 1 字节能表示的长度范围是 0 到 255(总共 256 个值)。
     - 2 字节 能表示的长度范围是 0 到 65535(总共 65536 个值)。
     - 由于 varchar字段的设计最大长度为 65535 字节,2 字节已经足以表示所有可能的长度,所以没有必要再增加字节数。

  2. 更大数据类型的选择

   如果需要存储比 varchar 更大且更长的文本数据,MySQL 提供了其他数据类型,专门用于处理超长字符串或文本数据。这些类型在存储时采用不同的机制,而不是通过增加更多字节的长度信息。以下是常用的几种更大类型:

 - TEXT类型:TEXT 数据类型允许存储更大的文本数据,分为四种变体:
     1. TINYTEXT:最大 255 字节,使用 1 字节存储长度。
     2. TEXT:最大 65535 字节,使用 2 字节存储长度。
     3. MEDIUMTEXT:最大 16 MB,使用 3 字节存储长度。
     4. LONGTEXT:最大 4 GB,使用 4 字节存储长度。

   - BLOB 类型:与 TEXT`类型相似,但专门用于存储二进制数据。BLOB 也分为 TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB`四种变体,它们的存储机制和长度信息与 TEXT类型类似。

2. 为什么不使用更多字节?

   - 效率与需求的平衡:对于varchar 字段,2 字节已经能表示所有可能的长度(最大 65535 字节),而增加更多的字节来存储长度信息会显著增加存储开销,但并不会带来额外的好处,因为 varchar 类型本身就有长度限制。
   - 更大数据类型的存在:如果应用需要存储更大规模的数据,使用 `TEXT` 或 `BLOB` 类型是更合适的选择,而不是通过增加 varchar 字段的长度来实现。

结论:
     MySQL 选择使用 1 字节 或 2 字节 来存储varchar 字段的长度信息,因为这是对varchar 类型设计的最优折衷。对于更大的数据存储需求,MySQL 提供了 `TEXT`、`BLOB` 这类数据类型,它们使用 3 字节或 4 字节来存储长度信息,满足更大的存储需求。因此,在varchar 类型中没有必要使用超过 2 字节来表示长度信息。

3.使用 TEXT 或 BLOB 类型就不会增加存储开销了么

使用 TEXT 或 BLOB`类型虽然可以存储更大的数据,但它们也会带来额外的存储开销,与 varchar 类型相比。具体来说,主要体现在以下几个方面:

1. 额外的长度信息存储
   - 与 varchar 类型类似,`TEXT` 和 `BLOB` 类型也需要存储每个字段的长度信息。不过,它们的长度信息更大,因此会导致一定的开销。
   例如:
   - TEXT类型:
     - `TINYTEXT`:最大 255 字节,使用 1 字节存储长度。
     - `TEXT`:最大 65535 字节,使用 2 字节存储长度。
     - `MEDIUMTEXT`:最大 16 MB,使用 3 字节存储长度。
     - `LONGTEXT`:最大 4 GB,使用 4 字节存储长度。
   
   - BLOB类型:
     - `TINYBLOB`:最大 255 字节,使用 1 字节存储长度。
     - `BLOB`:最大 65535 字节,使用 2 字节存储长度。
     - `MEDIUMBLOB`:最大 16 MB,使用 3 字节存储长度。
     - `LONGBLOB`:最大 4 GB,使用 4 字节存储长度。

   总结: TEXT和 BLOB的长度存储信息随着数据类型的变化需要更多的字节,而 varchar 类型最多只使用 2 字节来存储长度信息。

2. 存储和处理机制差异
   - TEXT和 BLOB数据存储的方式通常与varchar 不同。TEXT和BLOB类型是外部存储(out-of-row)类型,意味着它们的实际数据可能存储在表的外部,而不是直接存储在行数据中。这是因为它们的内容可能非常大。
   - 因为这些数据可能存储在不同的存储位置(例如,外部文件、其他存储区域),所以读取 TEXT或 BLOB类型数据时,通常会有额外的 I/O 开销,即读取或写入这些字段时可能比 VARCHAR类型更慢,尤其在涉及大量数据时。
   - VARCHAR 数据直接存储在行内,因此读取速度通常会更快。

 3. 空间开销
     - TEXT 和 BLOB类型的存储开销相较于 VARCHAR可能更大。因为:
     - varchar 只存储实际字符的字节数和长度信息(1 或 2 字节)。
     - TEXT和 BLOB在存储数据时,除了长度信息之外,还可能引入额外的空间开销,用于管理外部存储的元数据、指针等。
   
   **举个例子**:如果你存储的是非常小的文本数据(比如 10 个字符的英文字符串),使用 TEXT类型相比 VARCHAR类型可能会带来更多的存储开销,尤其是当存储的数据量非常小,TEXT类型的存储机制可能会浪费更多的空间。

 4. 性能差异
    查询效率:对于 `VARCHAR` 字段,查询性能通常较好,因为它的存储方式是行内存储,数据直接保存在行中,不需要额外的 I/O 操作。
   - 对于 TEXT和BLOB字段,虽然它们可以存储更大的数据,但查询时可能会有额外的 I/O 开销,因为 MySQL 可能需要从外部存储中读取数据(特别是当数据量非常大时)。这种存储方式更适合处理大数据量的字段,而不是小文本。

 总结:TEXT 和 BLOB 的开销

- 存储开销:TEXT 和 BLOB 类型相较于 varchar 会有额外的存储开销,特别是当字段长度较小且需要存储的小文本时。它们的长度信息存储会使用更多的字节(最多 4 字节),而且数据存储在行外可能会增加 I/O 开销。
- 性能差异:对于较小的文本数据,varchar 类型通常会更高效,因为它是内存中连续存储的,而 TEXT 和 BLOB 类型可能需要额外的 I/O 操作。
- 适用场景:TEXT 和 BLOB 更适合存储大量文本或二进制数据,比如文章、图片数据、日志等。而 varchar 则适合存储较短的字符串数据,如用户名、电子邮件地址、简单描述等。

在选择 varchar 还是 TEXT 类型时,通常需要根据数据的实际大小来决定。如果存储的数据较小,varchar 是更合适的选择;如果存储的数据量较大,且长度可能会变化较大,TEXT或 BLOB类型则更为适用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/882427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

周易解读:八卦02,八卦所代表的基本事物

八 卦02 上一节&#xff0c;我是讲完了八卦的卦象的画法的问题。这一节&#xff0c;我来尝试着去讲解八卦所代表的自然事物。 八卦是谁发明的呢&#xff1f;根据《周易说卦传》的说法&#xff0c;八卦是伏羲发明的。伏羲氏仰观天文&#xff0c;俯察地理&#xff0c;从中提取…

项目模块二:日志宏

一、代码展示 二、补充知识 1、LOG(level, format, ...) format 是用于宏识别格式化&#xff0c;类似于 printf("%s", str); 里面的 "%s" ... 不定参&#xff0c;传入宏的参数除了 level, format, 还有不确定个数的参数。 2、红色 \ 由于宏只能写在一…

链上相遇,节点之间的悸动与牵连

公主请阅 1. 返回倒数第 k 个节点1.1 题目说明1.2 题目分析1.3 解法一代码以及解释1.3 解法二代码以及解释 2.相交链表2.1 题目说明示例 1示例 2示例 3 2.2 题目分析2.3 代码部分2.4 代码分析 1. 返回倒数第 k 个节点 题目传送门 1.1 题目说明 题目名称&#xff1a; 面试题 02…

15分钟学 Go 第 10 天:函数参数和返回值

第10天&#xff1a;函数参数和返回值 目标&#xff1a;理解函数如何传递参数 在Go语言中&#xff0c;函数是程序的基本构建块。了解如何传递参数和返回值是编写高效、可复用代码的重要步骤。本文将详细讲解函数参数的类型、传递方式以及如何处理返回值&#xff0c;辅以代码示…

DP—子数组,子串系列 第一弹 -最大子数组和 -环形子数组的最大和 力扣

你好&#xff0c;欢迎阅读我的文章~ 个人主页&#xff1a;Mike 所属专栏&#xff1a;动态规划 ​ 53. 最大子数组和 最大子数组和 ​ 分析: 使用动态规划解决 状态表示: 1.以某个位置为结尾 2.以某个位置为起点 这里使用以某个位置为结尾&#xff0c;结合题目要求&#…

MySQL8.0主从同步报ERROR 13121错误解决方法

由于平台虚拟机宿主机迁移&#xff0c;导致一套MySQL主从库从节点故障&#xff0c;从节点服务终止&#xff0c;在服务启动后&#xff0c;恢复从节点同步服务&#xff0c;发现了如下报错&#xff1a; mysql> show slave status\G; *************************** 1. row *****…

GDAL+C#实现矢量多边形转栅格

1. 开发环境测试 参考C#配置GDAL环境&#xff0c;确保GDAL能使用&#xff0c;步骤简述如下&#xff1a; 创建.NET Framework 4.7.2的控制台应用 注意&#xff1a; 项目路径中不要有中文&#xff0c;否则可能报错&#xff1a;can not find proj.db 在NuGet中安装GDAL 3.9.1和G…

无人机之自主飞行关键技术篇

无人机自主飞行指的是无人机利用先进的算法和传感器&#xff0c;实现自我导航、路径规划、环境感知和自动避障等能力。这种飞行模式大大提升了无人机的智能化水平和操作的自动化程度。 一、传感器技术 传感器是无人机实现自主飞行和数据采集的关键组件&#xff0c;主要包括&a…

C语言复习第3章 函数

目录 一、函数介绍1.1 函数是什么1.2 C语言中函数的分类1.3 函数原型1.4 高内聚 低耦合1.5 C语言main函数的位置 二、函数的参数2.1 实参和形参2.2 函数的参数(实参)可以是表达式2.3 传值与传址(swap函数)2.4 明确形参是实参的临时拷贝2.5 void(如果不写函数返回值 默认是int)2…

python 爬虫 入门 三、登录以及代理。

目录 一、登录 &#xff08;一&#xff09;、登录4399 1.直接使用Cookie 2.使用账号密码进行登录 可选观看内容&#xff0c;使用python对密码进行加密&#xff08;无结果代码&#xff0c;只有过程分析&#xff09; 二、代理 免费代理 后续&#xff1a;协程&#xff0c;…

企业级调度器 LVS

集群和分布式基础知识 系统性能的扩展方式 当一个系统&#xff0c;或一个服务的请求量达到一定的数量级的时候&#xff0c;运行该服务的服务器的性能和资源上限&#xff0c; 很容易成为其性能瓶颈。除了性能问题之外&#xff0c;如果只部署在单台服务器上&#xff0c;在此服务…

gitee建立/取消关联仓库

目录 一、常用指令总结 二、建立关联具体操作 三、取消关联具体操作 一、常用指令总结 首先要选中要关联的文件&#xff0c;右击&#xff0c;选择Git Bash Here。 git remote -v //查看自己的文件有几个关联的仓库git init //初始化文件夹为git可远程建立链接的文件夹…

uniapp uni.uploadFile errMsg: “uploadFile:fail

uniapp 上传后一直显示加载中 1.检查前后端上传有无问题 2.检查失败信息 await uni.uploadFile({url,filePath,name,formData,header,timeout: 30000000, // 自定义上传超时时间fail: async function(err) {$util.hideAll()// 失败// err 返回 {errMsg: "uploadFile:fai…

SpringCloud学习:Openfeign组件实现服务调用和负载均衡

OpenFeign&#xff1a;服务调用与负载均衡&#xff08;服务端接口&#xff09; 是什么&#xff1a;通过OpenFeign可以实现服务调用和负载均衡 OpenFeign是一个声明性web服务客户端&#xff0c; 怎么用&#xff1a;服务提供者提取公共接口用FrignClient标注&#xff0c;服务调…

kernel32.dll下载地址:如何安全地恢复系统文件

关于从网络上寻找kernel32.dll的下载地址&#xff0c;这通常不是一个安全的做法&#xff0c;而且可能涉及到多种风险。kernel32.dll是Windows操作系统的核心组件之一&#xff0c;负责内存管理、进程和线程管理以及其他关键系统功能。因为kernel32.dll是系统的基础文件&#xff…

信息安全工程师(57)网络安全漏洞扫描技术与应用

一、网络安全漏洞扫描技术概述 网络安全漏洞扫描技术是一种可以自动检测计算机系统和网络设备中存在的漏洞和弱点的技术。它通过使用特定的方法和工具&#xff0c;模拟攻击者的攻击方式&#xff0c;从而检测存在的漏洞和弱点。这种技术可以帮助组织及时发现并修补漏洞&#xff…

【数据结构与算法】链表(上)

记录自己所学&#xff0c;无详细讲解 无头单链表实现 1.项目目录文件 2.头文件 Slist.h #include <stdio.h> #include <assert.h> #include <stdlib.h> struct Slist {int data;struct Slist* next; }; typedef struct Slist Slist; //初始化 void SlistI…

C++20中头文件ranges的使用

<ranges>是C20中新增加的头文件&#xff0c;提供了一组与范围(ranges)相关的功能&#xff0c;此头文件是ranges库的一部分。包括&#xff1a; 1.concepts: (1).std::ranges::range:指定类型为range&#xff0c;即它提供开始迭代器和结束标记(it provides a begin iterato…

系统托盘图标+快捷启动(Python)

QkStart 我把这个程序命名为QkStart 代码 # -*- coding: utf-8 -*- # Environment PyCharm # File_name QkStart |User Pfolg # 2024/10/19 22:06 import threading import time import pystray from PIL import Image from pystray import MenuItem, Menu import o…

leetcode.204.计数质数

#中等#枚举 给定整数 n &#xff0c;返回 所有小于非负整数 n 的质数的数量 。 埃氏筛 枚举没有考虑到数与数的关联性&#xff0c;因此难以再继续优化时间复杂度。接下来我们介绍一个常见的算法&#xff0c;该算法由希腊数学家厄拉多塞&#xff08;Eratosthenes&#xff09;提…