2011-03-04 89 views
0

我目前正在研究一个中等规模的Web项目,并且遇到了问题。伪随机选择均匀分布的数据

我想要做的是显示一个问题,连同一个图像。我有一个(全球)问题列表和一个(全局)图像列表,所有图像都应该问所有问题。

至于用户可以看到的问题和图像应该随机选择。然而,答案的统计数据(问题/图像对)将用于研究目的。这意味着必须选择所有问题/图像对,以便答案在所有问题和所有图像间平均分配。

用户应该只能够回答特定的问题/图像对中的一个的时间。

我正在使用mysql数据库和php。目前,我有三个数据库表:

tbl_images (image_id) 

tbl_questions (question_id) 

tbl_answers (answer_id, image_id, question_id, user_id) 

其他列并不涉及这一特定问题。

解决方案1: 跟踪每个图像/问题已被使用多少次(在每个表格中添加一列)。总是选择最少要求的图像和问题。
问题: 什么我真正感兴趣的是图像,反之亦然问题中的分布,而不是每一个问题是,甚至全球。

解决方案2: 添加另一张表,其中包含所有问题/图像对以及询问的次数。选择最低的组合(如果计数列按升序排序,则为第一行)。
问题: 并不强制用户只能回答一个问题一次。也没有给出用户选择随机的外观。

解决方案3: 同#2,但商店的问题/图像/ 表user_id说明
问题: 性能问题,大量的空间浪费为每个用户(?)。可能会有大量的数据(数千个问题/图像和至少数百个用户)。

解决方案4: 选择从所有可用的真正的随机提问和形象。有了足够多的答案,他们将平均分配。
问题: 如果我添加了新的问题或图片,他们不会得到比别人更多的答案,因此永远也追不上。我想要所有问题/图像对的统计数据。

解决方案5: 加权随机。选择一些问题/图像对(比如约10-100),然后选择用户没有回答的最好的(如最低全局计数)。
问题: 不能保证最近添加的问题或图片能够快速获得大量答案。

到目前为止,解决方案#5可能是最好的。
您的输入是非常感谢,感谢您的时间。

+0

我在前面的问题中得到了有关加权值的一些很好的答案。也许他们会帮助你。 http://stackoverflow.com/questions/4030427/generate-random-weighted-value – 2011-03-04 18:37:39

+1

P.S.在编程中没有“真正的随机”这样的东西。只有伪随机(除非你有机会获得一个自然的随机生成器,甚至可以说它只是随机的,因为我们不知道如何预测它。) – 2011-03-04 18:39:01

回答

0

从我了解你的问题,我会去#1。但是,您不需要新的列。我会创建一个SQL视图,而不是因为它听起来像你需要报告这样的事情。一个视图基本上是一个缓存选择,但行为类似于一个表。因此,你将创建一个视图回答每幅图像的总每一个问题的饲养:

DROP VIEW IF EXISTS "main"."view_image_question_count"; 
CREATE VIEW "view_image_question_count" AS 
SELECT a.image_id, a.question_id, SUM(b.question_id) as "total" 
FROM answer AS a 
INNER JOIN answer AS b ON a.question_id = b.question_id 
GROUP BY a.image_id, a.question_id; 

然后,你需要一个快速简便的方法来获得下一个最好的图像/问题二合一问:

DROP VIEW IF EXISTS "main"."view_next_best_question"; 
CREATE VIEW "view_next_best_question" AS 
SELECT a.*, user_id 
    FROM view_image_question_count a 
    JOIN answer USING(image_id, question_id) 
    JOIN question USING(question_id) 
    JOIN image USING(image_id) 
ORDER BY total ASC; 

SELECT * FROM view_image_question_count 

如果需要下一个最好的图像+问题要问一个用户,你会打电话:

现在,如果您需要在图像上报告质疑成效,请您可以通过这样做

SELECT * FROM view_next_best_question WHERE user_id != {USERID} LIMIT 1 

!= {USERID}部分是为了防止让用户已经回答的问题。 LIMIT优化只能得到一个。

免责声明:可能有很多工作可以优化这一点。我只是想发表一些想法。

另外,这里是我用于测试的数据库转储。 http://pastebin.com/yutyV2GU

+0

谢谢你的回答,一个很好的解决方案。经过一些改动后,我得到了它的工作,最值得注意的是SUM函数将加起来每个id的数值,而我想要的数量。我可能还会添加一些额外的代码来处理从未问过的问题(即不在答案表中)。再一次,谢谢:) – ChewToy 2011-03-05 11:23:14

+0

这已经处理了没有得到回答的问题。因此,第二个视图中的所有联接。 – 2011-03-05 17:10:34