【微信公众号开发】一个随机产生抽奖码的逻辑

活动参与人数大概150人左右,然后设计在公众号回复抽奖会随机获得一个一定范围内抽奖码,然后活动现场会在箱子里提前准备好一定范围的抽奖码纸条进行现场抽奖。基于这个需求,第一版代码只是简单的一个循环不断rand取值,回查数据库抽奖码是否产生过,如果是,重新随机rand取值。但这个思路写完就被我否决了= =,因为假设抽奖码产生了一大半了情况下,这样去随机到产生过抽奖码概率是很大的,增加了服务器数据库负担(虽然数据量很小,影响微乎其微),但是假设在数据量巨大上亿的情况下,这个问题如何解决。
于是在百度上一番查找,据random.org资料,将所有的数想象成一个表格?然后随机产生一个数,如果被使用过,那么随机选择上,下,左,右,移动一定的距离决定下一个数字。但是这貌似还是没解决如果范围内数据被用了一大半了,这效率还是很低啊。
在这个活动数据量很小的情况下,先给出解决方案,设计两张表,一张luck表存抽奖码和对应用户信息,一张status表存范围内所有的抽奖码,flag字段标记使用和未使用。每次用户发送抽奖指令,先判断是否抽过,是,则返回属于他的抽奖码,否则进入随机产生抽奖码流程->取出status表中flag为0未使用过的抽奖码,加入到数组,然后在数组中随机抽取一个,然后发送给用户,更新luck和status表最后exit。
但是这个思路在上亿数据面前,肯定不能取出来存数组吧,所以我觉得有必要看看大数据方面的知识?如果看官有好的思路,请指导我或者和我交流!
下面上代码,因为功能简单,直接一个php文件全写了。

