一个有趣的问题——MySQL中varchar的最大长度
明明维护了一个1k的最小堆,可是输出到MySQL里却只有九百多行数据。
查log,发现这么一段内容:
01
stderr logs
02
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'reqs' at row 1
03
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3595)
04
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3529)
05
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990)
06
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151)
07
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2625)
08
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
09
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415)
10
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333)
11
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318)
12
at com.successfactors.perflog.hadoop.mapreduce.core.ParseRecordToDB$RecordReducer.insertData(Unknown Source)
13
at com.successfactors.perflog.hadoop.mapreduce.core.ParseRecordToDB$RecordReducer.cleanup(Unknown Source)
14
at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:178)
15
at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:649)
16
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:417)
17
at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
18
at java.security.AccessController.doPrivileged(Native Method)
19
at javax.security.auth.Subject.doAs(Subject.java:415)
20
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)
21
at org.apache.hadoop.mapred.Child.main(Child.java:249)
看来是column的最大长度不够,查看DDL:
我都一万了还不够,试下65535吧!
01 CREATE TABLE `record` ( 02 `eid` varchar(100) NOT NULL, 03 `module` varchar(32) NOT NULL, 04 `stime` int(11) NOT NULL, 05 `edate` varchar(32) NOT NULL, 06 `fname` varchar(100) NOT NULL, 07 `event` varchar(500) NOT NULL, 08 `reqs` varchar(10000) NOT NULL, 09 PRIMARY KEY (`eid`) 10 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
发现varchar直接变成mediumtext了,这可不对。那就试试22222吧
又报错了...
最后我设置为20000长度了,倒是通过了,通过一个复杂的减法可以计算更为临界的值。
去网上查查,发现MySQL里column的最大长度貌似跟很多东西有关,跑去问公司的DBA,貌似oracle是另一套机制。
附一篇别人的文章,讲最大值的:
http://www.2cto.com/database/201210/159610.html
01
这不是一个固定的数字。本文简要说明一下限制规则。
02
03
strlen 计算字符串长度,一个中文当2字符
04
05
mb_strlen根据它的字符编码模式,统计字符quot
06
07
count计算数组中的元素数目或对象中的属性个数
08
09
< php
10
header('Content-Type:text/html;charset=UTF-8');
11
$string1="谢春业";//定义中文字符变量
12
$string2="xcy";//定义英文字符变量
13
//直接输出看看他们的长度
14
echo strlen($string1);
15
echo "";
16
echo strlen($string2);
17
echo "";
18
//用 php 多字节扩展函数 mb_strlen试试看
19
echo mb_strlen($string1,'utf8');
20
echo "";
21
echo mb_strlen($string2,'utf8');
22
echo "";
23
>
24
25
输出结果是:
26
9
27
3
28
3
29
3
30
1、限制规则
31
32
字段的限制在字段定义的时候有以下规则:
33
34
a) 存储限制
35
36
varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。
37
38
b) 编码长度限制
39
40
字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
41
42
字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
43
44
对于英文比较多的论坛 ,使用GBK则每个字符占用2个字节,而使用UTF-8英文却只占一个字节。
45
46
若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
47
48
c) 行长度限制
49
50
导致实际应用中varchar长度限制的是一个行定义的长度。 MySQL要求一个行的定义长度不能超过65535。若定义的表长度超过这个值,则提示
51
52
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not co