MongoDB开发系列-选定合理的数据类型

本篇介绍MongoDB数据库中常见的数据类型使用场景,并给出最佳实践引导。

不将数字作为字符存储

优势:

采用聚合函数时,可以直接计算,比如sum max函数

原因:

MonoDB中是严格区分数据类型的,如果用字符串存储数字,用纯数字int类型查询是查询不到结果的,反之也是一样。

对于聚合函数,字符串如何计算呢?用的时候就知道了,字符串有多别扭。

时间类型选择

不将时间作为字符存储

首先温习几个基础的时间概念

UTC 与 Unix时间戳

在计算机中看到的UTC时间都是从(1970年01月01日 0:00:00)开始计算秒数的。所看到的UTC时间那就是从>1970年这个时间点起到具体时间共有多少秒。 这个秒数就是Unix时间戳。

UTC 与本地时间

UTC + 时区差 = 本地时间

UTC时间 与 GMT时间

我们可以认为格林威治时间就是时间协调时间(GMT=UTC),格林威治时间和UTC时间均用秒数来计算的。

再次了解下MongoDB存储时间的简单原理

MongoDB存储时间

在MongoDB常见的数据类型中关于时间的存储有两个类型分别是

● Timestamp: 时间戳, 表示从1970-1-1到现在的总秒数

● Date: 存储当前⽇期或时间的UNIX时间格式

MongoDB存储时间类型数据时,如果是Date类型,都是先转换为UTC时间,然后存储到数据库中。

时间属性常见的存储格式如下:

time:ISODate("2000-10-10T20:55:36Z"),

优势:

1 可以采用时间范围查询

2 用可视化工具查询结果时,可以一目了然对应的时间,方便跟踪问题。

原因:

如果使用时间戳存储,操作者还得专门去做转化,有多麻烦,谁用谁知道。

那你可以说,我可以直接转化为格式化的时间字符串存储到数据库中,那样问题更大。有以下几种可能:

1》数据库存储的时间格式不一定是前端要真正展示的格式,必定会存在转化。转化存在转化效率问题。

2》格式化的时间字符串不是一个标准的形式,没有规范,12小时制,24小时制?年月日,年月日时分秒?时区问题?这几个都无法解决,都是后续程序BUG的根源。

系统之间如何处理时间,我的建议如下。

前端系统通过时间戳与后端业务系统做交互,业务系统之间传递使用时间戳做交互,涉及到数据库访问,在数据库访问层,将时间戳转化为数据库可以识别的数据类型,通过驱动与数据库做交互。

Date类型的存储虽然有上边描述的优点,也有不足,就是数据从数据库取出来到应用程序转化时有消耗。所以也有一部分开发人员推荐在MongoDB中使用时间戳存储时间数据。

官方文档中有相关的建议

Additionally, using proper types for your data also increases query flexibility: if you store date as a timestamp you can make date range queries, whereas it’s very difficult to compare two strings that represent dates. The same issue holds for numeric fields; storing numbers as strings requires more space and is difficult to query.

上边一段话的意思主要表达,如果使用时间戳存储时间数据,可以为查询和范围查找提供方便,字符存储数字也会遇到同样的问题,如果用字符存储数字,则计算,比较会是非常困难的。

以下是官方的关于日志的设计示例

{

    _id: ObjectId('4f442120eb03305789000000'),

    host: "127.0.0.1",

    logname: null,

    user: 'frank',

   time: ISODate("2000-10-10T20:55:36Z"),

    path: "/apache_pb.gif",

    request: "GET /apache_pb.gif HTTP/1.0",

    status: 200,

    response_size: 2326,

    referrer: "[http://www.example.com/start.html](http://www.example.com/start.html)",

    user_agent: "Mozilla/4.08 [en] (Win98; I ;Nav)"

}


下面我们看看PHP中关于MongoDb时间的常用操作

环境YII2 MongoDB

MongoDB\BSON\UTCDateTime 来源于mongodb驱动包

```

use MongoDB\BSON\UTCDateTime;

```

```

/**

    * 获取当前时间的utc时间

    *

    * @return utcTime

    * */

    public static function getCurrentUtcTime()

    {

        $timeStamp = TimeUtility::getCurrentTimeStamp();

        return $currentTime = new UTCDatetime($timeStamp * 1000);

    }

/**

    * 根据时间获取utc时间

    *

    * @param $date 时间格式

    *

    * @return utcTime

    */

    public static function getUtcTimeByTimeDate($date)

    {

        return $time = new UTCDatetime(strtotime($date) * 1000);

    }

```


文章中的观点有不严谨之处,欢迎评论沟通。

学习MongoDb数据库的基本态度:边学习,边实践,边参考,边改进,在问题中成长。

你可能感兴趣的:(MongoDB开发系列-选定合理的数据类型)