<?php
//获得参数 signature nonce token timestamp echostr
    $nonce     = $_GET['nonce'];
    $token     = '';//自定义的微信token
    $timestamp = $_GET['timestamp'];
    $echostr   = $_GET['echostr'];
    $signature = $_GET['signature'];
    //形成数组,然后按字典序排序
    $array = array();
    $array = array($nonce, $timestamp, $token);
    sort($array);
    //拼接成字符串,sha1加密 ,然后与signature进行校验
    $str = sha1( implode( $array ) );
    if( $str == $signature && $echostr ){
        //第一次接入weixin api接口的时候
        echo  $echostr;
        exit;
    }else{
        //1.获取到微信推送过来post数据(xml格式)
        $postArr = $GLOBALS['HTTP_RAW_POST_DATA'];
        if(!empty($postArr)){
            //2.处理消息类型,并设置回复类型和内容
            /*
            ToUserName        开发者微信号
            FromUserName    发送方帐号(一个OpenID)
            CreateTime        消息创建时间 (整型)
            MsgType            text
            Content            文本消息内容
            MsgId            消息id,64位整型
            */
            $postObj = simplexml_load_string($postArr, 'SimpleXMLElement', LIBXML_NOCDATA);  
            //$postObj->ToUserName = '';
            //$postObj->FromUserName = '';
            //$postObj->CreateTime = '';
            //$postObj->MsgType = '';
            //$postObj->Event = '';
            $fromUsername = $postObj->FromUserName;//发送人  
            $toUsername = $postObj->ToUserName;//接收人  
            $MsgType = $postObj->MsgType;//消息类型  
            $MsgId = $postObj->MsgId;//消息id
            if($MsgType == 'text'){
                $content = trim($postObj->Content);//消息内容  
                if(!empty($content)){
                    $con = mysql_connect("","","");//连接数据库  数据库地址,用户名,密码
                    mysql_select_db("yueying", $con);//选择库
                    $keyword = "666666";//触发抽奖关键词
                    //判断该数据包是否是回复触发抽奖
                    if($content == $keyword){
                        $textTpl = "<xml>  
                                    <ToUserName><![CDATA[%s]]></ToUserName>  
                                    <FromUserName><![CDATA[%s]]></FromUserName>  
                                    <CreateTime>%s</CreateTime>  
                                    <MsgType><![CDATA[%s]]></MsgType>  
                                    <Content><![CDATA[%s]]></Content>  
                                    <FuncFlag>0</FuncFlag>  
                                    </xml>";
                        $toUser = $fromUsername;
                        $fromUser = $toUsername;
                        $time = time();
                        $tempStr = "抽奖码:";
                        //判断重复申请抽奖码
                        $result = mysql_query("SELECT * FROM luck WHERE user='{$toUser}'");
                        //SELECT * FROM luck WHERE user=oxfAQw8iA7mawarLkuzVkRBPCr-U
                        if(mysql_num_rows($result)!=0){
                            $result = mysql_query("SELECT code FROM luck WHERE user='{$toUser}'");
                            $row = mysql_fetch_array($result);
                            $luck = $row['code'];
                            $content="你已经拥有抽奖码啦,你的抽奖码是:".$luck;
                            $resultStr = sprintf($textTpl, $toUser, $fromUser, $time, 'text', $content);  
                            echo $resultStr;
                            mysql_close($con);
                            exit;
                        }
                        $code = array();
                        unset($code);//清空数组
                        //取1-150未使用的抽奖码
                        $count = 0;
                        $result = mysql_query("SELECT * FROM status WHERE flag=0 and code<151");
                        //如果1-150使用完了
                        if(mysql_num_rows($result)==0){
                            $result = mysql_query("SELECT * FROM status WHERE flag=0 and code>150");
                            $row = mysql_fetch_array($result);
                            $luck = $row['code'];
                            //回复拼接
                            $content = $tempStr.$luck;
                            $resultStr = sprintf($textTpl, $toUser, $fromUser, $time, 'text', $content);  
                            mysql_query("INSERT INTO luck (user,code) VALUES ('{$toUser}','$luck')");
                            mysql_query("UPDATE status SET `flag` = 1 WHERE `code`='{$luck}';");
                            echo $resultStr; 
                            mysql_close($con);
                            exit;
                        }else{
                            while($row = mysql_fetch_array($result))
                            {
                                $code[$count] = $row['code'];
                                $count++;
                            }
                            //随机一个未使用的抽奖码
                            $random = rand(0,$count-1);
                            $luck = $code[$random];
                            //回复拼接
                            $content = $tempStr.$luck;
                            $resultStr = sprintf($textTpl, $toUser, $fromUser, $time, 'text', $content);  
                            mysql_query("INSERT INTO luck (user,code) VALUES ('{$toUser}','$luck')");
                            mysql_query("UPDATE status SET `flag` = 1 WHERE `code`='{$luck}';");
                            echo $resultStr; 
                            mysql_close($con);
                            exit;
                        }
                    }else if($content == "洪轰最帅"){
                        $result = mysql_query("select * from luck");
                        $textTpl = "<xml>  
                                    <ToUserName><![CDATA[%s]]></ToUserName>  
                                    <FromUserName><![CDATA[%s]]></FromUserName>  
                                    <CreateTime>%s</CreateTime>  
                                    <MsgType><![CDATA[%s]]></MsgType>  
                                    <Content><![CDATA[%s]]></Content>  
                                    <FuncFlag>0</FuncFlag>  
                                    </xml>";
                        $toUser = $fromUsername;
                        $fromUser = $toUsername;
                        $time = time();
                        $content = "参与人数:".mysql_num_rows($result);
                        $resultStr = sprintf($textTpl, $toUser, $fromUser, $time, 'text', $content);
                        echo $resultStr;
                        mysql_close($con);
                        exit;
                    }else{
                        $textTpl = "<xml>  
                                    <ToUserName><![CDATA[%s]]></ToUserName>  
                                    <FromUserName><![CDATA[%s]]></FromUserName>  
                                    <CreateTime>%s</CreateTime>  
                                    <MsgType><![CDATA[%s]]></MsgType>  
                                    <Content><![CDATA[%s]]></Content>  
                                    <FuncFlag>0</FuncFlag>  
                                    </xml>";
                        $toUser = $fromUsername;
                        $fromUser = $toUsername;
                        $time = time();
                        $content = "回复“{$keyword}”即可抽奖!";
                        $resultStr = sprintf($textTpl, $toUser, $fromUser, $time, 'text', $content);
                        echo $resultStr;
                        mysql_close($con);
                        exit;
                    }
                }
            }
        }
    }
添加新评论