Mysql数据库常用字段int(),tinyint(),char(),varchar()后括号内参数详解

近期有朋友问我说mysql数据库里tinyint(1)这个1到底是什么意思啊?

于是就有了这篇文章,来给大家说一说常见字段后面带的参数都有什么意义,什么时候会用到.

注: (本人测试版本为mysql 5.7.16 及 8.0.15)

int,tinyint:

它们两个的参数意义一模一样, 下边我用int来举例:

假设我表中有一字段age 类型为int(5) 那这个5代表的其实是最小显示长度(不足则前边用0补全), 也就是说当我们给age字段设为12的时候,select查询显示应该是00012, 可是实际操作中我们发现并没有补全效果, 是这样的, 如果我们想要这个5生效, 我们还需要给age字段增加 zerofill 约束 增加完zerofill约束之后, 我们再执行查询就发现有了这个补全效果, 这个跟python 里的字符串占位 %05d 的写法比较类似

测试过程:

首先我们创建一个表test, 字段为num1,num2 类型分别为int(5), tinyint(5), 然后插入一行数据(3, 3), 查询一下看看没有什么异常.

然后我为字段num1,num2 指定zerofill 属性(当指定zerofill后, 会自动变为无符号模式: unsigned), 我们再来查询看看, 被补全了.

char,varchar:

这两个的参数意义基本上一样,下边我用char来举例:

假设我表中有字段name, 类型为char(4) 这个4代表的就是最大字符长度, 也就是说我们可以写4个字符, 注意是字符不是字节,经测试我写进去4个英文字母或者4个汉字都是可以的, 而5个字母或者5个汉字就都提示数据过长.

测试过程:

创建表test, 字段str1, str2, 类型分别为char(4), varchar(4), 不管插入字母还是汉字: 只有当两个字段都小于等于4个的时候才能插入成功.

最后补充一下:

int()类型默认范围: -2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647), 无符号模式下范围: 0到4294967295

tinyint()类型默认范围: -128 到 127, 无符号模式下范围: 0-255

char()类型是一个定长文本型, 当你设定为长度4的时候, 就算你写入一个"哈哈", 数据库内部也会给你补成"哈哈xx"保存(x代表空格, 补全的空格查询语句不会显示), 因为定长,所以常用于身份证电话号码等长度基本一致的数据, 有人说char()的效率高,但是在存储引擎为InnoDB时, 影响效率更重要的是一整条数据的长度, 所以在InnoDB更推荐都用varchar()类型.

varchar()类型没有char()的特性, 它是一个可变长度, 正因为是可变长度, 内部实际存储时是你写入的字符串长度加上一个记录长度的字节(如果超过255则占两个字节)

你提供的关键信息: > 🔴 `LineNumber` 字段类型是 `VARCHAR(10)`,存储的是字符串形式的数字(如 `'1'`) 这正是导致你接口报错 **“LineNumber 必须是 0~9 的整数”** 的根本原因! --- ## 🧨 问题本质:类型不匹配 虽然你在数据库中存了 `'1'`(字符串),但服务端期望的是一个 **真正的整数类型 `int`**。 当你从 MySQL 查询后直接转成字典发送: ```python item = dict(row) # {'LineNumber': '1'} ← 是字符串! ``` 然后发给 API: ```json { "LineNumber": "1" } ``` 📌 服务端收到的是 JSON 字符串 `"1"`,而不是数字 `1`,所以校验失败。 --- ## ✅ 解决方案:在 Python 中强制转为 `int` 你需要在构造数据时,显式将 `LineNumber` 转成整数类型。 ### ✅ 正确代码示例: ```python for row in cursor.execute("SELECT * FROM AppSortingTasks WHERE CreationTime >= %s", (since,)): item = dict(row) # 关键修复:把 VARCHAR转为 int try: item['LineNumber'] = int(item['LineNumber']) if item['LineNumber'] else 1 except (TypeError, ValueError): item['LineNumber'] = 1 # 默认值 data["AppSortingTasks"].append(item) ``` > 💡 这样生成的 JSON 就会是: > > ```json > { "LineNumber": 1 } ← 数字,不是字符串 ✅ > ``` --- ## 🔍 验证方法:打印生成的 JSON 加一行调试输出: ```python print(json.dumps(data["AppSortingTasks"][0], ensure_ascii=False, indent=2)) ``` ✅ 正确输出(注意没有引号): ```json { "Id": 901007441448148999, "WaybillId": "25548953", "LineNumber": 1 } ``` ❌ 错误输出(带引号表示字符串): ```json { "Id": 901007441448148999, "WaybillId": "25548953", "LineNumber": "1" } ``` --- ## 🛠️ 补充建议:批量处理所有数值字 你可以写一个通用函数自动转换常见数值字: ```python def convert_types(record, int_fields=None, float_fields=None): int_fields = int_fields or ['LineNumber', 'SortUnitNo', 'TaskId', 'Id', 'WaybillId'] float_fields = float_fields or [] for field in int_fields: if field in record: try: record[field] = int(record[field]) except (TypeError, ValueError): record[field] = 0 for field in float_fields: if field in record: try: record[field] = float(record[field]) except (TypeError, ValueError): record[field] = 0.0 return record # 使用方式 for row in cursor.execute(sql, (since,)): item = convert_types(dict(row)) data["AppSortingTasks"].append(item) ``` --- ## 📌 其他注意事项 | 项目 | 建议 | |------|------| | 数据库设计 | 如果 `LineNumber` 永远只存数字,建议改为 `TINYINT` 更合适 | | 接口文档 | 提醒后端明确字段类型要求(如 `type: integer`) | | 日志记录 | 记录发送前的数据结构,便于排查 | --- ## ✅ 总结一句话 > ❗ 即使你的 `LineNumber` 值是 `1`,只要它是从 `VARCHAR` 字读取并未经转换,就会以字符串 `"1"` 发送,从而被后端拒绝。必须在 Python 中用 `int()` 显式转为整数才能通过验证! --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值