我正在写一个十大投票系统。民意调查员每周都会在他们的前10名投票。我应该如何存储每周的民意调查?也就是说,如何控制轮询在存储(mySQL)或PHP(5.x +)计算中的哪一周?
( System#1 )我以前通过在我设置为0的服务器上设置文件“week.txt”然后每周运行一个cron作业来更新+1来完成此操作。当我将轮询数据存储在数据库中时,我只是加载文件并知道它是什么周。我正在寻找更优雅的东西。
系统必须:
其他信息:
我以前用过的系统不起作用,因为为了跳过几周,它需要互动并违反#4,否则不能跳过几周,从而违反#2。
我已经考虑过2个系统,但它们的部分原因都失败了:
( System#2 )当民意测验者投票时使用PHP的日期(“W”)。因此,第一周他们都得到#48周(例如),第二周#49,所以很容易分辨哪一周是什么。问题是一些民意调查将持续到日历年,因此我最终会得到48,49,50,51,52,1,2,3,4并违反上述#3。此外,如果我们跳过几周,我们最终会得到48,49,50,1,2,3,这违反了上面的#2和#8。
( System#3 )然后,我有想法存储他们进入民意调查的日期。我会设置一个日期来计算从第一轮投票之前的一周,因此,它只需要计算周数之间的差异,我就知道周数。但除非我们改变违反#3的日子,否则没有简单的方法可以跳过违反#2的数周。
( System#4 )然后,我认为当民意测验者第一次投票时,我们只将其记录为第1周投票。当他们下次投票时,它是第2周,依此类推。如果他们想要编辑他们的民意调查(同一天),他们只是使用编辑按钮,我们不会记录新的民意调查,因为他们已经发信号通知它是一个编辑。唯一的问题是,如果民意测验者忘记了一周,这意味着我必须进入并更正数据(添加一个空白周或更改他们投票但违反#4的周数)。这样处理跳过周就好了。也许一个cron工作会解决这个问题?如果有人忘了,在投票结束后运行的cron作业将进入一个空白周。可编程以查看输入的最大周数,如果任何用户ID没有该周数,则只需输入空白数据。
如果您可以调整上述任何系统以满足所有标准,那也没关系。我正在寻找一种简单,优雅,免提的解决方案。
请询问任何其他澄清信息。
答案 0 :(得分:3)
使用周数时,您应该记住01.01.2012是在第52周(而不是1)。问题是,您是否希望在日历周内修正您的民意调查,或者从民意调查开始日期开始7天抵消。考虑一下周五开始的投票,并在7天之后结束。您将跨越日历周障碍,因此您的用户可以投票2个星期。
我可能更喜欢偏移方法,因为严格的日历绑定通常无济于事。你想回答“日历周34的票数是多少”或“投票第三周的票数是多少”的问题?
计算偏移非常简单:
// 0-based
$week_offset = floor(time() - strtotime("2011-11-02") / 7);
我不知道你的轮询算法。我只是用加权民意调查来证明(1-3星,3是最好的):
| poll_id | user_id | week_offset | vote |
| 7 | 3 | 0 | 1 |
| 7 | 4 | 0 | 3 |
| 7 | 5 | 0 | 2 |
| 7 | 3 | 1 | 2 |
| 7 | 4 | 1 | 2 |
| 7 | 5 | 2 | 3 |
| 7 | 5 | 5 | 1 |
运行类似
的查询SELECT
poll_id,
week_offset,
SUM(vote) as `value`,
COUNT(user_id) as `count`,
AVG(vote) as `average`
FROM votes_table
WHERE poll_id = 7
GROUP BY poll_id, week_offset
ORDER BY poll_id, week_offset;
会给你类似的东西
| poll_id | week_offset | value | count | average |
| 7 | 0 | 6 | 3 | 2 |
| 7 | 1 | 4 | 2 | 2 |
| 7 | 2 | 3 | 1 | 3 |
| 7 | 5 | 1 | 1 | 1 |
到目前为止,您可能已经注意到差距0,1,2,[3],[4],5。
当从MySQL获取数据时,你必须反复迭代结果。那么问题在于延长填充间隙的问题在哪里?
<?php
// your database accessor of heart (mine is PDO)
$query = $pdo->query($above_statement);
$results = array();
$previous_offset = 0;
foreach ($query as $row) {
// calculate offset distance
$diff = $row['week_offset'] - $previous_offset;
// make sure we start at 0 offset
if ($previous_offset === 0 && $row['week_offset'] > 0) {
$diff++;
}
// if distance is greater than a single step, fill the gaps
for (; $diff > 1; $i--) {
$results[] = array(
'value' => 0,
'count' => 0,
'average' => 0,
);
}
// add data from db
$results[] = array(
'value' => $row['value'],
'count' => $row['count'],
'average' => $row['average'],
);
// remember where we were
$previous_offset = $row['week_offset'];
}
// 0 based list of voting weeks, enjoy
var_dump($results);
您也可以使用function在MySQL中执行上述操作。