1

以下のアップデートをご覧ください!

これが私がやりたいことです: 記事の最終更新タイムスタンプ (int として格納) を、最終更新時の人気 (これも int) と共に取得し、新しい人気と結果の傾向 (= 推定値) を計算します。前回の更新以降の単位時間あたりの人気の変化について)、記事を更新します。

問題は、DB 行に書き込まれる値が、ほとんどの場合、トレンド方程式の分子 (つまり、計算された人気) または 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()、すべての単一の値でキャスト (int) を試しましたが、何も機能しません。

関連するすべての列は int(11) であり、十分な大きさである必要があります。また、トレンドの varchar を試し、それを文字列として挿入しましたが、成功しませんでした。私はこの問題に 2 日間取り組んできました。

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。現在、php 5.4.15、mysql 5.6.11 を使用して、apache と mysql のクリーン インストールでコードを実行しています。次に、コードイグナイターをまったく使わずに試してみます...

更新:私自身の間違いです。ログを注意深く読んでおらず、次のようなことが起こっていることに気づきませんでした。

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