一个有趣的问题――MySQL中varchar的最大长度(一)

2014-11-24 16:02:09 · 作者: · 浏览: 1
一个有趣的问题——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:

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;

我都一万了还不够,试下65535吧!
发现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