从无到有创建一个聊天App六-仿QQ号生成算法

思考

当你注册QQ的时候,系统会给你生成一个唯一的数字账号。那么这个账号在后台是怎么生成的呢?当让实现方法有很多,可以直接生成一个随机数,然后查找该随机数有没有被注册过,若是没有,则生成成功,否则,重新执行以上步骤。这个方法有个很大的问题:随着注册的号码越来越多,以后每生成一个号码,可能要多次查询是否已经注册,效率太低!
我也查了一些资料,最简单的算法莫过于预先生成一批数字,作为一个号码池,以后注册时可以每次从号码池中取一个。当号码池中的号码不够用时可再生成一批。这样其实每次仅需查询一次数据库,看似最笨,实则效率极高,效果也较好。

实现

我们先生成10001到10099这99和账号,插入到数据库中,并在每个号码后面加上一个标志位,这样以后靓号可以标识为locked,保证不能被注册到。代码如下。

var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/users');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
    console.log("数据库连接成功");
    let accountSchema = mongoose.Schema({
        account: Number,
        status: String
    });
    let accountModel = mongoose.model('account_pool', accountSchema);

    for (var i = 10001; i <= 10099; i++) {
        let account = new accountModel({
            account: i,
            status: "ok"
        });
        account.save(function (error, newAccount) {
            if (error) {
                console.log("插入 " + account + " 错误:" + error);
            } else {
                console.log("已成功插入 " + newAccount);
            }
        });
    }

});

我们并非批量插入,而是一个个循环插入,其实数据插入的顺序并不是固定的,你看下log就知道了。这样也算是稍微的一点点随机,使得连续注册不会注册到连续的号码。启动数据库之后,将上面的代码保存到文件accountGen.js中运行如下命令即可生成好号码池。

node accountGen.js

同样,每次注册时候去号码池中取一个。

function createAccountNumber(callback) {
    accountModel.findOneAndRemove({status: "ok"}, function (err, newAccount) {
        if (err) {
            console.log("createAccountNumber err:" + err);
            callback(err, null)
        } else if (!newAccount) {
            console.log("createAccountNumber newAccount null");
            callback(null, null)
        } else {
            console.log("createAccountNumber result:" + newAccount);
            callback(null, newAccount.account)
        }
    })
}

大功告成!非常简单。

接下来要做的事情

目前看来系统已经可以运行了,但是却缺少了一个重要的东西:日志系统。服务器没有日志是不行的,下面我将学习如何使用log4js。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值