【发布时间】:2018-08-23 13:51:41
【问题描述】:
我希望通过我的 api 从不同时区向我的用户提供简单的日志,我有点迷茫,希望能得到一些帮助。
我有下表称为日志:
CREATE TABLE `logs` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) NOT NULL,
`ip` VARCHAR(45) NOT NULL,
`timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我有一个每小时表来绑定我的查询超过 24 小时。
CREATE TABLE `log_hours` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`hourId` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO log_hours
(hourId)
VALUES
(1),
(2),
(3),
(4),
(5),
(6),
(7),
(8),
(9),
(10),
(11),
(12),
(13),
(14),
(15),
(16),
(17),
(18),
(19),
(20),
(21),
(22),
(23),
(24);
每次我获得 api 命中时,我都会存储日志并获取以下数据。
id | userId | ip | timestamp
1 1 0.0.0.0 2018-08-23 14:20:34
2 1 0.0.0.0 2018-08-23 14:20:34
3 1 0.0.0.0 2018-08-23 14:20:34
4 1 0.0.0.0 2018-08-23 14:20:34
5 1 0.0.0.0 2018-08-23 14:20:34
现在,如果我像下面这样运行我的查询。
SELECT DW.hourId AS hour, ifnull(t.hits,0) hits from log_hours DW left join (
SELECT COUNT( * ) AS hits, HOUR( logs.timestamp ) AS `hour`
FROM logs WHERE DAY( logs.timestamp ) = DAY(CURDATE())
AND MONTH( logs.timestamp ) = MONTH(CURDATE())
AND `userId` = 1 GROUP BY HOUR( logs.timestamp )) t on DW.hourId = t.hour
ORDER BY hour ASC
这很好用,并且像这样给我每小时的日志。
现在我卡在时区上,我的数据库时区设置为 BST。
假设我在美国有一个用户,例如,如果他们在他们的时区点击 api,mysql 是否会自动将他们的时区转换为我的 BST 时区,以便输出数据有意义?
我应该使用 datetime NOT NULL DEFAULT CURRENT_TIMESTAMP 还是应该使用 INT 并使用 php time() 函数来插入记录?
我应该先从我的时区通过 php 返回数据,然后转换为他们的数据,在这种情况下什么是最佳做法?
编辑:
如果我在这里问一些愚蠢的问题,但我真的想完全理解这个过程,首先很抱歉。
我在什么时候检索用户的本地时区?我应该将它作为必需参数添加到 API 中吗?
这是我的 PHP 代码,我只是将所有内容添加到一个函数中,这样更容易阅读我的过程是 MVC。
public function usage_get(){
$userId = $this->get('userId'); // i am obviously not getting the users info this way this is just for the example
// DO I MAKE THEM SEND THEIR TIMEZONE TO THE API AS A PARAM THEN USE IT IN MYSQL
//https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_convert-tz?
$timezone = $this->get('timezone');
// DO I SOMEHOW RETRIEVE THE TIME ZONE BASE ON IP AND GET IT THAT WAY?
$query = $this->db->query("SELECT DW.hourId AS hour, ifnull(t.hits,0) hits
from log_hours DW
left join (
SELECT COUNT( * ) AS hits, HOUR( logs.timestamp ) AS `hour`
FROM logs
WHERE DAY( logs.timestamp ) = DAY(CURDATE())
AND MONTH( logs.timestamp ) = MONTH(CURDATE())
AND `userId` = ".$this->db->escape_str($userId)."
GROUP BY HOUR( logs.timestamp )
) t on DW.hourId = t.hour ORDER BY hour ASC");
// DO I RUN A PHP FUNCTION AFTER THE MYSQL BASED ON TIMEZONE?
if($query->num_rows() > 0){
$this->response([
'status' => TRUE,
'message' => 'Success',
'data' => $query->result(),
], REST_Controller::HTTP_OK);
}else{
$this->response([
'status' => FALSE,
'message' => 'Error'
], REST_Controller::HTTP_OK);
}
}
【问题讨论】: