1

请参阅下面的更新!

这就是我想做的:获取一篇文章的最后一次更新时间戳(存储为int),连同最后一次更新时的流行度(也是int),计算新的流行度和产生的趋势(=一个估计值自上次更新以来每时间单位的流行度变化)并更新文章。

问题是,写入数据库行的值几乎总是趋势方程的分子(因此计算出的流行度)或 0。流行度的静态值不会改变任何事情,但是 last_update 的静态值或time() 导致插入正确的值。还有一些奇怪的事情:将 last_update 排除在更新查询之外也会导致插入趋势的正确值。就像 last_update 列影响趋势列,我不明白如何。

这是我的代码,请注意我使用的是 codeigniter,所以我使用 activerecord 来获取文章。另外,我对几乎所有数值都使用了 intval(),因为我的第一个猜测是数据类型问题:

$this->db->where('id', 1);
$article_query = $this->db->get('articles');
$article = $article_query->row_array();

$article['last_update'] = intval($article['last_update']);
$time = intval(time());
$new_popularity = // Calculate Popularity here (I tried with static values, doesn't affect the result) ;
$time_diff = intval(($time - $article['last_update']));

$trend = intval((($new_popularity - $article['popularity']) / $time_diff)); 

var_dump($trend);

$this->db->query('UPDATE `articles` SET `popularity` = '.$new_popularity.',  `trend` = '.$trend.' WHERE `id` =  1 ');

var 转储给了我一个带有预期值的 int。查询日志还显示了预期的查询,例如

UPDATE `articles` SET `popularity` = 50000, `last_update` = 1374840645, `trend` = 10 WHERE `id` =  1

但是 50000 被插入趋势。如前所述,$time 和 $article['last_update'] 的静态值使问题消失,将 last_update 排除在查询之外也是如此。我还对每个值都尝试了 ceil()、floor()、casting (int),但没有任何效果。

所有涉及的列都是 int(11),应该足够大。我还尝试了 varchar 的趋势并将其作为字符串插入 - 没有成功。我已经处理这个问题两天了,我真的很渴望任何帮助!

我在 Windows 7 上运行 MySQL 5.5.32。

请消除怪异,谢谢!

编辑:进一步澄清:出于测试目的,我将 $article['popularity'] 设置为 0,因此我可以反复测试并且仍然得到 >0 的趋势。这就是为什么插入 50000 而不是实际差异的原因。

更新:这是我的代码现在所在的位置。使用 ON UPDATE CURRENT_TIMESTAMP 将 last_update 设置为 TIMEZONE 类型。

$this->db->where('id', 1);
$article_query = $this->db->get('articles');
$article = $article_query->row_array();

date_default_timezone_set('Europe/Berlin');
$article['last_update'] = intval(strtotime($article['last_update']));

$time = intval(time());
$new_popularity = 50000; // Static test value
$time_diff = intval(($time - $article['last_update']));

$trend = intval((($new_popularity - 0) / $time_diff)); // Zero for testing purposes only, so that there will always be a positive trend.

var_dump($trend);

$this->db->_protect_identifiers=false;
$this->db->query('UPDATE articles SET popularity = ?,  trend = ? WHERE id =  ?', Array($new_popularity, $trend, 1));

查询日志:

UPDATE articles SET popularity = 50000, trend = 403 WHERE id =  1

通过 phpMyAdmin 获得的实际值:流行度 = 50000,趋势 = 50000。我现在也在全新安装的 apache 和 mysql 上运行代码,使用 php 5.4.15,mysql 5.6.11。接下来我会尝试不使用codeigniter,我猜......

更新:我自己的错误,我没有仔细阅读日志,也没有注意到发生这样的事情:

130730 17:25:48    51 Connect   root@localhost on zeenr
           51 Init DB   zeenr
           51 Query SET NAMES utf8
           51 Query SET SESSION sql_mode="STRICT_ALL_TABLES"
           51 Query SELECT *
FROM (`articles`)
WHERE `id` =  1
           51 Query UPDATE articles SET `popularity` = 50000, `trend` = 179 WHERE `id` =  1
           51 Quit  
130730 17:25:49    52 Connect   root@localhost on zeenr
           52 Init DB   zeenr
           52 Query SET NAMES utf8
           52 Query SET SESSION sql_mode="STRICT_ALL_TABLES"
           52 Query SELECT *
FROM (`articles`)
WHERE `id` =  1
           52 Query UPDATE articles SET `popularity` = 50000, `trend` = 50000 WHERE `id` =  1
           52 Quit  

为什么会这样?我的代码中没有任何循环。

4

1 回答 1

0

要真正知道正在运行什么查询,您应该启用 MySql 日志:

SET GLOBAL general_log = 'ON';

运行查询后有一个日志文件C:\xampp\mysql\data。(就我而言)

也尝试不保护标识符和查询绑定:

$this->db->query(
    'UPDATE articles SET popularity = ?, trend = ? WHERE id = ?',
    array($new_popularity, $trend, 1)
);

编辑:

您是否尝试过活动记录语法?

$data = array
(
    'popularity' => $new_popularity,
    'trend' => $trend,
);

$this->db->where('id', 1);
$this->db->update('articles', $data);
于 2013-07-26T12:55:36.367 回答