今天接到客户那边一个需求,用26个大写英文字母加8个数字(去掉0和1,因为和字母里面的I/O相似)产生11位的随机字符串。不能有重复。(客户是个生产饮料的企业,字符打在瓶盖上,抽奖用)
看起来其实是蛮简单的,关键是要5300万条。
第一步:用java生成随机码,插入到DB,1000条提交一次,整个过程用了20多分钟。
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class RandCode { /** * 生成随机码,插到数据表中 * @param agrs */ public static void main(String[] agrs){ Connection conn = getConnection(); try{ PreparedStatement stmt = conn.prepareStatement("insert into A2 values(?)"); String temp = ""; StringBuffer buf = new StringBuffer("A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"); buf.append(",2,3,4,5,6,7,8,9"); String[] arr = buf.toString().split(","); for(int k = 0; k < 53000; k++){ for (int i = 0; i < 1000; i++){ temp = getPswd(arr); stmt.setString(1, temp); stmt.addBatch(); } stmt.executeBatch(); conn.commit(); System.out.println(k); } }catch(SQLException e){ e.printStackTrace(); } } public static String getPswd(String[] arr){ StringBuffer b = new StringBuffer(); java.util.Random r; int k ; for(int i=0;i<11;i++){ r = new java.util.Random(); k = r.nextInt(); b.append(String.valueOf(arr[Math.abs(k % 34)])); } return b.toString(); } }
第二步:剔除重复数据。
1、本来考虑用select语句查询出重复数据,然后删除。
select distinct(code) from a2 t group by code having count(code) > 1;
后来发现这个方法实在太天真了,5300万条数据,在等待了几分钟后,Cancel了。
请教了DBA,说建议我用md5算法,这样可以保证产生的结果不会有重复。但是md5加密出来的结果比较长,好像是32位吧,而我的客户要的是11位的。
后来DBA提议另外一个办法,再建一个临时表,把原始表里面的非重复数据选择出来,然后插入临时表。
insert into a1 (select distinct code from a2);
果然在不到5分钟的时间内,执行结束。
结束后看了看a1表中的记录总数:52999665,剔除了335条重复记录。
第三步:导出数据。
写个程序导到txt文件中去,没啥好说的,就是有点慢。(本来想保存到excel里面去,可惜每个sheet只能保存65536条。。。!)
个人感觉应该还有更加好的办法,特别是在产生随机码这块。如果能有办法直接生成不重复的记录就好了。
1 楼
王者之剑
2009-04-13
真的有这个必要?不能按顺序循环生成?
2 楼
honda418
2009-04-15
王者之剑 写道
真的有这个必要?不能按顺序循环生成?
那还叫随机码么?知道这个规则或者顺序的,不就能随便取到了?