如何产生既随机又不随机的数据

标题没有写错,的确有这样的需要,至少我碰到了。

首先描述一下我碰到的情况,我的笑话站(xiaohuayoumo.com)使用的是MySQL数据库。其中有一个表alljokes,记录了所有的笑话。我现在想实现的功能是,每天随机的选择出一部分笑话(比如说50个)。要做到这一点是非常容易的,最简单的方法就是“SELECT * from alljokes ORDER BY rand() LIMIT 50”。当然如果alljokes中的数据非常多的话,“ORDER BY rand()”的效率会比较低,网上有很多文章将到如何用其他方法来替代“ORDER BY rand()”。

接下来的问题是,如果这些笑话一旦选定,我希望是永远不会改变。比如说2008年11月23日随机选出了50个笑话,那无论什么时候(比如1年后),我希望看看2008年11月23日的随机笑话是啥,看到的必须和最初选择到的50个笑话一样,不能改变。要做到这一点,前面的方法需要改进。需要给ORDER BY rand()加一个seed。比如假定2008年11月23日的seed是20081123,那把原来的SQL语句改成“SELECT * from alljokes ORDER BY rand(20081123) LIMIT 50”,这样一来,无论什么时候查看2008年11月23日的随机笑话,应该始终就是最初的50个。

但是还有问题,如果alljokes这个表中的数据是变化的。也就是说,笑话的个数是会增加或者减少。那么即使给rand用了seed,也不能保证选择出来的数据是相同的。要解决这样的问题,用简单的SQL语句和程序应该是不行的。必须创建一个新的表(比如叫randjokes),这个表,只需要2个数据段,1个用来存放seed(seedid),一个用来存放从alljokes中随机选择出来的50个笑话的id(aids),用英语逗号链接这样id。这样SQL语句可以写成“SELECT * FROM alljokes WHERE id IN (SELECT aids FROM randjokes WHERE seedid = 20081123)”。

这样就实现了既随机又不随机的数据,也就是说的一次是随机的,然后把这个随机数据记录下来。以后每次都不随机了。

Leave a Reply

Your email address will not be published.