varchar和text的区别

最近有几个同学问我varchar和text有啥别吗,这个问题,以前说真的也没太多的整理,以前遇到text在设计中就是尽可能的拆到另一个表中,保持主表尽量的瘦小,可以让innodb bp缓存更多的数据。

今天借次机会系统整理一下,主要从存储上,最大值,默认值几个方面进行比较。

BTW: 从ISO SQL:2003上讲VARCHAR是一个标准型,但TEXT不是(包括tinytext).varchar在MySQL 5.0.3之前只支持0-255byte, 在5.0.3之后才支持到0-65535byte.

从存储上讲:

- text 是要要进overflow存储。 也是对于text字段,不会和行数据存在一起。但原则上不会全部overflow ,
会有768字节和原始的行存储在一块,多于768的行会存在和行相同的Page或是其它Page上。
  
- varchar 在MySQL内部属于从blob发展出来的一个结构,在早期版本中innobase中,也是768字节以后进行overfolw存储。
  
- 对于Innodb-plugin后: 对于变长字段处理都是20Byte后进行overflow存储
(在新的row_format下:dynimic compress)

 

说完存储后,说一下使用这些大的变长字段的缺点:

 

- 在Innobase中,变长字段,是尽可能的存储到一个Page里,这样,如果使用到这些大的变长字段,会造成一个Page里能容纳的行
数很少,在查询时,虽然没查询这些大的字段,但也会加载到innodb buffer pool中,等于浪费的内存。
(buffer pool 的缓存是按page为单位)(不在一个page了会增加随机的IO)
 
- 在innodb-plugin中为了减少这种大的变长字段对内存的浪费,引入了大于20个字节的,都进行overflow存储,
而且希望不要存到相同的page中,为了增加一个page里能存储更多的行,提高buffer pool的利用率。 这也要求我们,
如果不是特别需要就不要读取那些变长的字段。

那问题来了? 为什么varchar(255+)存储上和text很相似了,但为什么还要有varchar, mediumtext, text这些类型?
(从存储上来讲大于255的varchar可以说是转换成了text.这也是为什么varchar大于65535了会转成mediumtext)

我理解:这块是一方面的兼容,另一方面在非空的默认值上varchar和text有区别。从整体上看功能上还是差别的。

这里还涉及到字段额外开销的:

- varchar 小于255byte  1byte overhead
- varchar 大于255byte  2byte overhead
 
- tinytext 0-255 1 byte overhead
- text 0-65535 byte 2 byte overhead
- mediumtext 0-16M  3 byte overhead
 
- longtext 0-4Gb 4byte overhead

 

备注 overhead是指需要几个字节用于记录该字段的实际长度。

从处理形态上来讲varchar 大于768字节后,实质上存储和text差别不是太大了。 基本认为是一样的。
另外从8000byte这个点说明一下: 对于varcahr, text如果行不超过8000byte(大约的数,innodb data page的一半) ,overflow不会存到别的page中。基于上面的特性可以总结为text只是一个MySQL扩展出来的特殊语法有兼容的感觉。

默认值问题:

- 对于text字段,MySQL不允许有默认值。
- varchar允许有默认值

 

总结:

根据存储的实现: 可以考虑用varchar替代tinytext
如果需要非空的默认值,就必须使用varchar
如果存储的数据大于64K,就必须使用到mediumtext , longtext
varchar(255+)和text在存储机制是一样的
 
需要特别注意varchar(255)不只是255byte ,实质上有可能占用的更多。
 
特别注意,varchar大字段一样的会降低性能,所以在设计中还是一个原则大字段要拆出去,主表还是要尽量的瘦小

 

源码中类型:

+--Field_str (abstract)
 |  +--Field_longstr
 |  |  +--Field_string
 |  |  +--Field_varstring
 |  |  +--Field_blob
 |  |     +--Field_geom
 |  |
 |  +--Field_null
 |  +--Field_enum
 |     +--Field_set

 

(末完待续,也希望大家一块讨论一下)

参考:

http://yoshinorimatsunobu.blogspot.com/2010/11/handling-long-textsblobs-in-innodb-1-to.html

http://nicj.net/mysql-text-vs-varchar-performance/

http://www.pythian.com/blog/text-vs-varchar/

 

测试SQL及方法

create table tb_01(
c1 varchar(255),
c2 varchar(255),
c3 varchar(255),
c4 varchar(255),
c5 varchar(255),
c6 varchar(255),
c7 varchar(255),
c8 varchar(255),
c9 varchar(255),
c10 varchar(255),
c11 varchar(255)
)engine=Innodb;
 
insert into tb_01(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11) values(repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255));
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
 
