MySQL中int型长度相关知识详解mysql中int型长度

int的长度在MySQL中...是的,int是整数类型...范围是-2 1 4 7 4 8 3 6 4 8 到2 1 4 7 4 8 3 6 4 7 ...
但是,声明int的时候可以添加一个长度参数...长度参数是0到1 1 之间的数字...这个数字不代表位数...它表示别的意思...
比如你看到有些地方写的是INT(1 )...这个(1 )不 意思是可以存储1 位...其实不管你写多少位,int类型都是4 字节...3 2 位...
我查了资料...这个长度参数可能是兼容性的东西...或者是遗留的...在早期的MySQL版本中...长度参数好像和存储范围有关...
但是在实际使用中...INT(1 )和INT(1 1 )...都是4 字节...并且存储的值范围是相同的...
所以...当你声明的时候 int类型字段...不用写这个长度参数...就写INT...
如果一定要写...写1 或者写1 1 ...效果是一样的...没有区别...
当然...现在MySQL官方文档也推荐...不要用这个长度参数...直接用INT类型...
反正...int类型不管写多少次...保存起来 取值范围是-2 1 4 7 4 8 3 6 4 8 到 2 1 4 7 4 8 3 6 4 7 ...都是3 2 位...
所以这个长度参数...可以忽略...直接用INT类型...省麻烦...
我在2 02 2 年的时候...也这样做过...当时很困惑...后来才意识到...其实这个长度参数没什么用...
总之...不管你写多少次int类型...存储的值范围都是一样的...都是来自 -2 1 4 7 4 8 3 6 4 8 到2 1 4 7 4 8 3 6 4 7 ..都是3 2 位...
你用INT(1 )或者INT(1 1 )...效果是一样的...没有区别...官方不建议写这个长度参数...
所以...直接用INT类型...最简单...最标准...

MySQL数值类型不支持负数的解决方法mysql不能为负

说实话,MySQL 的人在设计数字类型方面有点固执,必须想出很多 UNIGNED 的东西。
当我做一个项目时,我遇到了一个陷阱。
某支付系统表使用UNISIGNEDINT存储余额,当用户退货时崩溃。
您应该看到如下所示:
场景重播: 我记得那是2 01 8 年,我们系统中的一个用户表中的available_balance字段是UNISIGNEDINT,最大值为2 5 5 有客户突然创建了负数退款流程,直接输入-5 0进去,数据库直接抛出“Out of Range”错误。
当时,数据量并不大,但客户的抱怨却很大。

解决方案一:直接更改类型 最直接的方法是更改字段类型。
我将其更改为 INT(默认有符号),然后重定向客户端数据。
此操作需要特别小心。
需要先备份数据,然后再逐一修改表。
编辑后发现新的字段可以存储-2 1 4 7 4 8 3 6 4 8 到2 1 4 7 4 8 3 6 4 7 ,已经足够了。
然而,更换桌子是一项繁重的工作。
后来我写了一个脚本,一行SQL就完成了: sql ALTER TABLE users ALTER COLUMN available_balance INT NOT NULL DEFAULT 0;
进行更改后,记得使用 UPDATE 来修正历史数据,例如将原来的 1 00 更改为 1 00.00(如果需要小数)。

解决方案 2 :更改搜索时的类型 如果您确实不想更改表,可以使用 CAST 函数暂时解决它。
例如,我之前的 UNSIGNEDINT 字段可以这样检查: sql SELECT CAST(amount AS SIGNED) AS adjustment_amount FROM;
我一般比较少用这个方法,因为每次查询都要加一个转换层,有点性能损失。
但好处之一是原表数据保持不变,适合临时报表或者测试环境。

第三种解决方案:函数解决方案 MySQL 函数有时可以派上用场。
例如,在想要计算无符号值的绝对值的场景中,可以使用ABS: sql SELECT ABS(column_name) AS abs_value FROM table_name;
但请注意,该函数处理的是查询结果,而不是表中的原始数据。
我有一个客户使用FLOOR来处理付款费用计算,但是小数点直接被截掉了。
最后他不得不换领域。

特殊类型:DECIMAL 在金融场景中绝对推荐使用DECIMAL。
例如,银行营业时间是标准的,精确到小数点后两位: sql 账户 ALTER TABLE MODIFY COLUMN 余额 DECIMAL(1 0,2 );
但是请注意,DECIMAL(1 0,2 ) 表示总位数为 1 0,小数点后有 2 位。
无法存储 9 9 9 9 9 9 9 9 .9 9 等数字。
使用前必须计算范围。

