mysql 拿取随机数据思考

一、背景

自己因为有一个答题插件逻辑,需要从数据库随机选择一定数目的题目,这个业务已经被同事实现,但我觉得他实现不对或者不够好,于是思考这个问题。他用rand() 产生一个随机数,然后大于这个随机数 加上limit 得到 题库。

二、问题

  1. 题库是连续的,用户体验不好
  2. 随机概率增大,如果用这个思路写抽奖那么绝对是不对的。

三、解决思路

假设我们选择uid 用户的ID 是整数,主键。。

select * from xxx where uid >= (rand(max(uid) - min(uid) ) + min(uid)) limit 1

上面手写,不代表语法正确, rand 只是找一个随机数据, 这个可以程序传过来,不一定要数据库随机数。 后面+min(uid) 只是为了防止随机到0而已,保证uid最小值而已。

如果要随机多条,应该调用多次,而不是limit 10 (假设多条是10),因为这里有一个隐藏前提,随机条数和数据必须差别比较大,不然很可能出现连续,而不是看起来随机的。

四、补充

select * from xxx where uid >= (rand(max(uid) - min(uid) ) + min(uid)) limit 1

select * 加了条件,如果数据库有10条数据,uid(0~9),如果我随机5条数据话,如果用上面的 select * from xxx where uid >= (rand(max(uid) - min(uid) ) + min(uid)) limit 5 。很容易出现连续的,而且数据缺失。select * 拿数据,会一行行拿,条件对比,而不是扑通一下拿取所有数据,然后才进行对比,所以用rand() limit 个数,会出现不连续,而你自己用 select * from xxx where uid >= 10 limit 5 却是 连续的,这里10我只是随便举一个数字而已。 如果数据少,加上UID自增,随机到大于5是50% ,如果我选择5条数据,那么很容易不够,并且连续,这里连续满足where条件太少了,所以导致连续,如果数据足够多就没有这个问题。

我以前全表扫描比较慢,测试200W数据,个人电脑也就0.85秒消耗。如果加上条件那么速度快很多,更不要说有索引的情况下。。。

这个问题我记录下来,只是跟后端开发探讨出来,自己不喜欢写数据库东西。只是记录技术而已。

node request 设置代理

一、背景

自己用node request 请求 http 发现请求无法正确应答,我用fidder抓包没有抓对应数据包,因为默认node 不会走 windows 默认代理。

二、解决过程

在request 构建增加参数 proxy: 'http://127.0.0.1:8888'

这个设置代理到fidder里面去,如果非HTTPS 可以直接用wireshark来抓包。

三、补充

如果是第三方程序,如果不会默认走代理,可以用proxifier, 这个软件出来很多年,自己可以百度下载,官方可以试用30天。

proxifier过滤指定进程名字,然后转发443 80 端口数据包到fiddler上面,这样子就可以抓任何程序的包,无论他支不支持代理。

edge微软账号登录

一,问题

edge 虽然可以同步登录,但大多数会出现登录出现问题,我以前都是通过梯子登录,最近发现一个简单方法解决了,自己记录一下。

二,解决

通过填写微软的dns就可以加快登录过程。4.2.2.1 4.2.2.2 这个地址

登录后可以改回自己默认DNS,只是临时切换一下,而可以用网上快速切换DNS的工具,进行快速切换。