MySQL 数据类型的范围上限

  今天帮朋友查一个 Discuz! 数据库的异常问题,表现是不能发帖,提示:

Discuz! info: MySQL Query Error
Script: /post.php
SQL: INSERT INTO [Table]threads (fid, readperm, price, iconid, typeid, author, authorid, subject, dateline, lastpost, lastposter, displayorder, digest, special, attachment, subscribed, moderated)
VALUES (‘4’, ‘0’, ‘0’, ‘0’, ‘0’, ‘2ndboy’, ‘6’, ‘test’, ‘1242289636’, ‘1242289636’, ‘2ndboy’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’)
Error: Duplicate entry ‘16777215’ for key 1
Errno.: 1062

  首先排除了程序被修改过的可能,然后看数据库,cdb_threads 表的第一个字段(即 key 1)是 tid,看了一下表里面的数据,最后一个帖子的 tid 确实是 16777215,而表的 auto_increment 值是 16777216,看上去一切正常,Check table 和 Repair table 也后返回 OK。尝试把数据表的 auto_increment 值改成 16777217 也没有用处,真是百思不得其解。

  抱着急病乱投医的心态让管理员更新缓存,还是没用。偶然打开计算器,把 16777215 复制进去,转成十六进制,咦?结果是 FFFFFF,顿时眼前一亮,不会是到达字段所能表示的数值上限了吧?看了一下 cdb_threads 表 tid 字段的定义,是 mediumint(8),经过查看 MySQL 文档得知,mediumint 的长度是 24bits,因此无符号数的最大值正好就是 16777215。这下就小白跟他哥的长的挺相——真相大白啦!

  于是乎备份数据库,把 cdb_threads 的 tid 字段改成 INT 类型,之后发现发帖后 cdb_threads 里出现了新贴的记录,但是界面上还是提示“操作未定义”,怀疑还有跟 tid 有关的字段,经过一番折腾之后,又修改了 n 处 tid 字段,这个世界终于清静啦。

  回过头来看看这个问题,一开始没有马上找到问题本质的原因,实在是对 16777215 这个值的敏感度不够,一般看到 255,65535 这种临界值总会留意一下,但是 24bits 数据的最大值还真没记住,这就是经验啊。

  其次是平时没有深究过 MySQL 里各种数值类型的取值范围(业余的 Web 开发毕竟还是业余的;)),而且对数据类型后面那个括号里的数字有误解,总觉得比如 INT(10) 跟 INT(8) 的取值范围是不一样的,这回查了文档才知道,这个数值是最大显示宽度,跟数据类型的取值范围无关。下面简单摘录一下 MySQL 中各常用数据类型的取值范围:
BIT,位域,6bits,取值范围1~64
TINYINT,很小的整数,8bits,取值范围0~255(有符号数 -128~127)
SMALLINT,小整数,16bits,取值范围 0~65535(有符号数 -32768~32767)
MEDIUMINT,中等大小整数,24bits,取值范围 0~16777215(有符号数 -8388608~8388607)
INT,整数,32bits,取值范围 0~ 4294967295(有符号数 – 2147483648~ 2147483647)
BIGINT,大整数,128bits,取值范围 0~ 18446744073709551615(有符号数 – 9223372036854775808~ 9223372036854775807)

此外,BOOL/BOOLEAN 和 TINYINT 的取值范围相同,INTEGER 和 INT 的取值范围相同。

  这么说来,朋友论坛的帖子数已经过一千六百多万了,现在改成 INT 以后,要到大约四十三亿个帖子时才会再次到达数值上限,那应该已经是很久以后的事情了。

4 Responses to “MySQL 数据类型的范围上限”

  1. dove1980 Says:

    没法现 你还是多才多艺啊
    我正想着怎么才能 专业呢

  2. 2ndboy Says:

    DB 不也是我们专业里的东西吗?!哈哈,不矛盾。艺多不压身嘛 :D

  3. dove1980 Says:

    太多了,现在还么有精通的
    c c++ mac installsheild xcode python
    MFC WTL ATL
    COM

    继续努力弄个精通的,发现赚钱比技术好玩多了

    以后改改口号,喜欢技术 更喜欢钱

  4. 2ndboy Says:

    怎么都好,开心最重要:)

Leave a Reply