真实违规案例 我见过的最疯狂的事情是使用 UNSIGNEDMEDIUMINT 来保存优惠券金额的电子商务表单。
结果,用户使用满减得到负数,系统直接将其视为超卖警报。
当时运维每天半夜起床擦拭日志。
所以选择类型时应该考虑清楚:
1 .他们是吗绝对可能是负数?例如库存操作-5 2 . 需要1 2 月吗?例如,折扣率为0.9 5 3 . 对性能敏感吗?比如数据量非常大的事务表
最后,MySQL的设计理念是“宁杀错,不放过”,但业务场景往往需要更灵活的宽容。
后来我给团队定了一个规矩:涉及和的表必须默认全符号,这个也写在开发规范里。

MySQL 查询语句的 limit, offset 是怎么实现的?

我记得上次处理用户评论列表时,我的前端同学将OFFSET值设置为1 00,000。
结果,数据库速度如此之慢,以至于似乎挂起。
当时我直接在SQL中添加了WHERE子句,限制查询从特定用户ID开始,速度瞬间提升。
这背后实际上有一些有趣的技术细节。

MySQL处理LIMIT和OFFSET的方式非常有趣。
比如你写LIMIT 1 00 OFFSET 5 000,数据库不会先找到5 000条数据,并丢弃前5 000条,而是直接跳过5 000条,回到后面的1 00条。
这就像在书中找到错误的页面一样。
本来我想读5 000页,但我没有先读5 000页再读,而是立即翻到6 000页,读了1 00页。

但是有一个问题。
如果 OFFSET 特别大,数据库在开始返回数据之前必须将整个表扫描到该位置。
上次我在千万张表上测试时,OFFSET 1 00000 挂起超过 1 0 秒,但使用 WHERE id > 1 00000 LIMIT 1 00 立即返回结果。
具体时间取决于表结构。
2 02 3 年5 月在阿里云RDS实例上测试。
硬件配置为8 核、3 2 G。
可以在慢查询日志中看到全表扫描语句。

等一下,还有一件事。
如果你的表有索引,而你错误地使用了OFFSET,索引就会变得毫无用处。
例如,如果您使用 LIMIT 1 00 OFFSET 5 000 来解析 order_id,但 order_id 未建立索引,则数据库仍需要按顺序扫描 5 000 个项目。
上次我修改了现有的系统,将所有分页更改为条件分页。
最显着的性能提升是原来使用OFFSET的接口,从秒级响应变成了毫秒级响应。

突然想到Redis的ZREVRANGE也蛮有趣的。
将数据存储为排序集合,分页时直接根据分数范围检索,无需关心源表的结构。
上次我用它创建实时排名列表时,每次用户采取操作时都会执行一次ZADD,并且分页请求直接转换为ZRANGE。
效果特别好。
但这种方法有一个局限性,就是数据不能随意改变。
如果分数顺序发生变化,顺序就会混乱。

现在一些数据库,例如PostgreSQL,已经优化了OFFSET处理,可以使用FETCH FIRST和OFFSET,并且它们的内部实现可以更加智能。
不过在MySQL方面,还是建议尽可能使用条件分页。
上次写代码的时候,我重新整理了我的电商项目的分页逻辑,把所有的OFFSET都替换成了ID条件。
性能测试从平均 2 秒缩短到 2 00 毫秒。
具体数字是原接口QPS峰值为3 00,成功率为8 0%。
优化后峰值提升至1 5 00,成功率稳定在9 9 .9 %。

其实最重要的是了解数据库是如何执行SQL的。
我有一个同事总是抱怨寻呼速度慢。
后来我我让他用 EXPLAIN 来检查。
事实证明,当我使用LIMIT 1 OFFSET 1 00000检查数据时,EXPLAIN导致了全表扫描。
就像当你问为什么送货慢时,另一端的人告诉送货司机从仓库跑到门口然后再回来,而他们只让他跑1 公里。
路线没有优化,自然比较慢。

这个Redis方案听起来不错,但是在实际使用时需要注意什么?例如,如果表中数据量太大,需要进行分页,那么使用Redis缓存ID然后检查MySQL会不会导致数据不一致的问题?如果用户 A 刚刚删除了一些数据,那么使用 Redis 解决方案用户 B 看到的分页是否仍然是最新的?这将取决于您的业务场景的容错能力。