原文:http://wubx.net/varchar-vs-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.
从存储上讲:
说完存储后,说一下使用这些大的变长字段的缺点:
那问题来了? 为什么varchar(255+)存储上和text很相似了,但为什么还要有varchar, mediumtext, text这些类型?
(从存储上来讲大于255的varchar可以说是转换成了text.这也是为什么varchar大于65535了会转成mediumtext)
我理解:这块是一方面的兼容,另一方面在非空的默认值上varchar和text有区别。从整体上看功能上还是差别的。
这里还涉及到字段额外开销的:
备注 overhead是指需要几个字节用于记录该字段的实际长度。
从处理形态上来讲varchar 大于768字节后,实质上存储和text差别不是太大了。 基本认为是一样的。
另外从8000byte这个点说明一下: 对于varcahr, text如果行不超过8000byte(大约的数,innodb data page的一半) ,overflow不会存到别的page中。基于上面的特性可以总结为text只是一个MySQL扩展出来的特殊语法有兼容的感觉。
默认值问题:
总结:
源码中类型:
(末完待续,也希望大家一块讨论一下)
参考:
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及方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
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;
|