在MySQL中存储日期和小时(没有分钟和秒)

时间:2016-05-30 16:29:21

标签: php mysql

我需要按小时存储日期,但不需要几分钟或几秒钟。这是因为我希望数据按小时分组,并且如果在同一小时内发生两个事件,则能够插入ON DUPLICATE KEY UPDATE...

我看过一些使用DATETIME字段的应用程序,并使用

插入

date("Y-m-d H") . ':00:00'

这是最佳做法还是有更好的解决方案?

4 个答案:

答案 0 :(得分:1)

是的,这是一种很好的做法。日期/时间应保留在日期/时间字段中 - 由于您仍然可以使用特殊的日期和时间功能,这是非常有用的。

答案 1 :(得分:1)

这实际上取决于您的使用案例。

  • 如果您需要查询特定的date或特定hour条目。您应该使用单独的DATETIME(或TINYINT)列类型,两列上都有UNIQUE INDEX,而不是DATETIME列类型。
  • 如果您只需要带有小时的日期,DATETIMEUNIQUE INDEX就适合。

我希望通过将完整日期作为列来确保结果数据是正确的。这样可以更轻松地查询报告目的等,以及标准化其他列值。

mysql> CREATE TABLE `test` (
    -> `my_date` DATE NULL DEFAULT NULL,
    -> `my_hour` TIME NULL DEFAULT NULL,
    -> `full_date` DATETIME NULL DEFAULT NULL,
    -> `duplicates` INT(11) NULL DEFAULT '0',
    -> UNIQUE INDEX `my_date_my_hour` (`my_date`, `my_hour`)
    -> );
Query OK, 0 rows affected (0.18 sec)

然后,不使用PHP格式化插入值或声明单个列值,而是使用full_date列作为参考格式化查询的输入数据。

mysql> INSERT INTO test (full_date, my_date, my_hour) 
    -> VALUES('2016-04-01 20:30:22', DATE(full_date), TIME_FORMAT(full_date, '%H:00:00'))
    -> ON DUPLICATE KEY UPDATE
    -> duplicates = duplicates+1;
Query OK, 1 row affected (0.04 sec)

如果您对TINYINT列使用my_hour,请将插入值更改为TIME_FORMAT(full_date, '%H')

mysql> SELECT * FROM test;
+------------+----------+---------------------+------------+
| my_date    | my_hour  | full_date           | duplicates |
+------------+----------+---------------------+------------+
| 2016-04-01 | 20:00:00 | 2016-04-01 20:30:22 |          0 |
+------------+----------+---------------------+------------+
1 row in set (0.00 sec)

插入另一个更改分钟和秒的条目,以使副本增加。

mysql> INSERT INTO test (full_date, my_date, my_hour) 
    -> VALUES('2016-04-01 20:32:20', DATE(full_date), TIME_FORMAT(full_date, '%H:00:00'))
    -> ON DUPLICATE KEY UPDATE
    -> duplicates = duplicates+1;
Query OK, 2 rows affected (0.04 sec)
mysql> SELECT * FROM test;
+------------+----------+---------------------+------------+
| my_date    | my_hour  | full_date           | duplicates |
+------------+----------+---------------------+------------+
| 2016-04-01 | 20:00:00 | 2016-04-01 20:30:22 |          1 |
+------------+----------+---------------------+------------+
1 row in set (0.00 sec)

然后,您可以将my_datemy_hour列连接成单个列值,以便在PHP中接受。

mysql> SELECT *, CONCAT(my_date, 'T', my_hour) as date_hour FROM test;
+------------+----------+---------------------+------------+---------------------+
| my_date    | my_hour  | full_date           | duplicates | date_hour           |
+------------+----------+---------------------+------------+---------------------+
| 2016-04-01 | 20:00:00 | 2016-04-01 20:30:22 |          1 | 2016-04-01T20:00:00 |
+------------+----------+---------------------+------------+---------------------+
1 row in set (0.00 sec)

然后在PHP中,您可以格式化生成的记录集。

$date = new DateTime($row['date_hour']);
$timestamp = strtotime($row['date_hour']);
//or
$date = new DateTime($row['my_date'] . 'T' . $row['my_hour']);
$timestamp = strtotime($row['my_date'] . 'T' . $row['my_hour']);

答案 2 :(得分:0)

如果您希望按小时对事物进行分组,并且希望它具有高效性,请创建一个衍生列,以列出自纪元以来的小时数。通常情况下,将纪元时间以秒为单位划分为3600。

您将拥有这样的架构:

event_time DATETIME,
event_hour INT

然后添加如下值:

INSERT INTO ... (..., event_time, event_hour)
  VALUES (..., '2016-05-30 13:00:00', 406841)

您可以在UNIQUE列上设置event_hour约束。

答案 3 :(得分:0)

据我所知,最好以整数格式存储日期,如纪元时间因为 1.它会存储日期月份小时分钟等所有内容。 2.使用纪元时间搜索时会更快,因为整数比较比字符串比较更快。

Use of epochtime in MySQL