MySql中varchar(10)和varchar(100)的区别==>>以及char的利弊

MySQL中varchar和char类型的差异不仅在于磁盘存储,还涉及内存处理。varchar按实际长度存储,但内存中可能按最大长度处理,如varchar(100)即使存储10个字符也会占用101字节。char为固定长度,减少碎片问题,适合长度相近的数据。varchar的最大长度为65532(非空时)。在建立唯一索引时,尾部空格不计入比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般初学会认为,二者占用的空间是一样的。比如说我存储5个char,二者都是实际占用了5个char了【勘误:varchar在实际存储的时候会多一个byte用来存放长度】。
但是深入一下,设计数据库的时候,二者一样吗?
答案是否定的【至少varchar类型需要在数据之前利用一个或者两个字节来存储数据的长度】【二者在内存中的操作方式也是不同的,下面的例子中有体现】。
看下面的例子
如现在用户需要存储一个地址信息。根据评估,只要使用100个字符就可以了。但是有些数据库管理员会认为,反正Varchar数据类型是根据实际的需要来分配长度的。还不如给其大一点的呢。为此他们可能会为这个字段一次性分配200个字符的存储空间。这VARCHAR(100)与VARCHAR(200)真的相同吗?结果是否定的。虽然他们用来存储90个字符的数据,其存储空间相同。但是对于内存的消耗是不同的。对于VARCHAR数据类型来说,硬盘上的存储空间虽然都是根据实际字符长度来分配存储空间的,但是对于内存来说,则不是。其时使用固定大小的内存块来保存值。简单的说,就是使用字符类型中定义的长度,即200个字符空间。显然,这对于排序或者临时表(这些内容都需要通过内存来实现)作业会产生比较大的不利影响。解释可以参见这里所以如果某些字段会涉及到文件排序或者基于磁盘的临时表时,分配VARCHAR数据类型时仍然不能够太过于慷慨。还是要评估实际需要的长度,然后选择一个最长的字段来设置字符长度。如果为了考虑冗余,可以留10%左右的字符长度。千万不能认为其为根据实际长度来分配存储空间,而随意的分配长度,或者说干脆使用最大的字符长度。
----------------------------------char------------------------------------------
1、从碎片角度进行考虑,使用CHAR字符型时,由于存储空间都是一次性分配的。为此某个字段的内容,其都是存储在一起的。单从这个角度来讲,其不存在碎片的困扰。而可变长度的字符数据类型,其存储的长度是可变的。当其更改前后数据长度不一致时,就不可避免的会出现碎片的问题。故使用可变长度的字符型数据时,数据库管理员要时不时的对碎片进行整理。如执行数据库导出导入作业,来消除碎片。
2、考虑其长度的是否相近,如果某个字段其长度虽然比较长,但是其长度总是近似的,如一般在90个到100个字符之间,甚至是相同的长度。此时比较适合采用CHAR字符类型。比较典型的应用就是MD5哈希值。当利用MD5哈希值来存储用户密码时,就非常使用采用CHAR字符类型。因为其长度是相同的。另外,像用来存储用户的身份证号码等等,一般也建议使用CHAR类型的数据。
另外请大家考虑一个问题,CHAR(1)与VARCHAR(1)两这个定义,会有什么区别呢?虽然这两个都只能够用来保存单个的字符,但是VARCHAR要比CHAR多占用一个存储位置。这主要是因为使用VARCHAR数据类型时,会多用1个字节用来存储长度信息。这个管理上的开销char字符类型是没有的。

---------------------------------总结---------------------------------------------

二者在磁盘上存储占的空间是一样的。区别有二。第一、一个变长一个固定长度。第二、在内存中的操作方式,varchar也是按照最长的方式在内存中进行操作的。比如说要进行排序的时候,varcahr(100)是按照100这个长度来进行的。

-----------------------------------------------------------------------------------

varchar的最大长度是多少呢?

参见这里

