通过数据库实现和程序实现的比较 1、通过数据库实现 Oracle可以通过我在 http://community.csdn.net/Expert/topic/4832/4832629.xml?temp=.4810602 中给出的方法来实现 select ID,name,star_level from (select ID,name,star_level,round(dbms_random.value(1,15))-star_level t from tbl_A) where t<=0select ID,name,star_level from (select ID,name,star_level,mod(abs(dbms_random.random),15)-star_level t from tbl_A) where t<=0select ID,name,star_level from (select ID,name,star_level from tbl_A order by dbms_random.value*(1+star_level/k) desc) where rownum<5select * from table sample(k) 也可以实现取k%的记录用数据库做可以直接将需要的数据取出。不同的数据库需要用不同的函数处理2、通过程序实现 需要先将数据全部取出,然后再随机取出需要的数据。算法不依赖于数据库
通过程序实现不需要全部取出数据吧。取出count,然后产生1-count的随机数 R ,选择第R条记录不就行了吗?取出全部数据,太不划算了。呵呵
解决这个问题,想来想去,至于取秒的小数部分,够随机!
select to_char(current_timestamp(6),'YYYY-MM-DD hh24:mi:ssxff') from dual;
查询结果:
2006-06-21 17:51:41.245732, 取后面的245732;
这6个数字够权威,够随机了吧~2. 其次,怎么选择题目? (比如试题表是 EXAM)
先取总数~
select count(1) from EXAM;
得到结果:
150000 (假设题库有15万题)
将上面得到的 245732 / 1000000 * 150000 = 368598, 那么新得到的368598就是随机选中的题目.3. 上面两步基本可以解决了随机选题的问题,但不能解决试题还有级别,不同级别之间,选中概率不同的问题:
解决方法如下:
例:level 1选中率为 50%
例:level 2选中率为 30%
例:level 3选中率为 10%
例:level 4选中率为 7%
例:level 5选中率为 3%
一共要选多少题是已知的,例如要选100题出来.
那么可以得到需要选出 50题(1级) 30题(2级) 10题(3级) 7题(4级) 3题(5级);4.
select count(1) from EXAM where level=1;
select count(1) from EXAM where level=2;
select count(1) from EXAM where level=3;
select count(1) from EXAM where level=4;
select count(1) from EXAM where level=5;
得到所有级别的试题数的结果:(假设结果如下)
100000
30000
10000
5000
5000 ,
好了, 现在的问题就转变成,怎样在100000题1级试题中选出50题, 30000题2级试题中选出30题 .......5. 将步骤4中的问题用步骤1,2来解, 完事~
(有不足之处~ 请指出! 这个过程需要代码和SQL结合来完成, 下一个SQL就能完成的人实在...高)
那就是取秒的小数部分,可能取的两次是相同(这个...1000000分之一的概率)或则调整后值相同.
那就会产生两次选一样的题~ 不过解决这个问题应该很easy吧~ 选中一题就往随便哪张表里塞条记录,说明这题已经被用啦,以后不能再用
1. select to_char(current_timestamp(6),'YYYY-MM-DD hh24:mi:ssxff') from dual;
小数部分并不是随机数,而是一个确定的时间;所以产生的并不是一个水平分布的随机数;
2. 245732 / 1000000 * 150000 = 368598, 那么新得到的368598就是随机选中的题目.
由于产生的245732 并不是水平分布的随机数,那么通过它计算出选中题号的概率就不是 1/总题数,那么就无法保证后面的level 1选中率为 50%等
想知道用数据库实现和用程序实现两者的优劣
1、通过数据库实现
Oracle可以通过我在
http://community.csdn.net/Expert/topic/4832/4832629.xml?temp=.4810602
中给出的方法来实现
select ID,name,star_level from (select ID,name,star_level,round(dbms_random.value(1,15))-star_level t from tbl_A) where t<=0select ID,name,star_level from (select ID,name,star_level,mod(abs(dbms_random.random),15)-star_level t from tbl_A) where t<=0select ID,name,star_level from (select ID,name,star_level from tbl_A order by dbms_random.value*(1+star_level/k) desc) where rownum<5select * from table sample(k) 也可以实现取k%的记录用数据库做可以直接将需要的数据取出。不同的数据库需要用不同的函数处理2、通过程序实现
需要先将数据全部取出,然后再随机取出需要的数据。算法不依赖于数据库
但是我想只要是通过算法实现的随机数应该都差不多吧。个人认为放在程序里比较好,比较灵活,适当减轻数据库负担。
1. 数据库的话,只需要一次就可以取得所需要的数据集;
2. 通过程序实现
1)不是特别清楚 waterfirer(水清) 所说的需要先将数据全部取出,然后再随机取出需要的数据应该怎么做,再次麻烦 waterfirer(水清) 解释一下
2)我的理解是如果需要随机取得确定level的题N道,那么,需要建立一个数组,记录已经被取出的题的序号,根据N进行循环,每次循环随机生成一个随机数,然后检查数组中是否已经存在该随机数对应的题目序号,如果不存在,那么把随机数生成的题目序号放入数组;如果存在,继续循环,直至取得N个题目序号;最后按照数组去数据库一次性取得记录;(前提:按照随机数生成题目序号在数据库中一定存在)
想法不是特别完善
欢迎大家拍砖,多多指点
select * from table sample(k) 也可以实现取k%的记录
尝试了一下,好象取得记录的条数不总是确定的
SQL> select count(1) from t1; COUNT(1)
----------
100
SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
19 19
22 22
25 25
35 35
70 70
78 78
84 84
87 87
91 91已选择9行。SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
3 3
4 4
26 26
35 35
41 41
43 43
82 82
86 86已选择8行。SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
3 3
4 4
26 26
35 35
41 41
43 43
82 82
86 86已选择8行。SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
3 3
4 4
26 26
35 35
41 41
43 43
82 82
86 86已选择8行。SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
3 3
9 9
13 13
30 30
33 33
35 35
44 44
51 51
65 65
74 74
90 90 MONTH MONEY
---------- ----------
93 93已选择12行。SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
3 3
9 9
13 13
30 30
33 33
35 35
44 44
51 51
65 65
74 74
90 90 MONTH MONEY
---------- ----------
93 93已选择12行。SQL> select * from t1 sample(10); MONTH MONEY
---------- ----------
10 10
17 17
20 20
56 56
73 73
94 94已选择6行。