V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
VeryZero
V2EX  ›  程序员

请教个问题,为什么数据库的日期用字符串存,字符串格式是 20201027195800 这种

  •  1
     
  •   VeryZero · 2020-10-27 20:05:48 +08:00 · 4332 次点击
    这是一个创建于 1488 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看了好几家公司的 Java 项目都有这么干的,一直想不通。

    数据库是 Oracle,也有 MySQL 的。

    除了这个以外,还有字符串做主键,AA0001 这种。

    还有字符串做关联查询等等。

    最骚的是字符串传参。。

    感觉 Oracle 里的字符串是万能的。是他们太菜了还是我太菜了。。

    36 条回复    2020-10-28 17:45:50 +08:00
    wpblank
        1
    wpblank  
       2020-10-27 20:13:20 +08:00 via iPhone
    我们时间也是上述格式,用 bigint 存。我也不知道为啥。
    jingniao
        2
    jingniao  
       2020-10-27 20:17:17 +08:00 via Android
    数据库原生 datetime 要注意时区
    int 类型时间戳
    cmdOptionKana
        3
    cmdOptionKana  
       2020-10-27 21:00:43 +08:00
    日期用字符串很常见,也是有一些好处。
    VeryZero
        4
    VeryZero  
    OP
       2020-10-27 21:09:48 +08:00
    @wpblank
    @jingniao
    @cmdOptionKana

    你们说的整形存的可能是 unix 时间戳,这个很正常,特别是 PHP 的系统里比较常见,计算比较都很方便。

    但是这是年月日时分秒格式的,比较计算啥的都要用函数。

    不知道好处在哪,所以才问的。

    退一步说就算这种年月日时分秒的格式有某方面的优势,也应该用整形存吧,用字符串真的不用考虑索引的感受吗
    CRVV
        5
    CRVV  
       2020-10-27 21:10:36 +08:00 via Android   ❤️ 7
    本来就可以这么用,如果你要深究,就保存时间这件事情上,每个方法都会有缺点。

    首先字符串就是任意长度的整数,没什么区别。

    日期时间的存法很多,比如
    1. 用 unix timestamp,缺点是人类不能一眼看出来那是哪天。
    2. 用数据库内置的 datetime 类型,但 MySQL 的 datetime 有奇怪的行为还不能带时区。
    3. 用楼主说的这种,存字符串类型。
    4. 用楼主说的这种,存整数类型。

    4 比 3 省 6 个 byte 的空间。
    但是这个格式一定要从字符串转换过来,用的时候也必然要转回字符串,所以 3 比 4 节省一点 cpu 。

    实际上 3 和 4 的差别是无关紧要的事情,没人在乎 6 个 byte,也没人在乎那一点点 cpu 。
    但 1 和 2 的缺点是确实存在的。
    GopherDaily
        6
    GopherDaily  
       2020-10-27 23:52:23 +08:00   ❤️ 3
    实话说的话,就是菜
    chendy
        7
    chendy  
       2020-10-28 00:04:05 +08:00   ❤️ 1
    当处理不好时区还有其他一些奇怪的问题的时候,字符串就是最优解,数字性能更好一些但是也更麻烦一点
    xcstream
        8
    xcstream  
       2020-10-28 04:58:48 +08:00
    比如查找 10 点到 11 点的数据 , 用 int 存就要每个日期计算一遍。
    chenluo0429
        9
    chenluo0429  
       2020-10-28 08:00:56 +08:00 via Android   ❤️ 1
    1%的可能是有特殊需求,99%都是因为菜吧
    krixaar
        10
    krixaar  
       2020-10-28 08:14:20 +08:00
    如果他们存“20201027T195800+0800”也就是再加点无关紧要的佐料是不是就觉得没问题了?毕竟如果确实只在东八区用,+0800 写不写都知道。
    ragnaroks
        11
    ragnaroks  
       2020-10-28 08:35:35 +08:00
    这说明瓶颈在 web 应用上,不在数据库上
    opengps
        12
    opengps  
       2020-10-28 08:38:31 +08:00 via Android
    没什么菜不菜的,只是偷懒而已
    xuanbg
        13
    xuanbg  
       2020-10-28 08:57:38 +08:00   ❤️ 1
    对于接口来说,日期要么字符串传参,要么时间戳传参。还能有别的办法传参?反正我倾向于字符串传参,时间戳还得换算一下才能知道时间,不利于发现问题。
    blless
        14
    blless  
       2020-10-28 09:11:46 +08:00   ❤️ 1
    写业务多了就会发现时间戳的好处了,尤其是处理一些面向海外的业务
    zsdroid
        15
    zsdroid  
       2020-10-28 09:59:13 +08:00
    时间戳不可读?加个虚拟列就好了
    wysnylc
        16
    wysnylc  
       2020-10-28 10:21:21 +08:00
    @GopherDaily #6 +1 就是菜
    时间戳有时区而且索引比字符串要快得多,字符串是索引性能最低的,要不然要那么多整数类型干什么
    wilsonWei
        17
    wilsonWei  
       2020-10-28 11:18:14 +08:00
    应该用带时区的 timestamp
    qiayue
        18
    qiayue  
       2020-10-28 11:51:54 +08:00
    @wilsonWei 时间戳不分时区的吧
    no1xsyzy
        19
    no1xsyzy  
       2020-10-28 12:55:05 +08:00
    @xuanbg 有是有,json 的方式传{}或者传[]都可以的。
    比如传 [2020, 10, 27, 19, 58, 00] 还比主题的格式更方便眼 parse
    当然,ISO 8601 也是好的
    只是觉得主题这样毫无 “肉眼解析锚点” 的方式确实不太行。
    不过数据库是另一个问题,有日期格式优先日期格式,没有再看数据量级和需求综合分析,指不定最优方案是同时存储 timestamp 和字符串表示呢。
    GrayXu
        20
    GrayXu  
       2020-10-28 12:59:32 +08:00
    字符串不是显然解析开销比较大嘛。。
    wilsonWei
        21
    wilsonWei  
       2020-10-28 13:26:42 +08:00
    @qiayue 也分时区的
    Kr98
        22
    Kr98  
       2020-10-28 13:30:30 +08:00 via Android
    @wilsonWei timestamp 是以 utc 为基准点,datetime 类型+时区是数据库的功能,和 timestamp 无关。
    wilsonWei
        23
    wilsonWei  
       2020-10-28 14:14:18 +08:00
    @Kr98 我说的带时区的 timestamp,指的是数据库的字段类型:timestamp with time zone,并非 unix 时间戳
    xuanbg
        24
    xuanbg  
       2020-10-28 14:25:11 +08:00
    @no1xsyzy ISO 8601 什么的会被前端打死……
    xuanbg
        25
    xuanbg  
       2020-10-28 14:30:35 +08:00
    @qiayue 时间戳的值没有时区,但获取这个值的时候就和时区有关系了。错误的系统时区将会导致获取到错误的时间戳。
    v2webdev
        26
    v2webdev  
       2020-10-28 14:30:37 +08:00 via Android
    @CRVV 您好,请教一下,“多出 6 bytes” 是怎么计算的?
    cmdOptionKana
        27
    cmdOptionKana  
       2020-10-28 15:06:12 +08:00
    @xuanbg 不可能吧,ISO8601 对前端非常友好,js 标准库就支持 ISO8601,最流行的日期时间库 day.js 也重点支持 ISO8601 。
    hitmanx
        28
    hitmanx  
       2020-10-28 15:34:26 +08:00
    @v2webdev 我猜他指的是 char[14] vs uint64_t
    a719031256
        29
    a719031256  
       2020-10-28 15:47:01 +08:00
    太懒了
    我手上的项目就遇到,给建表的人说字段属性跟注释有歧义,然后这家伙就直接把所有字段属性改为 varchar,所有的值含义都通过口口相传
    wilsonWei
        30
    wilsonWei  
       2020-10-28 15:55:23 +08:00
    @a719031256 好家伙。。这规范也太差劲了,没人管管吗。。。
    a719031256
        31
    a719031256  
       2020-10-28 15:57:29 +08:00
    @wilsonWei 管什么,国企的开发只要文档够标准就行了,至于代码和数据库设计将就效率而不是质量,文档要求每一个功能点要够详细,截图要多。。。。
    CRVV
        32
    CRVV  
       2020-10-28 16:09:06 +08:00   ❤️ 1
    @v2webdev
    用整数的话,32 位不够,那就要用 64 位的,占 8 bytes
    那个字符串是 14 个数字,14 bytes

    如果用定长的字符串,也就是不需要额外存长度,也不需要在结尾补一个 0,那就是差 6 bytes
    ETiV
        33
    ETiV  
       2020-10-28 16:13:53 +08:00 via iPhone
    存时间戳
    海外不仅跨时区,遇到有夏令时的地方有的搞了…
    wilsonWei
        34
    wilsonWei  
       2020-10-28 16:22:09 +08:00
    @a719031256 好吧,追求不一样
    a719031256
        35
    a719031256  
       2020-10-28 16:26:33 +08:00
    @wilsonWei 这些人就是懒,啥事都是扔给我们帮他们弄,还有另一个人脸识别项目,海康 sdk 部署 Linux 环境居然不知道把动态库扔到系统库中,还要让我周六帮他弄,明明海康的文档写得清清楚楚
    wilsonWei
        36
    wilsonWei  
       2020-10-28 17:45:50 +08:00
    @a719031256 这些大爷们就是懒,工作一点都不上心
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2626 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 80ms · UTC 02:45 · PVG 10:45 · LAX 18:45 · JFK 21:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.