mysql的vachar字段的类型虽然最大长度是65535,但是并不是能存这么多数据,最大可以到65533(不允许非空字段的时候),当允许非空字段的时候只能到65532【在允许空的时候,varchar(65532) will be 2 bytes (length) + up to 65532 chars (latin1) + 1 null byte】【还不清楚这一个null byte的作用是什么。后续了解】。

-------------------------------------------------------------------------------------

请注意所有MySQL校对规则属于PADSPACE类。这说明在MySQL中的所有CHAR和VARCHAR值比较时不需要考虑任何尾部空格。请注意所有MySQL版本均如此,并且它不受SQL服务器模式的影响。【参见这里的note部分上面几行文字】

下图为证:

根据上面地址提供的mysql手册,如果在一个char或者varchar列上建立唯一索引之后,那么'a'和'a ',会引起duplicate-key error。

### MySQL复杂表结构设计与实现 在设计复杂的MySQL表结构时,需综合考虑多个方面以确保数据库系统的高性能、高可用性易维护性。以下是关于复杂表结构设计的关键要素及其最佳实践: #### 1. 需求分析的重要性 在设计任何数据库之前,需求分析是一个不可或缺的过程。通过深入理解业务逻辑数据存储的需求,可以更合理地定义表之间的关系以及字段属性[^1]。 #### 2. 命名规范 为了便于理解维护,应采用一致的命名策略。例如,表名通常使用名词单数形式(如`User`),而列名则具体描述该列的内容(如`user_id`, `created_at`)。这种规范化不仅提高了代码可读性,还减少了潜在错误的发生概率[^3]。 #### 3. 数据类型选择 正确选择合适的数据类型对于节省存储空间并提升查询效率至关重要。需要注意的是,在某些情况下,虽然指定了整数类型的显示宽度(如`INT(10)`),但这仅影响输出格式而不改变实际存储大小[^4]。 #### 4. 字段约束设置 利用各种约束条件来保障数据完整性是非常必要的。常见的约束有主键(`PRIMARY KEY`)用于唯一标识每条记录;外键(`FOREIGN KEY`)用来建立不同表格间的关系;还有非空(`NOT NULL`)限制等都可以有效防止非法输入进入系统。 #### 5. 索引优化 适当创建索引可以帮助加速检索操作,但过多或不当使用的索引反而会降低写入速度及增加磁盘占用量。因此,在决定哪些列应该被加索引前要仔细权衡利弊,并定期审查现有索引的有效性。 #### 6. 表关联关系处理 当涉及到多张相互依赖的表时,清晰表达它们之间的一对一、一对多或者多对多联系就显得尤为重要了。比如可以通过在外键上添加级联更新/删除选项简化管理流程。 #### 示例:电子商务平台订单管理系统 假设我们要构建一个简单的电商网站后台数据库模型,则可能涉及以下几个主要实体及其对应关系: - 用户 (`users`) - 商品类别 (`categories`) - 商品详情 (`products`) - 购物车项 (`cart_items`) - 订单头信息 (`orders`) - 订单明细行 (`order_details`) 下面是部分SQL语句展示如何按照上述原则搭建这样一个体系: ```sql CREATE TABLE users ( user_id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, password_hash CHAR(60) NOT NULL, -- Assuming bcrypt hash length is fixed at 60 chars. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE categories ( category_id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(80) NOT NULL UNIQUE COMMENT 'Category Name', description TEXT NULL ); CREATE TABLE products ( product_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, sku VARCHAR(30) NOT NULL UNIQUE COMMENT 'Stock Keeping Unit', title VARCHAR(255) NOT NULL, price DECIMAL(10 , 2 ) UNSIGNED NOT NULL CHECK (price >= 0), stock_quantity INT UNSIGNED DEFAULT 0, category_id SMALLINT UNSIGNED NOT NULL, FOREIGN KEY fk_products_categories(category_id) REFERENCES categories(category_id) ON DELETE RESTRICT ON UPDATE CASCADE ); ``` 以上仅为一小部分内容片段演示目的所用,请根据实际情况调整参数设定。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值