(testing)root@localhost [wubx]> set global innodb_file_format=BARRACUDA;
Query OK, 0 rows affected (0.00 sec)
 
(testing)root@localhost [wubx]> alter table tb_01 row_format=dynamic;
Query OK, 0 rows affected (0.19 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
(testing)root@localhost [wubx]> insert into tb_01(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11) values(repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255));
Query OK, 1 row affected (0.00 sec)
 
 
set global innodb_file_format=Antelope;
create table tb_02(
c1 varchar(2000),
c2 varchar(2000),
c3 varchar(2000),
c4 varchar(2000),
c5 varchar(2000),
c6 varchar(2000),
c7 varchar(2000),
c8 varchar(2000)
)engine=Innodb;
 
insert into tb_02(c1, c2, c3,c4,c5,c6,c7,c8) values(repeat('吴',2000),repeat('吴',2000),repeat('吴',2000),repeat('吴',2000),repeat('吴',2000),repeat('吴',2000),repeat('吴',2000),repeat('吴',2000) );
 
 
create table tb_03(
c1 text,
c2 text,
c3 text,
c4 text,
c5 text,
c6 text,
c7 text,
c8 text,
c9 text,
c10 text,
c11 text
)engine=Innodb;
insert into tb_03(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11) values(repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255));
 
(testing)root@localhost [wubx]> insert into tb_03(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11) values(repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255),repeat('吴',255));
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
 
set global innodb_file_format=BARRACUDA;
alter table tb_03 row_format=dynamic;
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: varchartext 在 MySQL 中是两种不同的存储字符串数据的数据类型。 - varchar:存储变长字符串,最大长度为 65535 个字符。 - text:存储较长的文本数据,最大长度为 2^32 - 1 个字符。 因此,如果需要存储较短的字符串数据,可以使用 varchar,如果需要存储较长的字符串数据,则可以使用 text。 总的来说,text 占用的空间更多,但具有更高的存储容量,而 varchar 占用的空间更少,但具有较低的存储容量。因此,选择哪种类型取决于实际的存储需求。 ### 回答2: 在MySQL中,varchartext都是用于存储文本数据类型的字段,它们在使用时有一些区别。 1. 存储长度:varchartext都能够存储不定长度的字符串,但是varchar有长度限制,而text没有长度限制。varchar的长度限制是指最大允许长度,例如varchar(100),表示允许存储的最大长度为100个字符;而text可以存储任意长度的字符串,最大长度取决于存储引擎。 2. 存储方式:varchartext的存储方式也不同。varchar是用于存储比较短的字符串,它会被放到表格的行中,不同于其它字符型数据类型,如果varchar存储的文本数据大小超过对应的表格大小,会造成MySQL自动转成text类型。text存储的字符串通常比较长,它会被存储在表格外面的数据文件中,因此text的存取速度会比varchar慢,占用的存储空间也更大。 3. 索引:varchar可以使用索引,比较方便进行查询和排序;而text类型的字段只能创建fulltext类型的索引,不能使用普通的索引。 4. 查询速度:由于varchar存储在表格中,因此查询速度会比text类型的字段快,尤其是在频繁查询、大量数据时效果更加明显。 总结而言,varchar主要适用于存储较短的字符串,它具有长度限制和较快的查询速度,而text适用于存储较长的字符串,具有无长度限制和较慢的查询速度,同时只能创建fulltext类型的索引。在实际开发中,应根据存储的实际情况选择使用varchartext。 ### 回答3: 在MySQL中,VARCHARTEXT都是用来存储字符数据类型的字段。它们的区别在于存储大小和存储方式。 1. 存储大小 VARCHAR的存储大小是固定的,它需要指定一个最大长度,在实际应用中,它只会占用实际存储的字符数加上一些额外的字节来存储长度信息。例如,如果将一个长度为10的VARCHAR字段设置为“Hello World”,MySQL将使用12个字节来存储它(10字节用于存储实际数据,2字节用于存储长度信息)。 而TEXT的存储大小是可变的,可以存储任何长度的文本数据。对于较长的文本数据,TEXT类型比VARCHAR类型更适合。 2. 存储方式 VARCHAR是以字符串的形式存储,而TEXT是以二进制大对象(BLOB)的形式存储。因此,在进行一些操作时,VARCHAR具有更高的性能。 另外,当涉及到排序和查找时,VARCHAR要比TEXT具有更好的性能,因为VARCHAR可以使用索引来进行优化,而TEXT则不能。 总体来说,VARCHAR适用于存储短字符串(一般少于255个字符),而TEXT适用于存储较长的文本信息,如博客文章、新闻内容等。但是,要根据具体情况和数据库的需求来选择合适的数据类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值