Discord/Twitch机器人开发:插入数据库的BIGINT类型Discord ID与实际值不符问题求助
解决Discord ID存入BIGINT字段时的精度丢失问题
我之前也踩过一模一样的坑,跟你拆解下问题根源和靠谱的解决方案:
首先说为啥会出现数值偏差:你的Discord ID是522855210926735422,这是一个18位的长数字,但JavaScript的Number类型是双精度浮点数,它只能精确表示**-253到253**之间的整数(大概是-9007199254740992到9007199254740992)。显然你的Discord ID远超这个范围,所以当你把它当作普通Number处理时,JavaScript已经悄悄丢失了精度,传到数据库里的数值自然就不对了。
你之前改用VARCHAR字段的思路其实非常合理——因为Discord ID本质上是一个标识符,不是用来做加减乘除的数值,字符串存储完全能满足需求,而且不会有任何精度问题,还简单省心。如果你觉得这个方案够用,完全可以继续用,定义字段为VARCHAR(20)就足够容纳所有Discord ID了。
如果你坚持要用数值类型存储,这里有两个更严谨的方案:
方案1:用JavaScript的BigInt配合数据库BIGINT
- 先在代码里把Discord ID转换成
BigInt类型,从源头避免精度丢失; - 同时一定要用参数化查询(别再直接拼接变量了,这不仅能解决精度问题,还能彻底避免SQL注入风险)。修改后的代码大概是这样:
add_discord(twitch_id, discord_id) { return this.get_user(twitch_id) .then((user_data) => { const discordBigId = BigInt(discord_id); return this.db.query(`UPDATE userdata SET discord_id = ? WHERE identity_id = ?`, [discordBigId, user_data[0]]) }) }
方案2:配置数据库驱动,让大整数以字符串返回
如果你用的是MySQL驱动,可以在连接配置里加上这两个参数:
const db = mysql.createConnection({ // 你的基础配置:host、user、password、database supportBigNumbers: true, bigNumberStrings: true });
这样驱动会把数据库里的BIGINT类型值以字符串形式返回,避免转成Number时丢失精度。
另外提一句,你查询返回的changedRows: 0,说明SQL执行成功但没修改数据——这大概率也是因为精度丢失后,传入的数值和数据库里已有的值不匹配导致的,解决精度问题后这个情况也会消失。
内容的提问来源于stack exchange,提问作者ThomasNotTom
相关产品推荐
相关产品推荐

