smallint 字段报长度不够

【TiDB 版本】v4.0.9

【问题描述】
smallint (10),字段长度给了10,插入只有5个数字值,却报长度不够。更改为smallint (500)还是报错,是啥原因啊。

root@mysql 15:39:15 [ims_a05_786]> CREATE TABLE ims_wash_code_vip_percent_set (
-> id int(10) NOT NULL AUTO_INCREMENT COMMENT ‘代理主键’,
-> vip_id smallint(5) NOT NULL COMMENT ‘vip的id(关联ims_user_vip_setting表的id)’,
-> game_id smallint(10) NOT NULL COMMENT ‘二级游戏的id(关联ims_wash_code_game_switch_sort表的id)’,
-> wc_money_scope varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ‘’ COMMENT ‘洗码金额范围,例如:100,1000’,
-> wc_percent decimal(5,2) NOT NULL DEFAULT ‘0.00’ COMMENT ‘洗码比例,例如:11.58<=>11.58%’,
-> audit_multiple decimal(18,2) DEFAULT ‘0.00’ COMMENT ‘稽核倍数,可以为空’,
-> status char(2) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ‘0’ COMMENT ‘状态:0,启用;1,禁止;’,
-> remark varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ‘’ COMMENT ‘备注’,
-> create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
-> create_by varchar(32) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ‘’ COMMENT ‘创建人员’,
-> update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘更新时间’,
-> update_by varchar(32) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ‘’ COMMENT ‘更新人员’,
-> min_valid_bet_number decimal(18,2) DEFAULT ‘0.00’ COMMENT ‘最低有效投注额’,
-> max_valid_bet_number decimal(18,2) DEFAULT ‘0.00’ COMMENT ‘最高有效投注额’,
-> PRIMARY KEY (id)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AUTO_INCREMENT=1;

Query OK, 0 rows affected (0.53 sec)

root@mysql 15:39:20 [ims_a05_786]>
root@mysql 15:39:20 [ims_a05_786]>
root@mysql 15:39:20 [ims_a05_786]>
root@mysql 15:39:21 [ims_a05_786]>
root@mysql 15:39:21 [ims_a05_786]>
root@mysql 15:39:21 [ims_a05_786]> INSERT into ims_wash_code_vip_percent_set
-> (vip_id, game_id,wc_money_scope,wc_percent,audit_multiple,status,create_by,remark,min_valid_bet_number,max_valid_bet_number)
-> VALUES ( 1, 60363, 1, 0.50, 0,1, ‘springtest1’,null, 1, 1 ) ;
ERROR 1264 (22003): Out of range value for column ‘game_id’ at row 1
root@mysql 15:39:23 [ims_a05_786]>
root@mysql 15:39:24 [ims_a05_786]>
root@mysql 15:42:23 [ims_a05_786]>
root@mysql 15:42:23 [ims_a05_786]>
root@mysql 15:42:45 [ims_a05_786]> alter table ims_wash_code_vip_percent_set modify game_id smallint(500) NOT NULL COMMENT ‘二级游戏的id(关联ims_wash_code_game_switch_sort表的id)’;
Query OK, 0 rows affected (1.02 sec)

root@mysql 15:42:47 [ims_a05_786]> INSERT into ims_wash_code_vip_percent_set
-> (vip_id, game_id,wc_money_scope,wc_percent,audit_multiple,status,create_by,remark,min_valid_bet_number,max_valid_bet_number)
-> VALUES ( 1, 60363, 1, 0.50, 0,1, ‘springtest1’,null, 1, 1 ) ;
ERROR 1264 (22003): Out of range value for column ‘game_id’ at row 1

SMALLINT 类型。有符号数的范围是 [-32768, 32767]。无符号数的范围是 [0, 65535]。
默认应该是有符号的

即使默认有符号,但是我的长度是10,插入一个5位的数值,都插不进去,改到500长度了,还是插不了。这有点奇怪啊

这个字段最大长度就是6吧,应该改再大也是6

smallint(10) 这个 10 只是设置显示长度,并不是设置字段数值范围,smallint 的数值取值范围是 [-32768, 32767]

SMALLINT[( M )] [UNSIGNED] [ZEROFILL] M默认为6

小的整数。带符号的范围是-32768到32767。无符号的范围是0到65535。
注意:这里的M代表的并不是存储在数据库中的具体的长度

哦,明白了

不是长度不够,仔细看报错说的是 out of range 是超出了 small int 的表达范围。

官方文档里说的很清楚,你参考一下

另外要注意,TiDB 和 MySQL 有不一样的地方:

SMALLINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

SMALLINT 这个 M 只在设置了 ZEROFILL 属性的时候才有用,是用 0 来补位,补到长度为 M (显示 M 位数字,例如 M=3 数字 7 被显示为 007)

不过,TiDB 不做这个补 0 的操作,如果在 TiDB 里设置了 ZEROFILL 属性,它只会自动给你加上UNSIGNED 标识。

好的,感谢

:+1: