抽奖,是很多企业、聚会的常见玩乐形式,光彩绚丽的抽奖屏幕背后,是计算程序+抽奖用户信息。程序=算法+数据结构。
好,说抽奖程序的的实现吧。这个实现一般需要应用数学原理。而本文的方法是我在参加一次婚礼的抽奖体验后突然想到的,一种比较简单、无需数学原理的方法。
功能:能按照相同概率,从用户集合中抽出随机的部分用户集合作为中奖者。抽奖可以进行多次,对已中奖的用户不会重复抽取。
使用技术:
1.SqlServer数据库,使用NewID()作为select随机筛选函数
2.sql随机函数
3.为了快速方便的搭建原型,使用EF4.1DBfirst,然后代码生成Model类(我在快速开发原型是喜欢EF,讨厌sql-实体转换。能让我从sql中解放出来,专注业务逻辑。只有
当需要的sql逻辑比较复杂,EF难以实现或效率不行时我才写sql-实体转换)。
主要逻辑:
1.建立LotteryUsers(抽奖用户的英文词组)表,定义用户信息、以及是否已中过奖的标志位IsLotteried,默认都是false-0(IsDelete-该用户是否已删除、无效)。
2.执行sql查询出定量的中奖用户集合:
SELECTTOP(@chooseCount)*FROMLotteryUsersluWHERElu.IsDeldte=0ANDlu.IsLotteried=0ORDERBYNEWID()
并且将这些中奖用户的IsLotteried字段设置为true-1
3.控制台显示中奖的用户集合
DB建表语句:
代码(使用EF4.1,实体生成模型),代码细节、EF技术看不懂没关系,了解原理即可:
就这样,lotteryUsers即是中奖的用户。若要继续抽奖,只要再调用GetPrizeUsersAndUpdatePrized()即可,中奖用户不会重复。
---------------------------------------------备注、其他----------------
1.对于某些抽奖,若要内定某些VIP中某个奖,最好不要写死、在配置文件中写上VIP的名字,在抽奖函数中传入这些VIP的名单、直接确认。
2.对于某些次VIP们,若需要提高中奖概率,需要待议。可能实现的方法有:在users表中加上权重Pritory值,然后再做某些操作;或者采用其他较复杂的数学实现方法。
3.我的程序不注重程序\DB效率,所以未经优化。但是实际上,一般抽奖用户也就1W人以下,完全不存在性能问题。(中国16亿人全名抽奖,淘宝京东等全站抽奖数据量很大的,需要另行优化)。